diff options
410 files changed, 151843 insertions, 0 deletions
@@ -0,0 +1,63 @@ +$Id$ + +The hybrid team is a group of ircd coders who were frustrated +with the instability and all-out "dirtiness" of the EFnet ircd's +available. "hybrid" is the name for the collective efforts of a group +of people, all of us. + +Anyone is welcome to contribute to this effort. You are encouraged +to participate in the Hybrid mailing list. To subscribe to the +Hybrid List, use this link: + https://lists.ircd-hybrid.org/mailman/listinfo/hybrid + +The core team as, of this major release: + +billy-jon, William Bierman III <bill@mu.org> +cryogen, Stuart Walsh <stu@ipng.org.uk> +Dianora, Diane Bruce <db@db.net> +metalrock, Jack Low <jclow@csupomona.edu> +Michael, Michael Wobst <michael@wobst.at> +Rodder, Jon Lusky <lusky@blown.net> +Wohali, Joan Touzet <joant@ieee.org> + +The following people have contributed blood, sweat, and/or code to +recent releases of Hybrid, in nick alphabetical order: + +A1kmm, Andrew Miller <a1kmm@mware.virtualave.net> +Adrian Chadd <adrian@creative.net.au +adx, Piotr Nizynski <nizynski@sysplex.pl> +AndroSyn, Aaron Sethman <androsyn@ratbox.org> +bane, Dragan Dosen <bane@idolnet.org> +bysin, Ben Kittridge <bkittridge@cfl.rr.com> +cosine, Patrick Alken <wnder@uwns.underworld.net> +David-T, David Taylor <davidt@yadt.co.uk> +fgeek, Henri Salo <henri@nerv.fi> +fl, Lee Hardy <lee@leeh.co.uk> +Garion, Joost Vunderink <garion@efnet.nl> +Habeeb, David Supuran <habeeb@cfl.rr.com> +Hwy101, W. Campbell <wcampbel@botbay.net> +jmallett, Juli Mallett <jmallett@FreeBSD.org> +joshk, Joshua Kwan <joshk@triplehelix.org> +jv, Jakub Vlasek <jv@pilsedu.cz> +k9, Jeremy Chadwick <ircd@jdc.parodius.com> +kire, Erik Small <smalle@hawaii.edu> +knight, Alan LeVee <alan.levee@prometheus-designs.net> +kre, Dinko Korunic <kreator@fly.srk.fer.hr> +madmax, Paul Lomax <madmax@efnet.org> +nenolod, William Pitcock <nenolod@nenolod.net> +Riedel, Dennis Vink, <riedel@chaotic.nl> +scuzzy, David Todd <scuzzy@aniverse.net> +spookey, David Colburn <spookey@spookey.org> +TimeMr14C, Yusuf Iskenderoglu <uhc0@stud.uni-karlsruhe.de> +toot, Toby Verrall <to7@antipope.fsnet.co.uk> +vx0, Mark Miller <mark@oc768.net> +wiz, Jason Dambrosio <jason@wiz.cx> +Xride, Søren Straarup <xride@x12.dk> +zb^3, Alfred Perlstein <alfred@freebsd.org> + +Others are welcome. Always. And if we left anyone off the above list, +be sure to let us know that too. Many others have contributed to +previous versions of this ircd and its ancestors, too many to list +here. + +Send bug fixes/complaints/rotten tomatoes to bugs@ircd-hybrid.org. @@ -0,0 +1,18 @@ + Known Bugs worthy of a mention: +-------------------------------------------------------------------------------- + +* None + + + BUG REPORTS: If you run this code and encounter problems, you should report + the bug on our SourceForge.net bug tracker, which you can find at this URL: + + https://sourceforge.net/tracker/?atid=409046&group_id=33573&func=browse + + Please include a gdb backtrace and a copy of your config.h and ircd.conf with + any report (with passwords and other sensitive information masked). + + For information how to get a gdb backtrace, see INSTALL (near the end of file). + +-------------------------------------------------------------------------------- +$Id$ @@ -0,0 +1,341 @@ +# $Id$ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 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,0 +1,156 @@ + Hybrid INSTALL Document + + $Id$ + + Copyright (c) 1997-2012 IRCD-Hybrid Development Team + + ---------------------------------------------------------------------- + + +------------------------------------------------------------------------+ + | Note for those who don't bother reading docs: | + | | + | Reading INSTALL is now a must, as the old DPATH is now specified when | + | configure is run. | + | | + | - You now need to ./configure --prefix="/path/to/install/it" as a | + | minimum. Try ./configure --help or read this file for more info on | + | the possible options you can pass to configure. | + | | + | - Important: The old config format WILL NOT WORK. Please see point 6! | + +------------------------------------------------------------------------+ + + ***** EFNET NOTE ***** + You should use the example.efnet.conf instead of example.conf. + ********************** + + ---------------------------------------------------------------------- + + HOW TO BUILD + + As of hybrid-4, the distribution uses GNU autoconf instead of the old + Config script. You must run ./configure before you can (sanely) build + ircd-hybrid. + + 1. Read the NEWS file to find out about the exciting new features in + this version. Other good reads are BUGS, doc/example.conf, and + README. + + 2. Run the configure script. It will create config.h and the + Makefiles to match your system. The paths are now handled + with the --prefix option to configure. + /usr/local/ircd is the default if no prefix is specified. + + ./configure --prefix=/usr/local/ircd + + The script will determine whichever of the following is best for + your system, but you may (unsupported) force their usage with + undefined results: + + * --enable-kqueue - Use the superior kqueue(2) system call as + opposed to the default poll(2). This is currently only available + on FreeBSD 4.1 or higher. + + * --enable-devpoll - Enable the superior /dev/poll support on + Solaris. Linux /dev/poll is broken and will not work with this + option. + + * --enable-epoll - Enables epoll(4) Signal I/O system. This is + currently only available on 2.5.44 Linux kernel versions or + later. + + * --enable-rtsigio - Enable the superior Linux RealTime Signal I/O + system. This is currently only available on 2.4 Linux kernel + versions or later. + + * --enable-poll - Use POSIX poll(2). + + * --enable-select - Use POSIX select(2). + + Incidentally, the order of listing above is the order of auto- + detection in configure. So if you do have kqueue but wish to + enable select(2) instead (bad idea), you must use --enable-select. + + * --enable-openssl - Enable the openssl dependent crypto functions. + Required for the SSL Challenge controlled OPER feature, compressed + and/or SSL/TLS server links, as well as SSL/TLS client connections. + + On systems where the configure script can automatically detect + OpenSSL, this option is not necessary. If configure cannot find + OpenSSL, you must specify a path with this option + (--enable-openssl=/path/to/openssl) + + + These are optional or have default values that may be overridden: + + * --enable-assert - Enable use of numerous debugging checks. This + should not be used on any production servers for maximum speed + so as to prevent cores from things that shouldn't normally happen. + + * --enable-halfops - Enable halfops (%, mode +h) usage. Halfops + are similar to plain ops, but can't kick/deop plain ops. Halfops + may or may not kick/deop other halfops depending on if (+p) is + set. Halfops may not set (+/-p). + + * --with-nicklen, + --with-topiclen - Respectively, sets the maximum NICK length and + maximum TOPIC length. Note that this must be consistent across your + entire network. Defaults are 9 and 120, respectively. + + + + 3. Run 'make'; this should build the ircd. + + 4. Run 'make install'; this will install the server, modules, and tools + in the path with the prefix specified when configure was ran. + + 5. If you wish to install the contrib modules, run 'make install' in the + contrib/ folder to compile and install the modules and help pages. + + 6. If you are upgrading from Hybrid 5 or Hybrid 6, the config files + have changed drastically. + + By default, the kline file is named kline.conf, the dline file is + named dline.conf, and the xline file is called xline.conf. + + The nick resv file is named nresv.conf, channel resv file is named + cresv.conf. + + ---------------------------------------------------------------------- + + HOW TO GET HELP + + - Send Check or Money Order to... just kidding! You're on your own for + support. Try asking other ircd-hybrid admins on EFnet if you can't + fix it yourself. If you do fix anything, however, please send context + or unified diffs to bugs@ircd-hybrid.org so the fixes can be + incorporated into the next release of ircd-hybrid. If hybrid crashes + on you, PLEASE contact bugs@ircd-hybrid.org ASAP with a backtrace of + the core. The Hybrid team can't fix bugs if no one tells us about them! + + - https://lists.ircd-hybrid.org/mailman/listinfo/hybrid + Here you can subscribe to a mailing list for general discussion of Hybrid. + + ---------------------------------------------------------------------- + + NOTES + + The best way to get a backtrace of the core is to follow this sequence of + instructions: + + 1. Change to the directory containing the core file + + 2. Run gdb on the binary and the core file. With an unmodified ircd-hybrid + installation, an example command line is below (in the /usr/local/ircd + directory) + + $ gdb bin/ircd ircd.core + + + 3. At the "(gdb)" prompt, enter the command "bt full" + + 4. Save the output of the backtrace command and send it to + bugs@ircd-hybrid.org. + + 5. Be sure to save the ircd binary, the modules, and the core file in a + safe place in case the developers need to look deeper than a backtrace + provides. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..0fcd28f --- /dev/null +++ b/Makefile.am @@ -0,0 +1,6 @@ +AUTOMAKE_OPTIONS = foreign +SUBDIRS = tools libltdl doc help messages modules src + +install-data-local: + $(INSTALL) -d $(DESTDIR)${localstatedir}/log + $(INSTALL) -d $(DESTDIR)${localstatedir}/run diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..07d98ef --- /dev/null +++ b/Makefile.in @@ -0,0 +1,792 @@ +# Makefile.in generated by automake 1.12.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/configure $(top_srcdir)/contrib/help/Makefile.in \ + AUTHORS COPYING INSTALL NEWS TODO config.guess config.sub \ + depcomp install-sh ltmain.sh missing ylwrap +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = contrib/help/Makefile +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + cscope distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBDIR = @LIBDIR@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PREFIX = @PREFIX@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +SUBDIRS = tools libltdl doc help messages modules src +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +contrib/help/Makefile: $(top_builddir)/config.status $(top_srcdir)/contrib/help/Makefile.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done +cscopelist-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) + +clean-cscope: + -rm -f cscope.files + +cscope.files: clean-cscope cscopelist-recursive cscopelist + +cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-data-local + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ + cscopelist-recursive ctags-recursive install-am install-strip \ + tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-cscope \ + clean-generic clean-libtool cscope cscopelist \ + cscopelist-recursive ctags ctags-recursive dist dist-all \ + dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ dist-xz \ + dist-zip distcheck distclean distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-data-local install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + + +install-data-local: + $(INSTALL) -d $(DESTDIR)${localstatedir}/log + $(INSTALL) -d $(DESTDIR)${localstatedir}/run + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: @@ -0,0 +1,113 @@ +-- ircd-hybrid-8.0.0 Release Notes +o) Fixed an off-by-one with spoofs. Spoofs are now also checked for + invalid characters +o) Removed general::use_whois_actually configuration directive. This is + now enabled by default +o) Minor SQUIT handling fixes +o) Fixed bancache not being updated on CHGHOST/CHGIDENT + + +-- ircd-hybrid-8rc1 Release Notes +o) Removed general::client_flood configuration option and added the + new 'recvq' configuration directive to class{} blocks. + The max size of a receive queue can be seen in "STATS Y" + for each class +o) Allow the '[' and ']' characters in server description + + +-- ircd-hybrid-8beta3 Release Notes +o) Fixed wrong syntax in several language files +o) Removed &localchannels +o) PRIVMSG to opers@some.server is no longer supported +o) Fixed bug that could lead to topic desynchronization +o) Removed serverhide::disable_hidden configuration option +o) Dropped ircd-hybrid-6 GLINE compatibility mode +o) Removed use_invex, use_except and use_knock configuration options. + These features are now enabled by default + + +-- ircd-hybrid-8beta2 Release Notes +o) channel::disable_fake_channels now also disables ascii 29 (mIRC italic) + when set to yes +o) Added channel::max_chans_per_oper configuration directive. The old way + was to let operators join three times the amount of max_chans_per_user +o) Replaced MODLOAD, MODUNLOAD, MODRELOAD, MODLIST and MODRESTART commands + with the new MODULE command which can be fed with the LOAD, UNLOAD, RELOAD + and LIST parameters. + MODRESTART has been entirely removed. Use "MODULE RELOAD *" to reload + all modules +o) Added back server notice when a client tries to obtain a reserved nick name +o) Removed OMOTD module +o) Added 'set' to operator privilege flags. Gives access to the "SET" command +o) Improved TS6 support +o) Channel keys/passwords are now case sensitive + + +-- ircd-hybrid-8beta1 Release Notes +o) Implemented full services support, including but not limited to the + following changes: + - Added SVSNICK, and SVSMODE command handlers + - Added service stamps to NICK/UID messages + - Added SVS to server capabilities (CAPAB). SVS capable servers can + deal with extended NICK/UID messages that contain service IDs/stamps. + - Changed rejected client notices to go to new usermode +j. These + previously used usermode +r. + - Added usermode +r (registered nick) and channelmode +r (registered channel) + - Added usermode +R (only registered clients may send a private message) + - Added channelmode +R (only registered clients may join that channel) + - Various services shortcuts have been added (/NS, /CS, /NICKSERV, /CHANSERV, etc.) + - Added services{} block to ircd.conf + - Added services_name directive to general{} block + - Added GLOBOPS mainly for services compatibility, but can be used by operators, too +o) Removed RKLINE and RXLINE commands. Regular expression based bans should + only be added via ircd.conf +o) Added 'globops', 'restart', 'dline', 'undline' and 'module' operator + privilege flags. Read doc/example.conf for further explanation of what + these flags control +o) Removed Idle-time klines +o) Cleaned up modules API. Old modules won't work anymore +o) Removed general::burst_away configuration directive. AWAY bursts are now + controlled via connect::flags explicitly +o) Introduced new logging subsystem including log rotation based on + file sizes. Log timestamp format is ISO8601 now +o) Added support for remote D-lines +o) Added usermode +H which is basically a replacement for the hidden_admin and + hidden_oper operator flags. With usermode +H, irc operator status can now + be hidden even on remote servers +o) Added CIDR support for operator{} blocks +o) Removed the servlink program. ircd-hybrid can now make use of + SSL/TLS for inter-server communication. + NOTE: compressed server links are of course still available, but a SSL/TLS + connection is required, as compression is now handled via OpenSSL +o) Removed 'ssl_server_protocol' configuration directive and + added 'ssl_client_method' and 'ssl_server_method' instead. + Both of these options can now be changed at runtime +o) Oper login IDs are no longer limited to NICKLEN*2 +o) Removed channel::burst_topicwho configuration option. Topicsetters are + now sent by default +o) "STATS Y|y" now reports CIDR limits as well +o) Added m_webirc.c to contrib/ +o) Overall code cleanup and speed improvements + +-------------------------------------------------------------------------------- + +BUGS: Major bugs in this release are listed in BUGS + +BUG REPORTS: If you run this code and encounter problems, you must report + the bug by EMAIL to bugs@ircd-hybrid.org + Please include a gdb backtrace and a copy of your config.h and + ircd.conf with any report (with passwords and other sensitive + information masked). + +DISCUSSION: There is a mailing list for discussion of hybrid issues, + including betas. To subscribe, use this link: + https://lists.ircd-hybrid.org/mailman/listinfo/hybrid + This is the proper place to discuss new features, bugs, etc. Posting here + is much more likely to get something done than ranting on #TZ. + +Questions/comments directed to bugs@ircd-hybrid.org + +Other files recommended for reading: BUGS, README, INSTALL + +-------------------------------------------------------------------------------- +$Id$ @@ -0,0 +1,72 @@ +Contact Information: + + * Bug Reports: + - bugs@ircd-hybrid.org + * General Discussion and Support mailing list: + - https://lists.ircd-hybrid.org/mailman/listinfo/hybrid + - hybrid@lists.ircd-hybrid.org + +******************************* IMPORTANT ************************************* + + + ************ Note for those who don't bother reading docs *************** + * - Reading INSTALL is now a must, as the old DPATH is now specified * + * when configure is run. * + * You now need to ./configure --prefix="/path/to/install/it" * + * - The old config format WILL NOT WORK. Please see doc/example.conf ! * + * - The old kline, dline, xline format WILL NOT WORK. * + ************************************************************************* + + ALSO, IF YOU ARE UPGRADING YOUR CURRENT SOURCE TREE, AND YOU TRY TO BUILD + IN IT WITHOUT PERFORMING AT LEAST 'make clean', THINGS _WILL_ BREAK. IT IS + RECOMMENDED THAT YOU RUN 'make distclean' AND THEN RERUN './configure'! + +******************************* REQUIREMENTS ********************************** + +Necessary Requirements: + +- A supported platform (look below) + +- A working dynamic load library + +Feature Specific Requirements: + +- For the SSL Challenge controlled OPER feature, compressed and/or + SSL/TLS server links, as well as SSL/TLS client connections, + a working OpenSSL library is required + +- For encrypted oper and (optional) server passwords, a working DES and/or + MD5 library + +- For regular expression based kline{} and gecos{} blocks, the + PCRE - Perl Compatible Regular Expressions library is required + +******************************************************************************* + +- See the INSTALL document for info on configuring and compiling + ircd-hybrid. + +- Please read doc/index.txt to get an overview of the current documentation. + +- Known bugs are listed in the BUGS file + +- TESTED PLATFORMS: The code has been tested on the following platforms, and + is known to run properly. + (FIXME: this list is out of date) + CentOS 5.8 + Red Hat Linux 9 + Ubuntu 12.04 + +- If you are wondering why config.h no longer exists, it's because most + things that were once in config.h are now specified in the 'general' + block of ircd.conf. Look at example.conf for more information about + these options. + +- /etc/resolv.conf must exist for the resolver to work. + +- Please read NEWS for information about what is in this release. + +- Other files recommended for reading: BUGS, INSTALL + +-------------------------------------------------------------------------------- +$Id$ diff --git a/RELNOTES b/RELNOTES deleted file mode 100644 index e69de29..0000000 --- a/RELNOTES +++ /dev/null @@ -0,0 +1,70 @@ +$Id$ + +- dynamically extensible parser for modules + +- modularize channel, network code etc (not just commands) + we can use override_function() or similar for this + => means prepared, now just make use of them + +- username/passwords (iauth ?) + +- make the reserved FD limit run-time tunable, esp from comm_open() + This involves making fd_table[] a dynamically growing/(don't bother with + shrinking) list.. have the max fd list configurable in the conf file.. + => partially done, just turn HARD_FDLIMIT into a variable + +- Add the IRCnet(?) split logic for nick collisions - on a nick collision, + change to "%d-%s", random, nick + => this is rather equal to their /nick 0, ie set nick to user's UID + +------------------------------------------------------------------------------ +Little things to be done given enough time and initiative -Hwy + +. <Riedel> walter : have you implemented the motd= thing in the auth block ? +. A FAQ +. More translations! + + +-- Rodder's list +. Add scalable database-based authentication. Probably part of Iauth. + Also add support for server-side notify with the list stored in the + auth database. This would make ircd an awesome instant messaging + back-end. + => currently possible to do as a module + + +-- Diane's list +* add logging to ircd.log of possible channel floods +* add code to log a minute worth of flooding if the ircd gets n possible + flood messages on a channel in t seconds.. This log would be available + to hand to authorities if requested. + + +-- Josh's list +* Find out the status of the build with IRIX64/MIPSpro. +* TENDRA IS BROKEN! (Not quite our fault) +* Fix lack of error message for oper initiating /connect that fails because +it's a leaf. + + +-- knight's list +* Add Czechoslovakian support. +* Database Authentication (IAUTH). +* VMS, NetBSD, Mac OS X (testing and porting). +* AMD64, Sparc(64) testing and development. +* Re-work nickname collision code to change + nicknames on collide rather than issue a + server kill. + + +-- adx's list +* modularize parser, channel modes, member flags and more +* split libio (engines, logging etc) from irc related sources? +* implement ND/CD split logic +* implement /nick 0 and uid addressing +* more I/O backends (ports) +* get rid of conf attaching as much as possible + + +-- metalrock's list +* Fix that missing server connection timed out notice. diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..e5cfd50 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,196 @@ +dnl Inspired by work Copyright (C) 2006 Luca Filipozzi +dnl vim: set fdm=marker sw=2 ts=2 et si: +dnl {{{ ax_check_lib_ipv4 +AC_DEFUN([AX_CHECK_LIB_IPV4],[ + AC_SEARCH_LIBS([socket],[socket],,[AC_MSG_ERROR([socket library not found])]) + AC_SEARCH_LIBS([inet_ntoa], [nsl]) + AC_SEARCH_LIBS([inet_aton], [resolv]) + AC_CHECK_FUNCS([inet_aton inet_ntop inet_pton]) + AC_CHECK_TYPES([struct sockaddr_in, struct sockaddr_storage, struct addrinfo],,,[#include <sys/types.h> + #include <sys/socket.h> + #include <netdb.h> + ]) + AC_CHECK_MEMBERS([struct sockaddr_in.sin_len],,,[#include <sys/types.h> + <sys/socket.h>]) +])dnl }}} +dnl {{{ ax_check_lib_ipv6 +AC_DEFUN([AX_CHECK_LIB_IPV6],[ + AC_CHECK_TYPE([struct sockaddr_in6],[AC_DEFINE([IPV6],[1],[Define to 1 if you have IPv6 support.])],,[#include <netinet/in.h>]) +])dnl }}} +dnl {{{ ax_arg_enable_ioloop_mechanism (FIXME) +AC_DEFUN([AX_ARG_ENABLE_IOLOOP_MECHANISM],[ + dnl {{{ allow the user to specify desired mechanism + desired_iopoll_mechanism="none" + dnl FIXME need to handle arguments a bit better (see ac_arg_disable_block_alloc) + AC_ARG_ENABLE([kqueue], [AS_HELP_STRING([--enable-kqueue], [Force kqueue usage.])], [desired_iopoll_mechanism="kqueue"]) + AC_ARG_ENABLE([epoll], [AS_HELP_STRING([--enable-epoll], [Force epoll usage.])], [desired_iopoll_mechanism="epoll"]) + AC_ARG_ENABLE([devpoll],[AS_HELP_STRING([--enable-devpoll],[Force devpoll usage.])],[desired_iopoll_mechanism="devpoll"]) + AC_ARG_ENABLE([rtsigio],[AS_HELP_STRING([--enable-rtsigio],[Force rtsigio usage.])],[desired_iopoll_mechanism="rtsigio"]) + AC_ARG_ENABLE([poll], [AS_HELP_STRING([--enable-poll], [Force poll usage.])], [desired_iopoll_mechanism="poll"]) + AC_ARG_ENABLE([select], [AS_HELP_STRING([--enable-select], [Force select usage.])], [desired_iopoll_mechanism="select"]) + dnl }}} + dnl {{{ preamble + AC_MSG_CHECKING([for optimal/desired iopoll mechanism]) + iopoll_mechanism_none=0 + AC_DEFINE_UNQUOTED([__IOPOLL_MECHANISM_NONE],[$iopoll_mechanism_none],[no iopoll mechanism]) + dnl }}} + dnl {{{ check for kqueue mechanism support + iopoll_mechanism_kqueue=1 + AC_DEFINE_UNQUOTED([__IOPOLL_MECHANISM_KQUEUE],[$iopoll_mechanism_kqueue],[kqueue mechanism]) + AC_LINK_IFELSE([AC_LANG_FUNC_LINK_TRY([kevent])],[is_kqueue_mechanism_available="yes"],[is_kqueue_mechanism_available="no"]) + dnl }}} + dnl {{{ check for epoll oechanism support + iopoll_mechanism_epoll=2 + AC_DEFINE_UNQUOTED([__IOPOLL_MECHANISM_EPOLL],[$iopoll_mechanism_epoll],[epoll mechanism]) + AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include <sys/epoll.h> +#include <sys/syscall.h> +#if defined(__stub_epoll_create) || defined(__stub___epoll_create) || defined(EPOLL_NEED_BODY) +#if !defined(__NR_epoll_create) +#if defined(__ia64__) +#define __NR_epoll_create 1243 +#elif defined(__x86_64__) +#define __NR_epoll_create 214 +#elif defined(__sparc64__) || defined(__sparc__) +#define __NR_epoll_create 193 +#elif defined(__s390__) || defined(__m68k__) +#define __NR_epoll_create 249 +#elif defined(__ppc64__) || defined(__ppc__) +#define __NR_epoll_create 236 +#elif defined(__parisc__) || defined(__arm26__) || defined(__arm__) +#define __NR_epoll_create 224 +#elif defined(__alpha__) +#define __NR_epoll_create 407 +#elif defined(__sh64__) +#define __NR_epoll_create 282 +#elif defined(__i386__) || defined(__sh__) || defined(__m32r__) || defined(__h8300__) || defined(__frv__) +#define __NR_epoll_create 254 +#else +#error No system call numbers defined for epoll family. +#endif +#endif +_syscall1(int, epoll_create, int, size) +#endif +]], [[ return epoll_create(256) == -1 ? 1 : 0 ]])], + [is_epoll_mechanism_available="yes"],[is_epoll_mechanism_available="no"]) + dnl }}} + dnl {{{ check for devpoll mechanism support + iopoll_mechanism_devpoll=3 + AC_DEFINE_UNQUOTED([__IOPOLL_MECHANISM_DEVPOLL],[$iopoll_mechanism_devpoll],[devpoll mechanism]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <devpoll.h>])],[is_devpoll_mechanism_available="yes"],[is_devpoll_mechanism_available="no"]) + if test "$is_devpoll_mechanism_available" = "yes" ; then + AC_DEFINE([HAVE_DEVPOLL_H],[1],[Define to 1 if you have the <devpoll.h> header file.]) + fi + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <sys/devpoll.h>])],[is_devpoll_mechanism_available="yes"],[is_devpoll_mechanism_available="no"]) + if test "$is_devpoll_mechanism_available" = "yes" ; then + AC_DEFINE([HAVE_SYS_DEVPOLL_H],[1],[Define to 1 if you have the <sys/devpoll.h> header file.]) + fi + dnl }}} + dnl {{{ check for rtsigio mechanism support + iopoll_mechanism_rtsigio=4 + AC_DEFINE_UNQUOTED([__IOPOLL_MECHANISM_RTSIGIO],[$iopoll_mechanism_rtsigio],[rtsigio mechanism]) + AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#define _GNU_SOURCE +#include <fcntl.h> +static unsigned int have_f_setsig = 0; + ]], [[ +#ifdef F_SETSIG + have_f_setsig = 1; +#endif + return have_f_setsig == 0; + ]])], [is_rtsigio_mechanism_available="yes"],[is_rtsigio_mechanism_available="no"]) + dnl }}} + dnl {{{ check for poll mechanism support + iopoll_mechanism_poll=5 + AC_DEFINE_UNQUOTED([__IOPOLL_MECHANISM_POLL],[$iopoll_mechanism_poll],[poll mechanism]) + AC_LINK_IFELSE([AC_LANG_FUNC_LINK_TRY([poll])],[is_poll_mechanism_available="yes"],[is_poll_mechanism_available="no"]) + dnl }}} + dnl {{{ check for select mechanism support + iopoll_mechanism_select=6 + AC_DEFINE_UNQUOTED([__IOPOLL_MECHANISM_SELECT],[$iopoll_mechanism_select],[select mechanism]) + AC_LINK_IFELSE([AC_LANG_FUNC_LINK_TRY([select])],[is_select_mechanism_available="yes"],[is_select_mechanism_available="no"]) + dnl }}} + dnl {{{ determine the optimal mechanism + optimal_iopoll_mechanism="none" + for mechanism in "kqueue" "epoll" "devpoll" "rtsigio" "poll" "select" ; do # order is important + eval "is_optimal_iopoll_mechanism_available=\$is_${mechanism}_mechanism_available" + if test "$is_optimal_iopoll_mechanism_available" = "yes" ; then + optimal_iopoll_mechanism="$mechanism" + break + fi + done + dnl }}} + dnl {{{ select between optimal mechanism and desired mechanism (if specified) + if test "$desired_iopoll_mechanism" = "none" ; then + if test "$optimal_iopoll_mechanism" = "none" ; then + AC_MSG_RESULT([none]) + AC_MSG_ERROR([no iopoll mechanism found!]) + else + selected_iopoll_mechanism=$optimal_iopoll_mechanism + AC_MSG_RESULT([$selected_iopoll_mechanism]) + fi + else + eval "is_desired_iopoll_mechanism_available=\$is_${desired_iopoll_mechanism}_mechanism_available" + if test "$is_desired_iopoll_mechanism_available" = "yes" ; then + selected_iopoll_mechanism=$desired_iopoll_mechanism + AC_MSG_RESULT([$selected_iopoll_mechanism]) + else + AC_MSG_RESULT([none]) + AC_MSG_ERROR([desired iopoll mechanism, $desired_iopoll_mechanism, is not available]) + fi + fi + dnl }}} + dnl {{{ postamble + eval "use_iopoll_mechanism=\$iopoll_mechanism_${selected_iopoll_mechanism}" + AC_DEFINE_UNQUOTED([USE_IOPOLL_MECHANISM],[$use_iopoll_mechanism],[use this iopoll mechanism]) + dnl }}} +])dnl }}} +dnl {{{ ax_arg_with_topiclen +AC_DEFUN([AX_ARG_WITH_TOPICLEN],[ + AC_ARG_WITH([topiclen],[AS_HELP_STRING([--with-topiclen=<value>],[Set topic length (default 160).])],[topiclen="$withval"],[topiclen="160"]) + AC_DEFINE_UNQUOTED([TOPICLEN],[($topiclen)],[Length of topics.]) +])dnl }}} +dnl {{{ ax_arg_with_nicklen +AC_DEFUN([AX_ARG_WITH_NICKLEN],[ + AC_ARG_WITH([nicklen],[AS_HELP_STRING([--with-nicklen=<value>],[Set nickname length (default 9).])],[nicklen="$withval"],[nicklen="9"]) + AC_DEFINE_UNQUOTED([NICKLEN],[($nicklen)],[Length of nicknames.]) +])dnl }}} +dnl {{{ ax_arg_enable_halfops +AC_DEFUN([AX_ARG_ENABLE_HALFOPS],[ + AC_ARG_ENABLE([halfops],[AS_HELP_STRING([--enable-halfops],[Enable halfops support.])],[halfops="$enableval"],[halfops="no"]) + if test "$halfops" = "yes" ; then + AC_DEFINE([HALFOPS],[1],[Define to 1 if you want halfops support.]) + fi +])dnl }}} +dnl {{{ ax_arg_enable_debugging +AC_DEFUN([AX_ARG_ENABLE_DEBUGGING],[ + AC_ARG_ENABLE([debugging],[AS_HELP_STRING([--enable-debugging],[Enable debugging.])],[debugging="$enableval"],[debugging="no"]) + if test "$debugging" = "yes" ; then + AC_DEFINE([DEBUG],[1],[Define to 1 to enable debugging.]) + CFLAGS="-Wall -g -O0" + else + AC_DEFINE([NDEBUG],[1],[Define to 1 to disable debugging.]) + fi +])dnl }}} +dnl {{{ ax_arg_enable_warnings +AC_DEFUN([AX_ARG_ENABLE_WARNINGS],[ + AC_ARG_ENABLE([warnings],[AS_HELP_STRING([--enable-warnings],[Enable compiler warnings.])],[warnings="$enableval"],[warnings="no"]) + if test "$warnings" = "yes" ; then + CFLAGS="-Wall -Wextra -Wno-unused -Wcast-qual -Wcast-align -Wbad-function-cast -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wredundant-decls -Wshadow -Wwrite-strings -Wundef" + fi +])dnl }}} +dnl {{{ ac_define_dir +dnl http://autoconf-archive.cryp.to/ac_define_dir.html +AC_DEFUN([AC_DEFINE_DIR], [ + prefix_NONE= + exec_prefix_NONE= + test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix + test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix + eval ac_define_dir="\"[$]$2\"" + eval ac_define_dir="\"$ac_define_dir\"" + AC_SUBST($1, "$ac_define_dir") + AC_DEFINE_UNQUOTED($1, "$ac_define_dir", [$3]) + test "$prefix_NONE" && prefix=NONE + test "$exec_prefix_NONE" && exec_prefix=NONE +])dnl }}} +]) dnl }}} diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..8caf67c --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,10486 @@ +# generated automatically by aclocal 1.12.4 -*- Autoconf -*- + +# Copyright (C) 1996-2012 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Portability macros for glibc argz. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. +# Written by Gary V. Vaughan <gary@gnu.org> +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 argz.m4 + +AC_DEFUN([gl_FUNC_ARGZ], +[gl_PREREQ_ARGZ + +AC_CHECK_HEADERS([argz.h], [], [], [AC_INCLUDES_DEFAULT]) + +AC_CHECK_TYPES([error_t], + [], + [AC_DEFINE([error_t], [int], + [Define to a type to use for `error_t' if it is not otherwise available.]) + AC_DEFINE([__error_t_defined], [1], [Define so that glibc/gnulib argp.h + does not typedef error_t.])], + [#if defined(HAVE_ARGZ_H) +# include <argz.h> +#endif]) + +ARGZ_H= +AC_CHECK_FUNCS([argz_add argz_append argz_count argz_create_sep argz_insert \ + argz_next argz_stringify], [], [ARGZ_H=argz.h; AC_LIBOBJ([argz])]) + +dnl if have system argz functions, allow forced use of +dnl libltdl-supplied implementation (and default to do so +dnl on "known bad" systems). Could use a runtime check, but +dnl (a) detecting malloc issues is notoriously unreliable +dnl (b) only known system that declares argz functions, +dnl provides them, yet they are broken, is cygwin +dnl releases prior to 16-Mar-2007 (1.5.24 and earlier) +dnl So, it's more straightforward simply to special case +dnl this for known bad systems. +AS_IF([test -z "$ARGZ_H"], + [AC_CACHE_CHECK( + [if argz actually works], + [lt_cv_sys_argz_works], + [[case $host_os in #( + *cygwin*) + lt_cv_sys_argz_works=no + if test "$cross_compiling" != no; then + lt_cv_sys_argz_works="guessing no" + else + lt_sed_extract_leading_digits='s/^\([0-9\.]*\).*/\1/' + save_IFS=$IFS + IFS=-. + set x `uname -r | sed -e "$lt_sed_extract_leading_digits"` + IFS=$save_IFS + lt_os_major=${2-0} + lt_os_minor=${3-0} + lt_os_micro=${4-0} + if test "$lt_os_major" -gt 1 \ + || { test "$lt_os_major" -eq 1 \ + && { test "$lt_os_minor" -gt 5 \ + || { test "$lt_os_minor" -eq 5 \ + && test "$lt_os_micro" -gt 24; }; }; }; then + lt_cv_sys_argz_works=yes + fi + fi + ;; #( + *) lt_cv_sys_argz_works=yes ;; + esac]]) + AS_IF([test "$lt_cv_sys_argz_works" = yes], + [AC_DEFINE([HAVE_WORKING_ARGZ], 1, + [This value is set to 1 to indicate that the system argz facility works])], + [ARGZ_H=argz.h + AC_LIBOBJ([argz])])]) + +AC_SUBST([ARGZ_H]) +]) + +# Prerequisites of lib/argz.c. +AC_DEFUN([gl_PREREQ_ARGZ], [:]) + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to <bug-libtool@gnu.org>." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$lt_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +_LT_PATH_LD_GNU +AC_SUBST([LD]) + +_LT_TAGDECL([], [LD], [1], [The linker used to build libraries]) +])# LT_PATH_LD + +# Old names: +AU_ALIAS([AM_PROG_LD], [LT_PATH_LD]) +AU_ALIAS([AC_PROG_LD], [LT_PATH_LD]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_LD], []) +dnl AC_DEFUN([AC_PROG_LD], []) + + +# _LT_PATH_LD_GNU +#- -------------- +m4_defun([_LT_PATH_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$lt_cv_prog_gnu_ld +])# _LT_PATH_LD_GNU + + +# _LT_CMD_RELOAD +# -------------- +# find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +m4_defun([_LT_CMD_RELOAD], +[AC_CACHE_CHECK([for $LD option to reload object files], + lt_cv_ld_reload_flag, + [lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac +_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl +_LT_TAGDECL([], [reload_cmds], [2])dnl +])# _LT_CMD_RELOAD + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[[4-9]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS + +# ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*- +# +# Copyright (C) 1999-2006, 2007, 2008, 2011 Free Software Foundation, Inc. +# Written by Thomas Tanner, 1999 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 18 LTDL_INIT + +# LT_CONFIG_LTDL_DIR(DIRECTORY, [LTDL-MODE]) +# ------------------------------------------ +# DIRECTORY contains the libltdl sources. It is okay to call this +# function multiple times, as long as the same DIRECTORY is always given. +AC_DEFUN([LT_CONFIG_LTDL_DIR], +[AC_BEFORE([$0], [LTDL_INIT]) +_$0($*) +])# LT_CONFIG_LTDL_DIR + +# We break this out into a separate macro, so that we can call it safely +# internally without being caught accidentally by the sed scan in libtoolize. +m4_defun([_LT_CONFIG_LTDL_DIR], +[dnl remove trailing slashes +m4_pushdef([_ARG_DIR], m4_bpatsubst([$1], [/*$])) +m4_case(_LTDL_DIR, + [], [dnl only set lt_ltdl_dir if _ARG_DIR is not simply `.' + m4_if(_ARG_DIR, [.], + [], + [m4_define([_LTDL_DIR], _ARG_DIR) + _LT_SHELL_INIT([lt_ltdl_dir=']_ARG_DIR['])])], + [m4_if(_ARG_DIR, _LTDL_DIR, + [], + [m4_fatal([multiple libltdl directories: `]_LTDL_DIR[', `]_ARG_DIR['])])]) +m4_popdef([_ARG_DIR]) +])# _LT_CONFIG_LTDL_DIR + +# Initialise: +m4_define([_LTDL_DIR], []) + + +# _LT_BUILD_PREFIX +# ---------------- +# If Autoconf is new enough, expand to `${top_build_prefix}', otherwise +# to `${top_builddir}/'. +m4_define([_LT_BUILD_PREFIX], +[m4_ifdef([AC_AUTOCONF_VERSION], + [m4_if(m4_version_compare(m4_defn([AC_AUTOCONF_VERSION]), [2.62]), + [-1], [m4_ifdef([_AC_HAVE_TOP_BUILD_PREFIX], + [${top_build_prefix}], + [${top_builddir}/])], + [${top_build_prefix}])], + [${top_builddir}/])[]dnl +]) + + +# LTDL_CONVENIENCE +# ---------------- +# sets LIBLTDL to the link flags for the libltdl convenience library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-convenience to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. LIBLTDL will be prefixed with +# '${top_build_prefix}' if available, otherwise with '${top_builddir}/', +# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single +# quotes!). If your package is not flat and you're not using automake, +# define top_build_prefix, top_builddir, and top_srcdir appropriately +# in your Makefiles. +AC_DEFUN([LTDL_CONVENIENCE], +[AC_BEFORE([$0], [LTDL_INIT])dnl +dnl Although the argument is deprecated and no longer documented, +dnl LTDL_CONVENIENCE used to take a DIRECTORY orgument, if we have one +dnl here make sure it is the same as any other declaration of libltdl's +dnl location! This also ensures lt_ltdl_dir is set when configure.ac is +dnl not yet using an explicit LT_CONFIG_LTDL_DIR. +m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl +_$0() +])# LTDL_CONVENIENCE + +# AC_LIBLTDL_CONVENIENCE accepted a directory argument in older libtools, +# now we have LT_CONFIG_LTDL_DIR: +AU_DEFUN([AC_LIBLTDL_CONVENIENCE], +[_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) +_LTDL_CONVENIENCE]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBLTDL_CONVENIENCE], []) + + +# _LTDL_CONVENIENCE +# ----------------- +# Code shared by LTDL_CONVENIENCE and LTDL_INIT([convenience]). +m4_defun([_LTDL_CONVENIENCE], +[case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; +esac +LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdlc.la" +LTDLDEPS=$LIBLTDL +LTDLINCL='-I${top_srcdir}'"${lt_ltdl_dir+/$lt_ltdl_dir}" + +AC_SUBST([LIBLTDL]) +AC_SUBST([LTDLDEPS]) +AC_SUBST([LTDLINCL]) + +# For backwards non-gettext consistent compatibility... +INCLTDL="$LTDLINCL" +AC_SUBST([INCLTDL]) +])# _LTDL_CONVENIENCE + + +# LTDL_INSTALLABLE +# ---------------- +# sets LIBLTDL to the link flags for the libltdl installable library +# and LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-install to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called from here. If an installed libltdl +# is not found, LIBLTDL will be prefixed with '${top_build_prefix}' if +# available, otherwise with '${top_builddir}/', and LTDLINCL will be +# prefixed with '${top_srcdir}/' (note the single quotes!). If your +# package is not flat and you're not using automake, define top_build_prefix, +# top_builddir, and top_srcdir appropriately in your Makefiles. +# In the future, this macro may have to be called after LT_INIT. +AC_DEFUN([LTDL_INSTALLABLE], +[AC_BEFORE([$0], [LTDL_INIT])dnl +dnl Although the argument is deprecated and no longer documented, +dnl LTDL_INSTALLABLE used to take a DIRECTORY orgument, if we have one +dnl here make sure it is the same as any other declaration of libltdl's +dnl location! This also ensures lt_ltdl_dir is set when configure.ac is +dnl not yet using an explicit LT_CONFIG_LTDL_DIR. +m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl +_$0() +])# LTDL_INSTALLABLE + +# AC_LIBLTDL_INSTALLABLE accepted a directory argument in older libtools, +# now we have LT_CONFIG_LTDL_DIR: +AU_DEFUN([AC_LIBLTDL_INSTALLABLE], +[_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) +_LTDL_INSTALLABLE]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBLTDL_INSTALLABLE], []) + + +# _LTDL_INSTALLABLE +# ----------------- +# Code shared by LTDL_INSTALLABLE and LTDL_INIT([installable]). +m4_defun([_LTDL_INSTALLABLE], +[if test -f $prefix/lib/libltdl.la; then + lt_save_LDFLAGS="$LDFLAGS" + LDFLAGS="-L$prefix/lib $LDFLAGS" + AC_CHECK_LIB([ltdl], [lt_dlinit], [lt_lib_ltdl=yes]) + LDFLAGS="$lt_save_LDFLAGS" + if test x"${lt_lib_ltdl-no}" = xyes; then + if test x"$enable_ltdl_install" != xyes; then + # Don't overwrite $prefix/lib/libltdl.la without --enable-ltdl-install + AC_MSG_WARN([not overwriting libltdl at $prefix, force with `--enable-ltdl-install']) + enable_ltdl_install=no + fi + elif test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + fi +fi + +# If configure.ac declared an installable ltdl, and the user didn't override +# with --disable-ltdl-install, we will install the shipped libltdl. +case $enable_ltdl_install in + no) ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLDEPS= + LTDLINCL= + ;; + *) enable_ltdl_install=yes + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdl.la" + LTDLDEPS=$LIBLTDL + LTDLINCL='-I${top_srcdir}'"${lt_ltdl_dir+/$lt_ltdl_dir}" + ;; +esac + +AC_SUBST([LIBLTDL]) +AC_SUBST([LTDLDEPS]) +AC_SUBST([LTDLINCL]) + +# For backwards non-gettext consistent compatibility... +INCLTDL="$LTDLINCL" +AC_SUBST([INCLTDL]) +])# LTDL_INSTALLABLE + + +# _LTDL_MODE_DISPATCH +# ------------------- +m4_define([_LTDL_MODE_DISPATCH], +[dnl If _LTDL_DIR is `.', then we are configuring libltdl itself: +m4_if(_LTDL_DIR, [], + [], + dnl if _LTDL_MODE was not set already, the default value is `subproject': + [m4_case(m4_default(_LTDL_MODE, [subproject]), + [subproject], [AC_CONFIG_SUBDIRS(_LTDL_DIR) + _LT_SHELL_INIT([lt_dlopen_dir="$lt_ltdl_dir"])], + [nonrecursive], [_LT_SHELL_INIT([lt_dlopen_dir="$lt_ltdl_dir"; lt_libobj_prefix="$lt_ltdl_dir/"])], + [recursive], [], + [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])])dnl +dnl Be careful not to expand twice: +m4_define([$0], []) +])# _LTDL_MODE_DISPATCH + + +# _LT_LIBOBJ(MODULE_NAME) +# ----------------------- +# Like AC_LIBOBJ, except that MODULE_NAME goes into _LT_LIBOBJS instead +# of into LIBOBJS. +AC_DEFUN([_LT_LIBOBJ], [ + m4_pattern_allow([^_LT_LIBOBJS$]) + _LT_LIBOBJS="$_LT_LIBOBJS $1.$ac_objext" +])# _LT_LIBOBJS + + +# LTDL_INIT([OPTIONS]) +# -------------------- +# Clients of libltdl can use this macro to allow the installer to +# choose between a shipped copy of the ltdl sources or a preinstalled +# version of the library. If the shipped ltdl sources are not in a +# subdirectory named libltdl, the directory name must be given by +# LT_CONFIG_LTDL_DIR. +AC_DEFUN([LTDL_INIT], +[dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +dnl We need to keep our own list of libobjs separate from our parent project, +dnl and the easiest way to do that is redefine the AC_LIBOBJs macro while +dnl we look for our own LIBOBJs. +m4_pushdef([AC_LIBOBJ], m4_defn([_LT_LIBOBJ])) +m4_pushdef([AC_LIBSOURCES]) + +dnl If not otherwise defined, default to the 1.5.x compatible subproject mode: +m4_if(_LTDL_MODE, [], + [m4_define([_LTDL_MODE], m4_default([$2], [subproject])) + m4_if([-1], [m4_bregexp(_LTDL_MODE, [\(subproject\|\(non\)?recursive\)])], + [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])]) + +AC_ARG_WITH([included_ltdl], + [AS_HELP_STRING([--with-included-ltdl], + [use the GNU ltdl sources included here])]) + +if test "x$with_included_ltdl" != xyes; then + # We are not being forced to use the included libltdl sources, so + # decide whether there is a useful installed version we can use. + AC_CHECK_HEADER([ltdl.h], + [AC_CHECK_DECL([lt_dlinterface_register], + [AC_CHECK_LIB([ltdl], [lt_dladvise_preload], + [with_included_ltdl=no], + [with_included_ltdl=yes])], + [with_included_ltdl=yes], + [AC_INCLUDES_DEFAULT + #include <ltdl.h>])], + [with_included_ltdl=yes], + [AC_INCLUDES_DEFAULT] + ) +fi + +dnl If neither LT_CONFIG_LTDL_DIR, LTDL_CONVENIENCE nor LTDL_INSTALLABLE +dnl was called yet, then for old times' sake, we assume libltdl is in an +dnl eponymous directory: +AC_PROVIDE_IFELSE([LT_CONFIG_LTDL_DIR], [], [_LT_CONFIG_LTDL_DIR([libltdl])]) + +AC_ARG_WITH([ltdl_include], + [AS_HELP_STRING([--with-ltdl-include=DIR], + [use the ltdl headers installed in DIR])]) + +if test -n "$with_ltdl_include"; then + if test -f "$with_ltdl_include/ltdl.h"; then : + else + AC_MSG_ERROR([invalid ltdl include directory: `$with_ltdl_include']) + fi +else + with_ltdl_include=no +fi + +AC_ARG_WITH([ltdl_lib], + [AS_HELP_STRING([--with-ltdl-lib=DIR], + [use the libltdl.la installed in DIR])]) + +if test -n "$with_ltdl_lib"; then + if test -f "$with_ltdl_lib/libltdl.la"; then : + else + AC_MSG_ERROR([invalid ltdl library directory: `$with_ltdl_lib']) + fi +else + with_ltdl_lib=no +fi + +case ,$with_included_ltdl,$with_ltdl_include,$with_ltdl_lib, in + ,yes,no,no,) + m4_case(m4_default(_LTDL_TYPE, [convenience]), + [convenience], [_LTDL_CONVENIENCE], + [installable], [_LTDL_INSTALLABLE], + [m4_fatal([unknown libltdl build type: ]_LTDL_TYPE)]) + ;; + ,no,no,no,) + # If the included ltdl is not to be used, then use the + # preinstalled libltdl we found. + AC_DEFINE([HAVE_LTDL], [1], + [Define this if a modern libltdl is already installed]) + LIBLTDL=-lltdl + LTDLDEPS= + LTDLINCL= + ;; + ,no*,no,*) + AC_MSG_ERROR([`--with-ltdl-include' and `--with-ltdl-lib' options must be used together]) + ;; + *) with_included_ltdl=no + LIBLTDL="-L$with_ltdl_lib -lltdl" + LTDLDEPS= + LTDLINCL="-I$with_ltdl_include" + ;; +esac +INCLTDL="$LTDLINCL" + +# Report our decision... +AC_MSG_CHECKING([where to find libltdl headers]) +AC_MSG_RESULT([$LTDLINCL]) +AC_MSG_CHECKING([where to find libltdl library]) +AC_MSG_RESULT([$LIBLTDL]) + +_LTDL_SETUP + +dnl restore autoconf definition. +m4_popdef([AC_LIBOBJ]) +m4_popdef([AC_LIBSOURCES]) + +AC_CONFIG_COMMANDS_PRE([ + _ltdl_libobjs= + _ltdl_ltlibobjs= + if test -n "$_LT_LIBOBJS"; then + # Remove the extension. + _lt_sed_drop_objext='s/\.o$//;s/\.obj$//' + for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | sed "$_lt_sed_drop_objext" | sort -u`; do + _ltdl_libobjs="$_ltdl_libobjs $lt_libobj_prefix$i.$ac_objext" + _ltdl_ltlibobjs="$_ltdl_ltlibobjs $lt_libobj_prefix$i.lo" + done + fi + AC_SUBST([ltdl_LIBOBJS], [$_ltdl_libobjs]) + AC_SUBST([ltdl_LTLIBOBJS], [$_ltdl_ltlibobjs]) +]) + +# Only expand once: +m4_define([LTDL_INIT]) +])# LTDL_INIT + +# Old names: +AU_DEFUN([AC_LIB_LTDL], [LTDL_INIT($@)]) +AU_DEFUN([AC_WITH_LTDL], [LTDL_INIT($@)]) +AU_DEFUN([LT_WITH_LTDL], [LTDL_INIT($@)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIB_LTDL], []) +dnl AC_DEFUN([AC_WITH_LTDL], []) +dnl AC_DEFUN([LT_WITH_LTDL], []) + + +# _LTDL_SETUP +# ----------- +# Perform all the checks necessary for compilation of the ltdl objects +# -- including compiler checks and header checks. This is a public +# interface mainly for the benefit of libltdl's own configure.ac, most +# other users should call LTDL_INIT instead. +AC_DEFUN([_LTDL_SETUP], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_SYS_MODULE_EXT])dnl +AC_REQUIRE([LT_SYS_MODULE_PATH])dnl +AC_REQUIRE([LT_SYS_DLSEARCH_PATH])dnl +AC_REQUIRE([LT_LIB_DLLOAD])dnl +AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl +AC_REQUIRE([LT_FUNC_DLSYM_USCORE])dnl +AC_REQUIRE([LT_SYS_DLOPEN_DEPLIBS])dnl +AC_REQUIRE([gl_FUNC_ARGZ])dnl + +m4_require([_LT_CHECK_OBJDIR])dnl +m4_require([_LT_HEADER_DLFCN])dnl +m4_require([_LT_CHECK_DLPREOPEN])dnl +m4_require([_LT_DECL_SED])dnl + +dnl Don't require this, or it will be expanded earlier than the code +dnl that sets the variables it relies on: +_LT_ENABLE_INSTALL + +dnl _LTDL_MODE specific code must be called at least once: +_LTDL_MODE_DISPATCH + +# In order that ltdl.c can compile, find out the first AC_CONFIG_HEADERS +# the user used. This is so that ltdl.h can pick up the parent projects +# config.h file, The first file in AC_CONFIG_HEADERS must contain the +# definitions required by ltdl.c. +# FIXME: Remove use of undocumented AC_LIST_HEADERS (2.59 compatibility). +AC_CONFIG_COMMANDS_PRE([dnl +m4_pattern_allow([^LT_CONFIG_H$])dnl +m4_ifset([AH_HEADER], + [LT_CONFIG_H=AH_HEADER], + [m4_ifset([AC_LIST_HEADERS], + [LT_CONFIG_H=`echo "AC_LIST_HEADERS" | $SED 's,^[[ ]]*,,;s,[[ :]].*$,,'`], + [])])]) +AC_SUBST([LT_CONFIG_H]) + +AC_CHECK_HEADERS([unistd.h dl.h sys/dl.h dld.h mach-o/dyld.h dirent.h], + [], [], [AC_INCLUDES_DEFAULT]) + +AC_CHECK_FUNCS([closedir opendir readdir], [], [AC_LIBOBJ([lt__dirent])]) +AC_CHECK_FUNCS([strlcat strlcpy], [], [AC_LIBOBJ([lt__strl])]) + +m4_pattern_allow([LT_LIBEXT])dnl +AC_DEFINE_UNQUOTED([LT_LIBEXT],["$libext"],[The archive extension]) + +name= +eval "lt_libprefix=\"$libname_spec\"" +m4_pattern_allow([LT_LIBPREFIX])dnl +AC_DEFINE_UNQUOTED([LT_LIBPREFIX],["$lt_libprefix"],[The archive prefix]) + +name=ltdl +eval "LTDLOPEN=\"$libname_spec\"" +AC_SUBST([LTDLOPEN]) +])# _LTDL_SETUP + + +# _LT_ENABLE_INSTALL +# ------------------ +m4_define([_LT_ENABLE_INSTALL], +[AC_ARG_ENABLE([ltdl-install], + [AS_HELP_STRING([--enable-ltdl-install], [install libltdl])]) + +case ,${enable_ltdl_install},${enable_ltdl_convenience} in + *yes*) ;; + *) enable_ltdl_convenience=yes ;; +esac + +m4_ifdef([AM_CONDITIONAL], +[AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno) + AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno)]) +])# _LT_ENABLE_INSTALL + + +# LT_SYS_DLOPEN_DEPLIBS +# --------------------- +AC_DEFUN([LT_SYS_DLOPEN_DEPLIBS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_CACHE_CHECK([whether deplibs are loaded by dlopen], + [lt_cv_sys_dlopen_deplibs], + [# PORTME does your system automatically load deplibs for dlopen? + # or its logical equivalent (e.g. shl_load for HP-UX < 11) + # For now, we just catch OSes we know something about -- in the + # future, we'll try test this programmatically. + lt_cv_sys_dlopen_deplibs=unknown + case $host_os in + aix3*|aix4.1.*|aix4.2.*) + # Unknown whether this is true for these versions of AIX, but + # we want this `case' here to explicitly catch those versions. + lt_cv_sys_dlopen_deplibs=unknown + ;; + aix[[4-9]]*) + lt_cv_sys_dlopen_deplibs=yes + ;; + amigaos*) + case $host_cpu in + powerpc) + lt_cv_sys_dlopen_deplibs=no + ;; + esac + ;; + darwin*) + # Assuming the user has installed a libdl from somewhere, this is true + # If you are looking for one http://www.opendarwin.org/projects/dlcompat + lt_cv_sys_dlopen_deplibs=yes + ;; + freebsd* | dragonfly*) + lt_cv_sys_dlopen_deplibs=yes + ;; + gnu* | linux* | k*bsd*-gnu | kopensolaris*-gnu) + # GNU and its variants, using gnu ld.so (Glibc) + lt_cv_sys_dlopen_deplibs=yes + ;; + hpux10*|hpux11*) + lt_cv_sys_dlopen_deplibs=yes + ;; + interix*) + lt_cv_sys_dlopen_deplibs=yes + ;; + irix[[12345]]*|irix6.[[01]]*) + # Catch all versions of IRIX before 6.2, and indicate that we don't + # know how it worked for any of those versions. + lt_cv_sys_dlopen_deplibs=unknown + ;; + irix*) + # The case above catches anything before 6.2, and it's known that + # at 6.2 and later dlopen does load deplibs. + lt_cv_sys_dlopen_deplibs=yes + ;; + netbsd*) + lt_cv_sys_dlopen_deplibs=yes + ;; + openbsd*) + lt_cv_sys_dlopen_deplibs=yes + ;; + osf[[1234]]*) + # dlopen did load deplibs (at least at 4.x), but until the 5.x series, + # it did *not* use an RPATH in a shared library to find objects the + # library depends on, so we explicitly say `no'. + lt_cv_sys_dlopen_deplibs=no + ;; + osf5.0|osf5.0a|osf5.1) + # dlopen *does* load deplibs and with the right loader patch applied + # it even uses RPATH in a shared library to search for shared objects + # that the library depends on, but there's no easy way to know if that + # patch is installed. Since this is the case, all we can really + # say is unknown -- it depends on the patch being installed. If + # it is, this changes to `yes'. Without it, it would be `no'. + lt_cv_sys_dlopen_deplibs=unknown + ;; + osf*) + # the two cases above should catch all versions of osf <= 5.1. Read + # the comments above for what we know about them. + # At > 5.1, deplibs are loaded *and* any RPATH in a shared library + # is used to find them so we can finally say `yes'. + lt_cv_sys_dlopen_deplibs=yes + ;; + qnx*) + lt_cv_sys_dlopen_deplibs=yes + ;; + solaris*) + lt_cv_sys_dlopen_deplibs=yes + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + esac + ]) +if test "$lt_cv_sys_dlopen_deplibs" != yes; then + AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1], + [Define if the OS needs help to load dependent libraries for dlopen().]) +fi +])# LT_SYS_DLOPEN_DEPLIBS + +# Old name: +AU_ALIAS([AC_LTDL_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], []) + + +# LT_SYS_MODULE_EXT +# ----------------- +AC_DEFUN([LT_SYS_MODULE_EXT], +[m4_require([_LT_SYS_DYNAMIC_LINKER])dnl +AC_CACHE_CHECK([which extension is used for runtime loadable modules], + [libltdl_cv_shlibext], +[ +module=yes +eval libltdl_cv_shlibext=$shrext_cmds +module=no +eval libltdl_cv_shrext=$shrext_cmds + ]) +if test -n "$libltdl_cv_shlibext"; then + m4_pattern_allow([LT_MODULE_EXT])dnl + AC_DEFINE_UNQUOTED([LT_MODULE_EXT], ["$libltdl_cv_shlibext"], + [Define to the extension used for runtime loadable modules, say, ".so".]) +fi +if test "$libltdl_cv_shrext" != "$libltdl_cv_shlibext"; then + m4_pattern_allow([LT_SHARED_EXT])dnl + AC_DEFINE_UNQUOTED([LT_SHARED_EXT], ["$libltdl_cv_shrext"], + [Define to the shared library suffix, say, ".dylib".]) +fi +])# LT_SYS_MODULE_EXT + +# Old name: +AU_ALIAS([AC_LTDL_SHLIBEXT], [LT_SYS_MODULE_EXT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_SHLIBEXT], []) + + +# LT_SYS_MODULE_PATH +# ------------------ +AC_DEFUN([LT_SYS_MODULE_PATH], +[m4_require([_LT_SYS_DYNAMIC_LINKER])dnl +AC_CACHE_CHECK([which variable specifies run-time module search path], + [lt_cv_module_path_var], [lt_cv_module_path_var="$shlibpath_var"]) +if test -n "$lt_cv_module_path_var"; then + m4_pattern_allow([LT_MODULE_PATH_VAR])dnl + AC_DEFINE_UNQUOTED([LT_MODULE_PATH_VAR], ["$lt_cv_module_path_var"], + [Define to the name of the environment variable that determines the run-time module search path.]) +fi +])# LT_SYS_MODULE_PATH + +# Old name: +AU_ALIAS([AC_LTDL_SHLIBPATH], [LT_SYS_MODULE_PATH]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_SHLIBPATH], []) + + +# LT_SYS_DLSEARCH_PATH +# -------------------- +AC_DEFUN([LT_SYS_DLSEARCH_PATH], +[m4_require([_LT_SYS_DYNAMIC_LINKER])dnl +AC_CACHE_CHECK([for the default library search path], + [lt_cv_sys_dlsearch_path], + [lt_cv_sys_dlsearch_path="$sys_lib_dlsearch_path_spec"]) +if test -n "$lt_cv_sys_dlsearch_path"; then + sys_dlsearch_path= + for dir in $lt_cv_sys_dlsearch_path; do + if test -z "$sys_dlsearch_path"; then + sys_dlsearch_path="$dir" + else + sys_dlsearch_path="$sys_dlsearch_path$PATH_SEPARATOR$dir" + fi + done + m4_pattern_allow([LT_DLSEARCH_PATH])dnl + AC_DEFINE_UNQUOTED([LT_DLSEARCH_PATH], ["$sys_dlsearch_path"], + [Define to the system default library search path.]) +fi +])# LT_SYS_DLSEARCH_PATH + +# Old name: +AU_ALIAS([AC_LTDL_SYSSEARCHPATH], [LT_SYS_DLSEARCH_PATH]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_SYSSEARCHPATH], []) + + +# _LT_CHECK_DLPREOPEN +# ------------------- +m4_defun([_LT_CHECK_DLPREOPEN], +[m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen], + [libltdl_cv_preloaded_symbols], + [if test -n "$lt_cv_sys_global_symbol_pipe"; then + libltdl_cv_preloaded_symbols=yes + else + libltdl_cv_preloaded_symbols=no + fi + ]) +if test x"$libltdl_cv_preloaded_symbols" = xyes; then + AC_DEFINE([HAVE_PRELOADED_SYMBOLS], [1], + [Define if libtool can extract symbol lists from object files.]) +fi +])# _LT_CHECK_DLPREOPEN + + +# LT_LIB_DLLOAD +# ------------- +AC_DEFUN([LT_LIB_DLLOAD], +[m4_pattern_allow([^LT_DLLOADERS$]) +LT_DLLOADERS= +AC_SUBST([LT_DLLOADERS]) + +AC_LANG_PUSH([C]) + +LIBADD_DLOPEN= +AC_SEARCH_LIBS([dlopen], [dl], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + if test "$ac_cv_search_dlopen" != "none required" ; then + LIBADD_DLOPEN="-ldl" + fi + libltdl_cv_lib_dl_dlopen="yes" + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#if HAVE_DLFCN_H +# include <dlfcn.h> +#endif + ]], [[dlopen(0, 0);]])], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + libltdl_cv_func_dlopen="yes" + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], + [AC_CHECK_LIB([svld], [dlopen], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + LIBADD_DLOPEN="-lsvld" libltdl_cv_func_dlopen="yes" + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"])])]) +if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes +then + lt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DLOPEN" + AC_CHECK_FUNCS([dlerror]) + LIBS="$lt_save_LIBS" +fi +AC_SUBST([LIBADD_DLOPEN]) + +LIBADD_SHL_LOAD= +AC_CHECK_FUNC([shl_load], + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function.]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la"], + [AC_CHECK_LIB([dld], [shl_load], + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function.]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" + LIBADD_SHL_LOAD="-ldld"])]) +AC_SUBST([LIBADD_SHL_LOAD]) + +case $host_os in +darwin[[1567]].*) +# We only want this for pre-Mac OS X 10.4. + AC_CHECK_FUNC([_dyld_func_lookup], + [AC_DEFINE([HAVE_DYLD], [1], + [Define if you have the _dyld_func_lookup function.]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la"]) + ;; +beos*) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la" + ;; +cygwin* | mingw* | os2* | pw32*) + AC_CHECK_DECLS([cygwin_conv_path], [], [], [[#include <sys/cygwin.h>]]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la" + ;; +esac + +AC_CHECK_LIB([dld], [dld_link], + [AC_DEFINE([HAVE_DLD], [1], + [Define if you have the GNU dld library.]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la"]) +AC_SUBST([LIBADD_DLD_LINK]) + +m4_pattern_allow([^LT_DLPREOPEN$]) +LT_DLPREOPEN= +if test -n "$LT_DLLOADERS" +then + for lt_loader in $LT_DLLOADERS; do + LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader " + done + AC_DEFINE([HAVE_LIBDLLOADER], [1], + [Define if libdlloader will be built on this platform]) +fi +AC_SUBST([LT_DLPREOPEN]) + +dnl This isn't used anymore, but set it for backwards compatibility +LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD" +AC_SUBST([LIBADD_DL]) + +AC_LANG_POP +])# LT_LIB_DLLOAD + +# Old name: +AU_ALIAS([AC_LTDL_DLLIB], [LT_LIB_DLLOAD]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_DLLIB], []) + + +# LT_SYS_SYMBOL_USCORE +# -------------------- +# does the compiler prefix global symbols with an underscore? +AC_DEFUN([LT_SYS_SYMBOL_USCORE], +[m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +AC_CACHE_CHECK([for _ prefix in compiled symbols], + [lt_cv_sys_symbol_underscore], + [lt_cv_sys_symbol_underscore=no + cat > conftest.$ac_ext <<_LT_EOF +void nm_test_func(){} +int main(){nm_test_func;return 0;} +_LT_EOF + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + ac_nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then + # See whether the symbols have a leading underscore. + if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then + lt_cv_sys_symbol_underscore=yes + else + if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then + : + else + echo "configure: cannot find nm_test_func in $ac_nlist" >&AS_MESSAGE_LOG_FD + fi + fi + else + echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.c >&AS_MESSAGE_LOG_FD + fi + rm -rf conftest* + ]) + sys_symbol_underscore=$lt_cv_sys_symbol_underscore + AC_SUBST([sys_symbol_underscore]) +])# LT_SYS_SYMBOL_USCORE + +# Old name: +AU_ALIAS([AC_LTDL_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_SYMBOL_USCORE], []) + + +# LT_FUNC_DLSYM_USCORE +# -------------------- +AC_DEFUN([LT_FUNC_DLSYM_USCORE], +[AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl +if test x"$lt_cv_sys_symbol_underscore" = xyes; then + if test x"$libltdl_cv_func_dlopen" = xyes || + test x"$libltdl_cv_lib_dl_dlopen" = xyes ; then + AC_CACHE_CHECK([whether we have to add an underscore for dlsym], + [libltdl_cv_need_uscore], + [libltdl_cv_need_uscore=unknown + save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DLOPEN" + _LT_TRY_DLOPEN_SELF( + [libltdl_cv_need_uscore=no], [libltdl_cv_need_uscore=yes], + [], [libltdl_cv_need_uscore=cross]) + LIBS="$save_LIBS" + ]) + fi +fi + +if test x"$libltdl_cv_need_uscore" = xyes; then + AC_DEFINE([NEED_USCORE], [1], + [Define if dlsym() requires a leading underscore in symbol names.]) +fi +])# LT_FUNC_DLSYM_USCORE + +# Old name: +AU_ALIAS([AC_LTDL_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], []) + +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) + +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) + +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 3337 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.2' +macro_revision='1.3337' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) + +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) + +# Copyright (C) 2002-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.12' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.12.4], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.12.4])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], +[$0: two- and three-arguments forms are deprecated. For more info, see: +http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_INIT_AUTOMAKE-invocation]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +dnl Support for Objective C++ was only introduced in Autoconf 2.65, +dnl but we still cater to Autoconf 2.62. +m4_ifdef([AC_PROG_OBJCXX], +[AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The 'parallel-tests' driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Copyright (C) 1998-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_LEX +# ----------- +# Autoconf leaves LEX=: if lex or flex can't be found. Change that to a +# "missing" invocation, for better error output. +AC_DEFUN([AM_PROG_LEX], +[AC_PREREQ([2.50])dnl +AC_REQUIRE([AM_MISSING_HAS_RUN])dnl +AC_REQUIRE([AC_PROG_LEX])dnl +if test "$LEX" = :; then + LEX=${am_missing_run}flex +fi]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless 'enable' is passed literally. +# For symmetry, 'disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], + [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], + am_maintainer_other[ make rules and dependencies not useful + (and sometimes confusing) to the casual installer])], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of '-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar <conftest.tar]) + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([acinclude.m4]) diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..137bedf --- /dev/null +++ b/config.guess @@ -0,0 +1,1537 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-08-14' + +# 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, see <http://www.gnu.org/licenses/>. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to <config-patches@gnu.org> and include a 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. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +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, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +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 ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # 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 + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + 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 ; set_cc_for_build= ;' + +# 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 tuples: *-*-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. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + 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 + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # 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 ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # 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. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + 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 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + 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 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + 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 ;; + 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 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /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 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # 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 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + 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 -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + 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 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????: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 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + 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 ;; + *: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 + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + 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 ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | 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 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 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 -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 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 -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + 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 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + 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 ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + 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 i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + 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 -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + 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 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + 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 ;; + 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 ;; + 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 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + 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 ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + 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 ;; + 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|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + 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 i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + 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 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*: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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + 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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *: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 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + 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 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *: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 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +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\n"); 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 -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# 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 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + 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 + + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +and + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +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: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..7950fac --- /dev/null +++ b/config.h.in @@ -0,0 +1,350 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Size of the auth heap. */ +#undef AUTH_HEAP_SIZE + +/* Size of the ban heap. */ +#undef BAN_HEAP_SIZE + +/* Size of the channel heap. */ +#undef CHANNEL_HEAP_SIZE + +/* Size of the client heap. */ +#undef CLIENT_HEAP_SIZE + +/* Set to datadir. */ +#undef DATADIR + +/* Size of the dbuf heap. */ +#undef DBUF_HEAP_SIZE + +/* Define to 1 to enable debugging. */ +#undef DEBUG + +/* Size of the dlink_node heap. */ +#undef DNODE_HEAP_SIZE + +/* Size of the dns heap. */ +#undef DNS_HEAP_SIZE + +/* Define to 1 if you want halfops support. */ +#undef HALFOPS + +/* Define to 1 if you have the `argz_add' function. */ +#undef HAVE_ARGZ_ADD + +/* Define to 1 if you have the `argz_append' function. */ +#undef HAVE_ARGZ_APPEND + +/* Define to 1 if you have the `argz_count' function. */ +#undef HAVE_ARGZ_COUNT + +/* Define to 1 if you have the `argz_create_sep' function. */ +#undef HAVE_ARGZ_CREATE_SEP + +/* Define to 1 if you have the <argz.h> header file. */ +#undef HAVE_ARGZ_H + +/* Define to 1 if you have the `argz_insert' function. */ +#undef HAVE_ARGZ_INSERT + +/* Define to 1 if you have the `argz_next' function. */ +#undef HAVE_ARGZ_NEXT + +/* Define to 1 if you have the `argz_stringify' function. */ +#undef HAVE_ARGZ_STRINGIFY + +/* Define to 1 if you have the `closedir' function. */ +#undef HAVE_CLOSEDIR + +/* Define to 1 if you have the <crypt.h> header file. */ +#undef HAVE_CRYPT_H + +/* Define to 1 if you have the declaration of `cygwin_conv_path', and to 0 if + you don't. */ +#undef HAVE_DECL_CYGWIN_CONV_PATH + +/* Define to 1 if you have the <devpoll.h> header file. */ +#undef HAVE_DEVPOLL_H + +/* Define to 1 if you have the <dirent.h> header file. */ +#undef HAVE_DIRENT_H + +/* Define if you have the GNU dld library. */ +#undef HAVE_DLD + +/* Define to 1 if you have the <dld.h> header file. */ +#undef HAVE_DLD_H + +/* Define to 1 if you have the `dlerror' function. */ +#undef HAVE_DLERROR + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the <dl.h> header file. */ +#undef HAVE_DL_H + +/* Define if you have the _dyld_func_lookup function. */ +#undef HAVE_DYLD + +/* Define to 1 if the system has the type `error_t'. */ +#undef HAVE_ERROR_T + +/* Define to 1 if you have the `inet_aton' function. */ +#undef HAVE_INET_ATON + +/* Define to 1 if you have the `inet_ntop' function. */ +#undef HAVE_INET_NTOP + +/* Define to 1 if you have the `inet_pton' function. */ +#undef HAVE_INET_PTON + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `crypto' library (-lcrypto). */ +#undef HAVE_LIBCRYPTO + +/* Define if you have the libdl library or equivalent. */ +#undef HAVE_LIBDL + +/* Define if libdlloader will be built on this platform */ +#undef HAVE_LIBDLLOADER + +/* Define to 1 if libpcre (-lpcre) is available. */ +#undef HAVE_LIBPCRE + +/* Define to 1 if you have the `ssl' library (-lssl). */ +#undef HAVE_LIBSSL + +/* Define this if a modern libltdl is already installed */ +#undef HAVE_LTDL + +/* Define to 1 if you have the <mach-o/dyld.h> header file. */ +#undef HAVE_MACH_O_DYLD_H + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mmap' function. */ +#undef HAVE_MMAP + +/* Define to 1 if you have the `opendir' function. */ +#undef HAVE_OPENDIR + +/* Define if libtool can extract symbol lists from object files. */ +#undef HAVE_PRELOADED_SYMBOLS + +/* Define to 1 if you have the `readdir' function. */ +#undef HAVE_READDIR + +/* Define if you have the shl_load function. */ +#undef HAVE_SHL_LOAD + +/* Define to 1 if you have the <socket.h> header file. */ +#undef HAVE_SOCKET_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strlcat' function. */ +#undef HAVE_STRLCAT + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define to 1 if you have the `strtok_r' function. */ +#undef HAVE_STRTOK_R + +/* Define to 1 if the system has the type `struct addrinfo'. */ +#undef HAVE_STRUCT_ADDRINFO + +/* Define to 1 if the system has the type `struct sockaddr_in'. */ +#undef HAVE_STRUCT_SOCKADDR_IN + +/* Define to 1 if `sin_len' is a member of `struct sockaddr_in'. */ +#undef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + +/* Define to 1 if the system has the type `struct sockaddr_storage'. */ +#undef HAVE_STRUCT_SOCKADDR_STORAGE + +/* Define to 1 if you have the <sys/devpoll.h> header file. */ +#undef HAVE_SYS_DEVPOLL_H + +/* Define to 1 if you have the <sys/dl.h> header file. */ +#undef HAVE_SYS_DL_H + +/* Define to 1 if you have the <sys/param.h> header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the <sys/resource.h> header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <sys/wait.h> header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the <types.h> header file. */ +#undef HAVE_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `usleep' function. */ +#undef HAVE_USLEEP + +/* Define to 1 if you have the <wait.h> header file. */ +#undef HAVE_WAIT_H + +/* This value is set to 1 to indicate that the system argz facility works */ +#undef HAVE_WORKING_ARGZ + +/* Define to 1 if you have IPv6 support. */ +#undef IPV6 + +/* Size of the local client heap. */ +#undef LCLIENT_HEAP_SIZE + +/* Set to libdir. */ +#undef LIBDIR + +/* Set to localstatedir. */ +#undef LOCALSTATEDIR + +/* Define if the OS needs help to load dependent libraries for dlopen(). */ +#undef LTDL_DLOPEN_DEPLIBS + +/* Define to the system default library search path. */ +#undef LT_DLSEARCH_PATH + +/* The archive extension */ +#undef LT_LIBEXT + +/* The archive prefix */ +#undef LT_LIBPREFIX + +/* Define to the extension used for runtime loadable modules, say, ".so". */ +#undef LT_MODULE_EXT + +/* Define to the name of the environment variable that determines the run-time + module search path. */ +#undef LT_MODULE_PATH_VAR + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Define to the shared library suffix, say, ".dylib". */ +#undef LT_SHARED_EXT + +/* Define to 1 to disable debugging. */ +#undef NDEBUG + +/* Define if dlsym() requires a leading underscore in symbol names. */ +#undef NEED_USCORE + +/* Length of nicknames. */ +#undef NICKLEN + +/* Size of the WHOWAS array. */ +#undef NICKNAMEHISTORYLENGTH + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Set to prefix. */ +#undef PREFIX + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Set to sysconfdir. */ +#undef SYSCONFDIR + +/* Length of topics. */ +#undef TOPICLEN + +/* use this iopoll mechanism */ +#undef USE_IOPOLL_MECHANISM + +/* Version number of package */ +#undef VERSION + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#undef YYTEXT_POINTER + +/* devpoll mechanism */ +#undef __IOPOLL_MECHANISM_DEVPOLL + +/* epoll mechanism */ +#undef __IOPOLL_MECHANISM_EPOLL + +/* kqueue mechanism */ +#undef __IOPOLL_MECHANISM_KQUEUE + +/* no iopoll mechanism */ +#undef __IOPOLL_MECHANISM_NONE + +/* poll mechanism */ +#undef __IOPOLL_MECHANISM_POLL + +/* rtsigio mechanism */ +#undef __IOPOLL_MECHANISM_RTSIGIO + +/* select mechanism */ +#undef __IOPOLL_MECHANISM_SELECT + +/* Define so that glibc/gnulib argp.h does not typedef error_t. */ +#undef __error_t_defined + +/* Define to a type to use for `error_t' if it is not otherwise available. */ +#undef error_t diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..bdda9e4 --- /dev/null +++ b/config.sub @@ -0,0 +1,1786 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-08-18' + +# 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, see <http://www.gnu.org/licenses/>. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted GNU 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. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# 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, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +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 ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # 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 ;; + + * ) + 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* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + 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 | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -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 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -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/'` + ;; + -sco5v6*) + # 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*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -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 \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # 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-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # 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 + ;; + abacus) + basic_machine=abacus-unknown + ;; + 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 + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + 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 + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + 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 | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + 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*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 + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + 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 + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + 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 + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-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-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + 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 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + 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 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + 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=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + 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 + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-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 + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + 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 + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + 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 + ;; + *-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. + -auroraux) + os=-auroraux + ;; + -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* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -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 + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -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 + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -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 + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + 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 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-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 + ;; + -cnk*|-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 + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + 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 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..cd93e12 --- /dev/null +++ b/configure @@ -0,0 +1,16897 @@ +#! /bin/sh +# From configure.ac Id: configure.ac 1523 2012-09-09 11:11:52Z michael . +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for ircd-hybrid 8.0.0. +# +# Report bugs to <bugs@ircd-hybrid.org>. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: bugs@ircd-hybrid.org about your system, including any +$0: error possibly output before this message. Then install +$0: a modern shell, or manually run the script under such a +$0: shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +lt_ltdl_dir='libltdl' + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='ircd-hybrid' +PACKAGE_TARNAME='ircd-hybrid' +PACKAGE_VERSION='8.0.0' +PACKAGE_STRING='ircd-hybrid 8.0.0' +PACKAGE_BUGREPORT='bugs@ircd-hybrid.org' +PACKAGE_URL='' + +ac_unique_file="src/ircd.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_func_list= +ac_header_list= +ac_subst_vars='ltdl_LTLIBOBJS +ltdl_LIBOBJS +am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +LOCALSTATEDIR +DATADIR +LIBDIR +SYSCONFDIR +PREFIX +ENABLE_SSL_FALSE +ENABLE_SSL_TRUE +LTDLOPEN +LT_CONFIG_H +CONVENIENCE_LTDL_FALSE +CONVENIENCE_LTDL_TRUE +INSTALL_LTDL_FALSE +INSTALL_LTDL_TRUE +ARGZ_H +sys_symbol_underscore +LIBADD_DL +LT_DLPREOPEN +LIBADD_DLD_LINK +LIBADD_SHL_LOAD +LIBADD_DLOPEN +LT_DLLOADERS +INCLTDL +LTDLINCL +LTDLDEPS +LIBLTDL +CPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +LEXLIB +LEX_OUTPUT_ROOT +LEX +YFLAGS +YACC +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_maintainer_mode +enable_dependency_tracking +enable_static +enable_shared +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +with_included_ltdl +with_ltdl_include +with_ltdl_lib +enable_ltdl_install +enable_libpcre +enable_openssl +enable_assert +enable_kqueue +enable_epoll +enable_devpoll +enable_rtsigio +enable_poll +enable_select +with_nicklen +with_topiclen +enable_halfops +enable_debugging +enable_warnings +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +YACC +YFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures ircd-hybrid 8.0.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/ircd-hybrid] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of ircd-hybrid 8.0.0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-static[=PKGS] build static libraries [default=no] + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-ltdl-install install libltdl + --disable-libpcre Disable PCRE support + --enable-openssl=DIR Enable OpenSSL support (DIR optional). + --disable-openssl Disable OpenSSL support. + --enable-assert Enable assert() statements + --enable-kqueue Force kqueue usage. + --enable-epoll Force epoll usage. + --enable-devpoll Force devpoll usage. + --enable-rtsigio Force rtsigio usage. + --enable-poll Force poll usage. + --enable-select Force select usage. + --enable-halfops Enable halfops support. + --enable-debugging Enable debugging. + --enable-warnings Enable compiler warnings. + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + --with-included-ltdl use the GNU ltdl sources included here + --with-ltdl-include=DIR use the ltdl headers installed in DIR + --with-ltdl-lib=DIR use the libltdl.la installed in DIR + --with-nicklen=<value> Set nickname length (default 9). + --with-topiclen=<value> Set topic length (default 160). + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + YACC The `Yet Another Compiler Compiler' implementation to use. + Defaults to the first program found out of: `bison -y', `byacc', + `yacc'. + YFLAGS The list of arguments that will be passed by default to $YACC. + This script will default YFLAGS to the empty string to avoid a + default value of `-d' given by some make applications. + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to <bugs@ircd-hybrid.org>. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +ircd-hybrid configure 8.0.0 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +$as_echo_n "checking for $2.$3... " >&6; } +if eval \${$4+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_member + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ----------------------------------- ## +## Report this to bugs@ircd-hybrid.org ## +## ----------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by ircd-hybrid $as_me 8.0.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +as_fn_append ac_func_list " mmap" +as_fn_append ac_func_list " strtok_r" +as_fn_append ac_func_list " usleep" +as_fn_append ac_func_list " strlcat" +as_fn_append ac_func_list " strlcpy" +as_fn_append ac_header_list " crypt.h" +as_fn_append ac_header_list " sys/resource.h" +as_fn_append ac_header_list " sys/param.h" +as_fn_append ac_header_list " types.h" +as_fn_append ac_header_list " socket.h" +as_fn_append ac_header_list " sys/wait.h" +as_fn_append ac_header_list " wait.h" +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +am__api_version='1.12' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='ircd-hybrid' + VERSION='8.0.0' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + +ac_config_headers="$ac_config_headers config.h" + + + +# Checks for programs. +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 +$as_echo_n "checking for $CC option to accept ISO C99... " >&6; } +if ${ac_cv_prog_cc_c99+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdbool.h> +#include <stdlib.h> +#include <wchar.h> +#include <stdio.h> + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +#define debug(...) fprintf (stderr, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + your preprocessor is broken; +#endif +#if BIG_OK +#else + your preprocessor is broken; +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\0'; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static void +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str; + int number; + float fnumber; + + while (*format) + { + switch (*format++) + { + case 's': // string + str = va_arg (args_copy, const char *); + break; + case 'd': // int + number = va_arg (args_copy, int); + break; + case 'f': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); +} + +int +main () +{ + + // Check bool. + _Bool success = false; + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + test_varargs ("s, d' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' + || dynamic_array[ni.number - 1] != 543); + + ; + return 0; +} +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c99" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c99" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +$as_echo "$ac_cv_prog_cc_c99" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c99" != xno; then : + +fi + + +if test "$ac_cv_prog_cc_c99" = "no"; then : + as_fn_error $? "no suitable C99 compiler found. Aborting." "$LINENO" 5 +fi +for ac_prog in 'bison -y' byacc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_YACC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$YACC"; then + ac_cv_prog_YACC="$YACC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_YACC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +YACC=$ac_cv_prog_YACC +if test -n "$YACC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 +$as_echo "$YACC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$YACC" && break +done +test -n "$YACC" || YACC="yacc" + + +for ac_prog in flex lex +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LEX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LEX"; then + ac_cv_prog_LEX="$LEX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LEX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LEX=$ac_cv_prog_LEX +if test -n "$LEX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 +$as_echo "$LEX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$LEX" && break +done +test -n "$LEX" || LEX=":" + +if test "x$LEX" != "x:"; then + cat >conftest.l <<_ACEOF +%% +a { ECHO; } +b { REJECT; } +c { yymore (); } +d { yyless (1); } +e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */ + yyless ((input () != 0)); } +f { unput (yytext[0]); } +. { BEGIN INITIAL; } +%% +#ifdef YYTEXT_POINTER +extern char *yytext; +#endif +int +main (void) +{ + return ! yylex () + ! yywrap (); +} +_ACEOF +{ { ac_try="$LEX conftest.l" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$LEX conftest.l") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5 +$as_echo_n "checking lex output file root... " >&6; } +if ${ac_cv_prog_lex_root+:} false; then : + $as_echo_n "(cached) " >&6 +else + +if test -f lex.yy.c; then + ac_cv_prog_lex_root=lex.yy +elif test -f lexyy.c; then + ac_cv_prog_lex_root=lexyy +else + as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5 +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5 +$as_echo "$ac_cv_prog_lex_root" >&6; } +LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root + +if test -z "${LEXLIB+set}"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5 +$as_echo_n "checking lex library... " >&6; } +if ${ac_cv_lib_lex+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_LIBS=$LIBS + ac_cv_lib_lex='none needed' + for ac_lib in '' -lfl -ll; do + LIBS="$ac_lib $ac_save_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +`cat $LEX_OUTPUT_ROOT.c` +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_lex=$ac_lib +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + test "$ac_cv_lib_lex" != 'none needed' && break + done + LIBS=$ac_save_LIBS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5 +$as_echo "$ac_cv_lib_lex" >&6; } + test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5 +$as_echo_n "checking whether yytext is a pointer... " >&6; } +if ${ac_cv_prog_lex_yytext_pointer+:} false; then : + $as_echo_n "(cached) " >&6 +else + # POSIX says lex can declare yytext either as a pointer or an array; the +# default is implementation-dependent. Figure out which it is, since +# not all implementations provide the %pointer and %array declarations. +ac_cv_prog_lex_yytext_pointer=no +ac_save_LIBS=$LIBS +LIBS="$LEXLIB $ac_save_LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #define YYTEXT_POINTER 1 +`cat $LEX_OUTPUT_ROOT.c` +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_prog_lex_yytext_pointer=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_save_LIBS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5 +$as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } +if test $ac_cv_prog_lex_yytext_pointer = yes; then + +$as_echo "#define YYTEXT_POINTER 1" >>confdefs.h + +fi +rm -f conftest.l $LEX_OUTPUT_ROOT.c + +fi +if test "$LEX" = :; then + LEX=${am_missing_run}flex +fi + + +# Initializing libtool. + + + + + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.2' +macro_revision='1.3337' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$lt_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$lt_cv_path_LD" +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + + +# Set options +enable_dlopen=yes +# Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=no +fi + + + + + + + + + + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which extension is used for runtime loadable modules" >&5 +$as_echo_n "checking which extension is used for runtime loadable modules... " >&6; } +if ${libltdl_cv_shlibext+:} false; then : + $as_echo_n "(cached) " >&6 +else + +module=yes +eval libltdl_cv_shlibext=$shrext_cmds +module=no +eval libltdl_cv_shrext=$shrext_cmds + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libltdl_cv_shlibext" >&5 +$as_echo "$libltdl_cv_shlibext" >&6; } +if test -n "$libltdl_cv_shlibext"; then + +cat >>confdefs.h <<_ACEOF +#define LT_MODULE_EXT "$libltdl_cv_shlibext" +_ACEOF + +fi +if test "$libltdl_cv_shrext" != "$libltdl_cv_shlibext"; then + +cat >>confdefs.h <<_ACEOF +#define LT_SHARED_EXT "$libltdl_cv_shrext" +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which variable specifies run-time module search path" >&5 +$as_echo_n "checking which variable specifies run-time module search path... " >&6; } +if ${lt_cv_module_path_var+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_module_path_var="$shlibpath_var" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_module_path_var" >&5 +$as_echo "$lt_cv_module_path_var" >&6; } +if test -n "$lt_cv_module_path_var"; then + +cat >>confdefs.h <<_ACEOF +#define LT_MODULE_PATH_VAR "$lt_cv_module_path_var" +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the default library search path" >&5 +$as_echo_n "checking for the default library search path... " >&6; } +if ${lt_cv_sys_dlsearch_path+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sys_dlsearch_path="$sys_lib_dlsearch_path_spec" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_dlsearch_path" >&5 +$as_echo "$lt_cv_sys_dlsearch_path" >&6; } +if test -n "$lt_cv_sys_dlsearch_path"; then + sys_dlsearch_path= + for dir in $lt_cv_sys_dlsearch_path; do + if test -z "$sys_dlsearch_path"; then + sys_dlsearch_path="$dir" + else + sys_dlsearch_path="$sys_dlsearch_path$PATH_SEPARATOR$dir" + fi + done + +cat >>confdefs.h <<_ACEOF +#define LT_DLSEARCH_PATH "$sys_dlsearch_path" +_ACEOF + +fi + + +LT_DLLOADERS= + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +LIBADD_DLOPEN= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 +$as_echo_n "checking for library containing dlopen... " >&6; } +if ${ac_cv_search_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_dlopen=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_dlopen+:} false; then : + break +fi +done +if ${ac_cv_search_dlopen+:} false; then : + +else + ac_cv_search_dlopen=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 +$as_echo "$ac_cv_search_dlopen" >&6; } +ac_res=$ac_cv_search_dlopen +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_LIBDL 1" >>confdefs.h + + if test "$ac_cv_search_dlopen" != "none required" ; then + LIBADD_DLOPEN="-ldl" + fi + libltdl_cv_lib_dl_dlopen="yes" + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if HAVE_DLFCN_H +# include <dlfcn.h> +#endif + +int +main () +{ +dlopen(0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +$as_echo "#define HAVE_LIBDL 1" >>confdefs.h + + libltdl_cv_func_dlopen="yes" + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + +$as_echo "#define HAVE_LIBDL 1" >>confdefs.h + + LIBADD_DLOPEN="-lsvld" libltdl_cv_func_dlopen="yes" + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la" +fi + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes +then + lt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DLOPEN" + for ac_func in dlerror +do : + ac_fn_c_check_func "$LINENO" "dlerror" "ac_cv_func_dlerror" +if test "x$ac_cv_func_dlerror" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLERROR 1 +_ACEOF + +fi +done + + LIBS="$lt_save_LIBS" +fi + + +LIBADD_SHL_LOAD= +ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + +$as_echo "#define HAVE_SHL_LOAD 1" >>confdefs.h + + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + +$as_echo "#define HAVE_SHL_LOAD 1" >>confdefs.h + + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" + LIBADD_SHL_LOAD="-ldld" +fi + +fi + + + +case $host_os in +darwin[1567].*) +# We only want this for pre-Mac OS X 10.4. + ac_fn_c_check_func "$LINENO" "_dyld_func_lookup" "ac_cv_func__dyld_func_lookup" +if test "x$ac_cv_func__dyld_func_lookup" = xyes; then : + +$as_echo "#define HAVE_DYLD 1" >>confdefs.h + + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la" +fi + + ;; +beos*) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la" + ;; +cygwin* | mingw* | os2* | pw32*) + ac_fn_c_check_decl "$LINENO" "cygwin_conv_path" "ac_cv_have_decl_cygwin_conv_path" "#include <sys/cygwin.h> +" +if test "x$ac_cv_have_decl_cygwin_conv_path" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_CYGWIN_CONV_PATH $ac_have_decl +_ACEOF + + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + +$as_echo "#define HAVE_DLD 1" >>confdefs.h + + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la" +fi + + + + +LT_DLPREOPEN= +if test -n "$LT_DLLOADERS" +then + for lt_loader in $LT_DLLOADERS; do + LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader " + done + +$as_echo "#define HAVE_LIBDLLOADER 1" >>confdefs.h + +fi + + +LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD" + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5 +$as_echo_n "checking for _ prefix in compiled symbols... " >&6; } +if ${lt_cv_sys_symbol_underscore+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sys_symbol_underscore=no + cat > conftest.$ac_ext <<_LT_EOF +void nm_test_func(){} +int main(){nm_test_func;return 0;} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + ac_nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$ac_nlist"; then + # See whether the symbols have a leading underscore. + if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then + lt_cv_sys_symbol_underscore=yes + else + if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then + : + else + echo "configure: cannot find nm_test_func in $ac_nlist" >&5 + fi + fi + else + echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "configure: failed program was:" >&5 + cat conftest.c >&5 + fi + rm -rf conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_symbol_underscore" >&5 +$as_echo "$lt_cv_sys_symbol_underscore" >&6; } + sys_symbol_underscore=$lt_cv_sys_symbol_underscore + + +if test x"$lt_cv_sys_symbol_underscore" = xyes; then + if test x"$libltdl_cv_func_dlopen" = xyes || + test x"$libltdl_cv_lib_dl_dlopen" = xyes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we have to add an underscore for dlsym" >&5 +$as_echo_n "checking whether we have to add an underscore for dlsym... " >&6; } +if ${libltdl_cv_need_uscore+:} false; then : + $as_echo_n "(cached) " >&6 +else + libltdl_cv_need_uscore=unknown + save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DLOPEN" + if test "$cross_compiling" = yes; then : + libltdl_cv_need_uscore=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) libltdl_cv_need_uscore=no ;; + x$lt_dlneed_uscore) libltdl_cv_need_uscore=yes ;; + x$lt_dlunknown|x*) ;; + esac + else : + # compilation failed + + fi +fi +rm -fr conftest* + + LIBS="$save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libltdl_cv_need_uscore" >&5 +$as_echo "$libltdl_cv_need_uscore" >&6; } + fi +fi + +if test x"$libltdl_cv_need_uscore" = xyes; then + +$as_echo "#define NEED_USCORE 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether deplibs are loaded by dlopen" >&5 +$as_echo_n "checking whether deplibs are loaded by dlopen... " >&6; } +if ${lt_cv_sys_dlopen_deplibs+:} false; then : + $as_echo_n "(cached) " >&6 +else + # PORTME does your system automatically load deplibs for dlopen? + # or its logical equivalent (e.g. shl_load for HP-UX < 11) + # For now, we just catch OSes we know something about -- in the + # future, we'll try test this programmatically. + lt_cv_sys_dlopen_deplibs=unknown + case $host_os in + aix3*|aix4.1.*|aix4.2.*) + # Unknown whether this is true for these versions of AIX, but + # we want this `case' here to explicitly catch those versions. + lt_cv_sys_dlopen_deplibs=unknown + ;; + aix[4-9]*) + lt_cv_sys_dlopen_deplibs=yes + ;; + amigaos*) + case $host_cpu in + powerpc) + lt_cv_sys_dlopen_deplibs=no + ;; + esac + ;; + darwin*) + # Assuming the user has installed a libdl from somewhere, this is true + # If you are looking for one http://www.opendarwin.org/projects/dlcompat + lt_cv_sys_dlopen_deplibs=yes + ;; + freebsd* | dragonfly*) + lt_cv_sys_dlopen_deplibs=yes + ;; + gnu* | linux* | k*bsd*-gnu | kopensolaris*-gnu) + # GNU and its variants, using gnu ld.so (Glibc) + lt_cv_sys_dlopen_deplibs=yes + ;; + hpux10*|hpux11*) + lt_cv_sys_dlopen_deplibs=yes + ;; + interix*) + lt_cv_sys_dlopen_deplibs=yes + ;; + irix[12345]*|irix6.[01]*) + # Catch all versions of IRIX before 6.2, and indicate that we don't + # know how it worked for any of those versions. + lt_cv_sys_dlopen_deplibs=unknown + ;; + irix*) + # The case above catches anything before 6.2, and it's known that + # at 6.2 and later dlopen does load deplibs. + lt_cv_sys_dlopen_deplibs=yes + ;; + netbsd*) + lt_cv_sys_dlopen_deplibs=yes + ;; + openbsd*) + lt_cv_sys_dlopen_deplibs=yes + ;; + osf[1234]*) + # dlopen did load deplibs (at least at 4.x), but until the 5.x series, + # it did *not* use an RPATH in a shared library to find objects the + # library depends on, so we explicitly say `no'. + lt_cv_sys_dlopen_deplibs=no + ;; + osf5.0|osf5.0a|osf5.1) + # dlopen *does* load deplibs and with the right loader patch applied + # it even uses RPATH in a shared library to search for shared objects + # that the library depends on, but there's no easy way to know if that + # patch is installed. Since this is the case, all we can really + # say is unknown -- it depends on the patch being installed. If + # it is, this changes to `yes'. Without it, it would be `no'. + lt_cv_sys_dlopen_deplibs=unknown + ;; + osf*) + # the two cases above should catch all versions of osf <= 5.1. Read + # the comments above for what we know about them. + # At > 5.1, deplibs are loaded *and* any RPATH in a shared library + # is used to find them so we can finally say `yes'. + lt_cv_sys_dlopen_deplibs=yes + ;; + qnx*) + lt_cv_sys_dlopen_deplibs=yes + ;; + solaris*) + lt_cv_sys_dlopen_deplibs=yes + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_dlopen_deplibs" >&5 +$as_echo "$lt_cv_sys_dlopen_deplibs" >&6; } +if test "$lt_cv_sys_dlopen_deplibs" != yes; then + +$as_echo "#define LTDL_DLOPEN_DEPLIBS 1" >>confdefs.h + +fi + +: + +for ac_header in argz.h +do : + ac_fn_c_check_header_compile "$LINENO" "argz.h" "ac_cv_header_argz_h" "$ac_includes_default +" +if test "x$ac_cv_header_argz_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ARGZ_H 1 +_ACEOF + +fi + +done + + +ac_fn_c_check_type "$LINENO" "error_t" "ac_cv_type_error_t" "#if defined(HAVE_ARGZ_H) +# include <argz.h> +#endif +" +if test "x$ac_cv_type_error_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_ERROR_T 1 +_ACEOF + + +else + +$as_echo "#define error_t int" >>confdefs.h + + +$as_echo "#define __error_t_defined 1" >>confdefs.h + +fi + + +ARGZ_H= +for ac_func in argz_add argz_append argz_count argz_create_sep argz_insert \ + argz_next argz_stringify +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + ARGZ_H=argz.h; + + _LT_LIBOBJS="$_LT_LIBOBJS argz.$ac_objext" + +fi +done + + +if test -z "$ARGZ_H"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if argz actually works" >&5 +$as_echo_n "checking if argz actually works... " >&6; } +if ${lt_cv_sys_argz_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host_os in #( + *cygwin*) + lt_cv_sys_argz_works=no + if test "$cross_compiling" != no; then + lt_cv_sys_argz_works="guessing no" + else + lt_sed_extract_leading_digits='s/^\([0-9\.]*\).*/\1/' + save_IFS=$IFS + IFS=-. + set x `uname -r | sed -e "$lt_sed_extract_leading_digits"` + IFS=$save_IFS + lt_os_major=${2-0} + lt_os_minor=${3-0} + lt_os_micro=${4-0} + if test "$lt_os_major" -gt 1 \ + || { test "$lt_os_major" -eq 1 \ + && { test "$lt_os_minor" -gt 5 \ + || { test "$lt_os_minor" -eq 5 \ + && test "$lt_os_micro" -gt 24; }; }; }; then + lt_cv_sys_argz_works=yes + fi + fi + ;; #( + *) lt_cv_sys_argz_works=yes ;; + esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_argz_works" >&5 +$as_echo "$lt_cv_sys_argz_works" >&6; } + if test "$lt_cv_sys_argz_works" = yes; then : + +$as_echo "#define HAVE_WORKING_ARGZ 1" >>confdefs.h + +else + ARGZ_H=argz.h + + + _LT_LIBOBJS="$_LT_LIBOBJS argz.$ac_objext" + +fi +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libtool supports -dlopen/-dlpreopen" >&5 +$as_echo_n "checking whether libtool supports -dlopen/-dlpreopen... " >&6; } +if ${libltdl_cv_preloaded_symbols+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$lt_cv_sys_global_symbol_pipe"; then + libltdl_cv_preloaded_symbols=yes + else + libltdl_cv_preloaded_symbols=no + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libltdl_cv_preloaded_symbols" >&5 +$as_echo "$libltdl_cv_preloaded_symbols" >&6; } +if test x"$libltdl_cv_preloaded_symbols" = xyes; then + +$as_echo "#define HAVE_PRELOADED_SYMBOLS 1" >>confdefs.h + +fi + +# Set options + + + + + + + + + + + +# Check whether --with-included_ltdl was given. +if test "${with_included_ltdl+set}" = set; then : + withval=$with_included_ltdl; +fi + + +if test "x$with_included_ltdl" != xyes; then + # We are not being forced to use the included libltdl sources, so + # decide whether there is a useful installed version we can use. + ac_fn_c_check_header_compile "$LINENO" "ltdl.h" "ac_cv_header_ltdl_h" "$ac_includes_default + +" +if test "x$ac_cv_header_ltdl_h" = xyes; then : + ac_fn_c_check_decl "$LINENO" "lt_dlinterface_register" "ac_cv_have_decl_lt_dlinterface_register" "$ac_includes_default + #include <ltdl.h> +" +if test "x$ac_cv_have_decl_lt_dlinterface_register" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lt_dladvise_preload in -lltdl" >&5 +$as_echo_n "checking for lt_dladvise_preload in -lltdl... " >&6; } +if ${ac_cv_lib_ltdl_lt_dladvise_preload+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lltdl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char lt_dladvise_preload (); +int +main () +{ +return lt_dladvise_preload (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ltdl_lt_dladvise_preload=yes +else + ac_cv_lib_ltdl_lt_dladvise_preload=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ltdl_lt_dladvise_preload" >&5 +$as_echo "$ac_cv_lib_ltdl_lt_dladvise_preload" >&6; } +if test "x$ac_cv_lib_ltdl_lt_dladvise_preload" = xyes; then : + with_included_ltdl=no +else + with_included_ltdl=yes +fi + +else + with_included_ltdl=yes +fi + +else + with_included_ltdl=yes +fi + + +fi + + + + +# Check whether --with-ltdl_include was given. +if test "${with_ltdl_include+set}" = set; then : + withval=$with_ltdl_include; +fi + + +if test -n "$with_ltdl_include"; then + if test -f "$with_ltdl_include/ltdl.h"; then : + else + as_fn_error $? "invalid ltdl include directory: \`$with_ltdl_include'" "$LINENO" 5 + fi +else + with_ltdl_include=no +fi + + +# Check whether --with-ltdl_lib was given. +if test "${with_ltdl_lib+set}" = set; then : + withval=$with_ltdl_lib; +fi + + +if test -n "$with_ltdl_lib"; then + if test -f "$with_ltdl_lib/libltdl.la"; then : + else + as_fn_error $? "invalid ltdl library directory: \`$with_ltdl_lib'" "$LINENO" 5 + fi +else + with_ltdl_lib=no +fi + +case ,$with_included_ltdl,$with_ltdl_include,$with_ltdl_lib, in + ,yes,no,no,) + case $enable_ltdl_convenience in + no) as_fn_error $? "this package needs a convenience libltdl" "$LINENO" 5 ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; +esac +LIBLTDL='${top_build_prefix}'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdlc.la" +LTDLDEPS=$LIBLTDL +LTDLINCL='-I${top_srcdir}'"${lt_ltdl_dir+/$lt_ltdl_dir}" + + + + + +# For backwards non-gettext consistent compatibility... +INCLTDL="$LTDLINCL" + + + ;; + ,no,no,no,) + # If the included ltdl is not to be used, then use the + # preinstalled libltdl we found. + +$as_echo "#define HAVE_LTDL 1" >>confdefs.h + + LIBLTDL=-lltdl + LTDLDEPS= + LTDLINCL= + ;; + ,no*,no,*) + as_fn_error $? "\`--with-ltdl-include' and \`--with-ltdl-lib' options must be used together" "$LINENO" 5 + ;; + *) with_included_ltdl=no + LIBLTDL="-L$with_ltdl_lib -lltdl" + LTDLDEPS= + LTDLINCL="-I$with_ltdl_include" + ;; +esac +INCLTDL="$LTDLINCL" + +# Report our decision... +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find libltdl headers" >&5 +$as_echo_n "checking where to find libltdl headers... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LTDLINCL" >&5 +$as_echo "$LTDLINCL" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find libltdl library" >&5 +$as_echo_n "checking where to find libltdl library... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBLTDL" >&5 +$as_echo "$LIBLTDL" >&6; } + + + +# Check whether --enable-ltdl-install was given. +if test "${enable_ltdl_install+set}" = set; then : + enableval=$enable_ltdl_install; +fi + + +case ,${enable_ltdl_install},${enable_ltdl_convenience} in + *yes*) ;; + *) enable_ltdl_convenience=yes ;; +esac + + if test x"${enable_ltdl_install-no}" != xno; then + INSTALL_LTDL_TRUE= + INSTALL_LTDL_FALSE='#' +else + INSTALL_LTDL_TRUE='#' + INSTALL_LTDL_FALSE= +fi + + if test x"${enable_ltdl_convenience-no}" != xno; then + CONVENIENCE_LTDL_TRUE= + CONVENIENCE_LTDL_FALSE='#' +else + CONVENIENCE_LTDL_TRUE='#' + CONVENIENCE_LTDL_FALSE= +fi + + + + + + +# In order that ltdl.c can compile, find out the first AC_CONFIG_HEADERS +# the user used. This is so that ltdl.h can pick up the parent projects +# config.h file, The first file in AC_CONFIG_HEADERS must contain the +# definitions required by ltdl.c. +# FIXME: Remove use of undocumented AC_LIST_HEADERS (2.59 compatibility). + + + +for ac_header in unistd.h dl.h sys/dl.h dld.h mach-o/dyld.h dirent.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_func in closedir opendir readdir +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + + + _LT_LIBOBJS="$_LT_LIBOBJS lt__dirent.$ac_objext" + +fi +done + +for ac_func in strlcat strlcpy +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + + + _LT_LIBOBJS="$_LT_LIBOBJS lt__strl.$ac_objext" + +fi +done + + + +cat >>confdefs.h <<_ACEOF +#define LT_LIBEXT "$libext" +_ACEOF + + +name= +eval "lt_libprefix=\"$libname_spec\"" + +cat >>confdefs.h <<_ACEOF +#define LT_LIBPREFIX "$lt_libprefix" +_ACEOF + + +name=ltdl +eval "LTDLOPEN=\"$libname_spec\"" + + + + + + + + +# Only expand once: + + +LIBTOOL="$LIBTOOL --silent" + +# Checks for libraries. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 +$as_echo_n "checking for library containing socket... " >&6; } +if ${ac_cv_search_socket+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +for ac_lib in '' socket; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_socket=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_socket+:} false; then : + break +fi +done +if ${ac_cv_search_socket+:} false; then : + +else + ac_cv_search_socket=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5 +$as_echo "$ac_cv_search_socket" >&6; } +ac_res=$ac_cv_search_socket +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + as_fn_error $? "socket library not found" "$LINENO" 5 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing inet_ntoa" >&5 +$as_echo_n "checking for library containing inet_ntoa... " >&6; } +if ${ac_cv_search_inet_ntoa+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char inet_ntoa (); +int +main () +{ +return inet_ntoa (); + ; + return 0; +} +_ACEOF +for ac_lib in '' nsl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_inet_ntoa=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_inet_ntoa+:} false; then : + break +fi +done +if ${ac_cv_search_inet_ntoa+:} false; then : + +else + ac_cv_search_inet_ntoa=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_inet_ntoa" >&5 +$as_echo "$ac_cv_search_inet_ntoa" >&6; } +ac_res=$ac_cv_search_inet_ntoa +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing inet_aton" >&5 +$as_echo_n "checking for library containing inet_aton... " >&6; } +if ${ac_cv_search_inet_aton+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char inet_aton (); +int +main () +{ +return inet_aton (); + ; + return 0; +} +_ACEOF +for ac_lib in '' resolv; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_inet_aton=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_inet_aton+:} false; then : + break +fi +done +if ${ac_cv_search_inet_aton+:} false; then : + +else + ac_cv_search_inet_aton=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_inet_aton" >&5 +$as_echo "$ac_cv_search_inet_aton" >&6; } +ac_res=$ac_cv_search_inet_aton +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + for ac_func in inet_aton inet_ntop inet_pton +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + ac_fn_c_check_type "$LINENO" "struct sockaddr_in" "ac_cv_type_struct_sockaddr_in" "#include <sys/types.h> + #include <sys/socket.h> + #include <netdb.h> + +" +if test "x$ac_cv_type_struct_sockaddr_in" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_IN 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "struct sockaddr_storage" "ac_cv_type_struct_sockaddr_storage" "#include <sys/types.h> + #include <sys/socket.h> + #include <netdb.h> + +" +if test "x$ac_cv_type_struct_sockaddr_storage" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" "#include <sys/types.h> + #include <sys/socket.h> + #include <netdb.h> + +" +if test "x$ac_cv_type_struct_addrinfo" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_ADDRINFO 1 +_ACEOF + + +fi + + ac_fn_c_check_member "$LINENO" "struct sockaddr_in" "sin_len" "ac_cv_member_struct_sockaddr_in_sin_len" "#include <sys/types.h> + <sys/socket.h> +" +if test "x$ac_cv_member_struct_sockaddr_in_sin_len" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 1 +_ACEOF + + +fi + + + + ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "#include <netinet/in.h> +" +if test "x$ac_cv_type_struct_sockaddr_in6" = xyes; then : + +$as_echo "#define IPV6 1" >>confdefs.h + +fi + + + +# Checks for typedefs, structures, and compiler characteristics. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + #include <sys/param.h> + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + #include <sys/param.h> + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + +# Checks for library functions. + + + + for ac_func in $ac_func_list +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + + + + + + + + + + +# Checks for header files. + + + + for ac_header in $ac_header_list +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt" >&5 +$as_echo_n "checking for library containing crypt... " >&6; } +if ${ac_cv_search_crypt+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char crypt (); +int +main () +{ +return crypt (); + ; + return 0; +} +_ACEOF +for ac_lib in '' crypt; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_crypt=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_crypt+:} false; then : + break +fi +done +if ${ac_cv_search_crypt+:} false; then : + +else + ac_cv_search_crypt=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt" >&5 +$as_echo "$ac_cv_search_crypt" >&6; } +ac_res=$ac_cv_search_crypt +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +# Check whether --enable-libpcre was given. +if test "${enable_libpcre+set}" = set; then : + enableval=$enable_libpcre; +else + ac_fn_c_check_header_mongrel "$LINENO" "pcre.h" "ac_cv_header_pcre_h" "$ac_includes_default" +if test "x$ac_cv_header_pcre_h" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pcre_study" >&5 +$as_echo_n "checking for library containing pcre_study... " >&6; } +if ${ac_cv_search_pcre_study+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pcre_study (); +int +main () +{ +return pcre_study (); + ; + return 0; +} +_ACEOF +for ac_lib in '' pcre; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_pcre_study=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_pcre_study+:} false; then : + break +fi +done +if ${ac_cv_search_pcre_study+:} false; then : + +else + ac_cv_search_pcre_study=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pcre_study" >&5 +$as_echo "$ac_cv_search_pcre_study" >&6; } +ac_res=$ac_cv_search_pcre_study +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_LIBPCRE 1" >>confdefs.h + +fi + +fi + + +fi + + +# Check whether --enable-openssl was given. +if test "${enable_openssl+set}" = set; then : + enableval=$enable_openssl; cf_enable_openssl=$enableval +else + cf_enable_openssl="auto" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL" >&5 +$as_echo_n "checking for OpenSSL... " >&6; } +if test "$cf_enable_openssl" != "no"; then + cf_openssl_basedir="" + if test "$cf_enable_openssl" != "auto" && + test "$cf_enable_openssl" != "yes"; then + cf_openssl_basedir="${cf_enable_openssl}" + else + for dirs in /usr/local/ssl /usr/pkg /usr/local /usr/lib /usr/lib/ssl\ + /opt /opt/openssl /usr/local/openssl; do + if test -f "${dirs}/include/openssl/opensslv.h"; then + cf_openssl_basedir="${dirs}" + break + fi + done + unset dirs + fi + + if test ! -z "$cf_openssl_basedir"; then + if test -f "${cf_openssl_basedir}/include/openssl/opensslv.h"; then + CPPFLAGS="-I${cf_openssl_basedir}/include $CPPFLAGS" + LDFLAGS="-L${cf_openssl_basedir}/lib $LDFLAGS" + else + cf_openssl_basedir="" + fi + else + if test -f "/usr/include/openssl/opensslv.h"; then + cf_openssl_basedir="/usr" + fi + fi + + if test ! -z "$cf_openssl_basedir"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cf_openssl_basedir" >&5 +$as_echo "$cf_openssl_basedir" >&6; } + cf_enable_openssl="yes" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found. Please check your path." >&5 +$as_echo "not found. Please check your path." >&6; } + cf_enable_openssl="no" + fi + unset cf_openssl_basedir +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 +$as_echo "disabled" >&6; } +fi + +if test "$cf_enable_openssl" != "no"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL 0.9.8 or above" >&5 +$as_echo_n "checking for OpenSSL 0.9.8 or above... " >&6; } + if test "$cross_compiling" = yes; then : + cf_openssl_version_ok=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include <openssl/opensslv.h> + #include <stdlib.h> +int +main () +{ + exit(!(OPENSSL_VERSION_NUMBER >= 0x00908000)); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + cf_openssl_version_ok=yes +else + cf_openssl_version_ok=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + + if test "$cf_openssl_version_ok" = "yes"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 +$as_echo "found" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for RSA_free in -lcrypto" >&5 +$as_echo_n "checking for RSA_free in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_RSA_free+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char RSA_free (); +int +main () +{ +return RSA_free (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_RSA_free=yes +else + ac_cv_lib_crypto_RSA_free=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_RSA_free" >&5 +$as_echo "$ac_cv_lib_crypto_RSA_free" >&6; } +if test "x$ac_cv_lib_crypto_RSA_free" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBCRYPTO 1 +_ACEOF + + LIBS="-lcrypto $LIBS" + +fi + + if test "$ac_cv_lib_crypto_RSA_free" = "yes"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_connect in -lssl" >&5 +$as_echo_n "checking for SSL_connect in -lssl... " >&6; } +if ${ac_cv_lib_ssl_SSL_connect+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lssl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char SSL_connect (); +int +main () +{ +return SSL_connect (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ssl_SSL_connect=yes +else + ac_cv_lib_ssl_SSL_connect=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_connect" >&5 +$as_echo "$ac_cv_lib_ssl_SSL_connect" >&6; } +if test "x$ac_cv_lib_ssl_SSL_connect" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSSL 1 +_ACEOF + + LIBS="-lssl $LIBS" + +fi + +fi + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no - OpenSSL support disabled" >&5 +$as_echo "no - OpenSSL support disabled" >&6; } + cf_enable_openssl="no" +fi +fi + + if test "$ac_cv_lib_ssl_SSL_connect" = yes; then + ENABLE_SSL_TRUE= + ENABLE_SSL_FALSE='#' +else + ENABLE_SSL_TRUE='#' + ENABLE_SSL_FALSE= +fi + + + +# Check whether --enable-assert was given. +if test "${enable_assert+set}" = set; then : + enableval=$enable_assert; assert=$enableval +else + assert=no +fi + + +if test "$assert" = "no"; then : + +$as_echo "#define NDEBUG 1" >>confdefs.h + +fi + + + +$as_echo "#define NICKNAMEHISTORYLENGTH 16384" >>confdefs.h + + +$as_echo "#define CHANNEL_HEAP_SIZE 1024" >>confdefs.h + + +$as_echo "#define BAN_HEAP_SIZE 1024" >>confdefs.h + + +$as_echo "#define CLIENT_HEAP_SIZE 1024" >>confdefs.h + + +$as_echo "#define LCLIENT_HEAP_SIZE 512" >>confdefs.h + + +$as_echo "#define DNODE_HEAP_SIZE 1024" >>confdefs.h + + +$as_echo "#define DBUF_HEAP_SIZE 512" >>confdefs.h + + +$as_echo "#define AUTH_HEAP_SIZE 256" >>confdefs.h + + +$as_echo "#define DNS_HEAP_SIZE 256" >>confdefs.h + + + +# Argument processing. + + desired_iopoll_mechanism="none" + # Check whether --enable-kqueue was given. +if test "${enable_kqueue+set}" = set; then : + enableval=$enable_kqueue; desired_iopoll_mechanism="kqueue" +fi + + # Check whether --enable-epoll was given. +if test "${enable_epoll+set}" = set; then : + enableval=$enable_epoll; desired_iopoll_mechanism="epoll" +fi + + # Check whether --enable-devpoll was given. +if test "${enable_devpoll+set}" = set; then : + enableval=$enable_devpoll; desired_iopoll_mechanism="devpoll" +fi + + # Check whether --enable-rtsigio was given. +if test "${enable_rtsigio+set}" = set; then : + enableval=$enable_rtsigio; desired_iopoll_mechanism="rtsigio" +fi + + # Check whether --enable-poll was given. +if test "${enable_poll+set}" = set; then : + enableval=$enable_poll; desired_iopoll_mechanism="poll" +fi + + # Check whether --enable-select was given. +if test "${enable_select+set}" = set; then : + enableval=$enable_select; desired_iopoll_mechanism="select" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for optimal/desired iopoll mechanism" >&5 +$as_echo_n "checking for optimal/desired iopoll mechanism... " >&6; } + iopoll_mechanism_none=0 + +cat >>confdefs.h <<_ACEOF +#define __IOPOLL_MECHANISM_NONE $iopoll_mechanism_none +_ACEOF + + iopoll_mechanism_kqueue=1 + +cat >>confdefs.h <<_ACEOF +#define __IOPOLL_MECHANISM_KQUEUE $iopoll_mechanism_kqueue +_ACEOF + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define kevent to an innocuous variant, in case <limits.h> declares kevent. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define kevent innocuous_kevent + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char kevent (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef kevent + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char kevent (); +/* 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_kevent || defined __stub___kevent +choke me +#endif + +int +main () +{ +return kevent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + is_kqueue_mechanism_available="yes" +else + is_kqueue_mechanism_available="no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + iopoll_mechanism_epoll=2 + +cat >>confdefs.h <<_ACEOF +#define __IOPOLL_MECHANISM_EPOLL $iopoll_mechanism_epoll +_ACEOF + + if test "$cross_compiling" = yes; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run test program while cross compiling +See \`config.log' for more details" "$LINENO" 5; } +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/epoll.h> +#include <sys/syscall.h> +#if defined(__stub_epoll_create) || defined(__stub___epoll_create) || defined(EPOLL_NEED_BODY) +#if !defined(__NR_epoll_create) +#if defined(__ia64__) +#define __NR_epoll_create 1243 +#elif defined(__x86_64__) +#define __NR_epoll_create 214 +#elif defined(__sparc64__) || defined(__sparc__) +#define __NR_epoll_create 193 +#elif defined(__s390__) || defined(__m68k__) +#define __NR_epoll_create 249 +#elif defined(__ppc64__) || defined(__ppc__) +#define __NR_epoll_create 236 +#elif defined(__parisc__) || defined(__arm26__) || defined(__arm__) +#define __NR_epoll_create 224 +#elif defined(__alpha__) +#define __NR_epoll_create 407 +#elif defined(__sh64__) +#define __NR_epoll_create 282 +#elif defined(__i386__) || defined(__sh__) || defined(__m32r__) || defined(__h8300__) || defined(__frv__) +#define __NR_epoll_create 254 +#else +#error No system call numbers defined for epoll family. +#endif +#endif +_syscall1(int, epoll_create, int, size) +#endif + +int +main () +{ + return epoll_create(256) == -1 ? 1 : 0 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + is_epoll_mechanism_available="yes" +else + is_epoll_mechanism_available="no" +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + iopoll_mechanism_devpoll=3 + +cat >>confdefs.h <<_ACEOF +#define __IOPOLL_MECHANISM_DEVPOLL $iopoll_mechanism_devpoll +_ACEOF + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <devpoll.h> +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + is_devpoll_mechanism_available="yes" +else + is_devpoll_mechanism_available="no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test "$is_devpoll_mechanism_available" = "yes" ; then + +$as_echo "#define HAVE_DEVPOLL_H 1" >>confdefs.h + + fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/devpoll.h> +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + is_devpoll_mechanism_available="yes" +else + is_devpoll_mechanism_available="no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test "$is_devpoll_mechanism_available" = "yes" ; then + +$as_echo "#define HAVE_SYS_DEVPOLL_H 1" >>confdefs.h + + fi + iopoll_mechanism_rtsigio=4 + +cat >>confdefs.h <<_ACEOF +#define __IOPOLL_MECHANISM_RTSIGIO $iopoll_mechanism_rtsigio +_ACEOF + + if test "$cross_compiling" = yes; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run test program while cross compiling +See \`config.log' for more details" "$LINENO" 5; } +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define _GNU_SOURCE +#include <fcntl.h> +static unsigned int have_f_setsig = 0; + +int +main () +{ + +#ifdef F_SETSIG + have_f_setsig = 1; +#endif + return have_f_setsig == 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + is_rtsigio_mechanism_available="yes" +else + is_rtsigio_mechanism_available="no" +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + iopoll_mechanism_poll=5 + +cat >>confdefs.h <<_ACEOF +#define __IOPOLL_MECHANISM_POLL $iopoll_mechanism_poll +_ACEOF + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define poll to an innocuous variant, in case <limits.h> declares poll. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define poll innocuous_poll + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char poll (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef poll + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char poll (); +/* 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_poll || defined __stub___poll +choke me +#endif + +int +main () +{ +return poll (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + is_poll_mechanism_available="yes" +else + is_poll_mechanism_available="no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + iopoll_mechanism_select=6 + +cat >>confdefs.h <<_ACEOF +#define __IOPOLL_MECHANISM_SELECT $iopoll_mechanism_select +_ACEOF + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define select to an innocuous variant, in case <limits.h> declares select. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define select innocuous_select + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char select (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef select + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char select (); +/* 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_select || defined __stub___select +choke me +#endif + +int +main () +{ +return select (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + is_select_mechanism_available="yes" +else + is_select_mechanism_available="no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + optimal_iopoll_mechanism="none" + for mechanism in "kqueue" "epoll" "devpoll" "rtsigio" "poll" "select" ; do # order is important + eval "is_optimal_iopoll_mechanism_available=\$is_${mechanism}_mechanism_available" + if test "$is_optimal_iopoll_mechanism_available" = "yes" ; then + optimal_iopoll_mechanism="$mechanism" + break + fi + done + if test "$desired_iopoll_mechanism" = "none" ; then + if test "$optimal_iopoll_mechanism" = "none" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } + as_fn_error $? "no iopoll mechanism found!" "$LINENO" 5 + else + selected_iopoll_mechanism=$optimal_iopoll_mechanism + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $selected_iopoll_mechanism" >&5 +$as_echo "$selected_iopoll_mechanism" >&6; } + fi + else + eval "is_desired_iopoll_mechanism_available=\$is_${desired_iopoll_mechanism}_mechanism_available" + if test "$is_desired_iopoll_mechanism_available" = "yes" ; then + selected_iopoll_mechanism=$desired_iopoll_mechanism + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $selected_iopoll_mechanism" >&5 +$as_echo "$selected_iopoll_mechanism" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } + as_fn_error $? "desired iopoll mechanism, $desired_iopoll_mechanism, is not available" "$LINENO" 5 + fi + fi + eval "use_iopoll_mechanism=\$iopoll_mechanism_${selected_iopoll_mechanism}" + +cat >>confdefs.h <<_ACEOF +#define USE_IOPOLL_MECHANISM $use_iopoll_mechanism +_ACEOF + + + + +# Check whether --with-nicklen was given. +if test "${with_nicklen+set}" = set; then : + withval=$with_nicklen; nicklen="$withval" +else + nicklen="9" +fi + + +cat >>confdefs.h <<_ACEOF +#define NICKLEN ($nicklen) +_ACEOF + + + + +# Check whether --with-topiclen was given. +if test "${with_topiclen+set}" = set; then : + withval=$with_topiclen; topiclen="$withval" +else + topiclen="160" +fi + + +cat >>confdefs.h <<_ACEOF +#define TOPICLEN ($topiclen) +_ACEOF + + + + # Check whether --enable-halfops was given. +if test "${enable_halfops+set}" = set; then : + enableval=$enable_halfops; halfops="$enableval" +else + halfops="no" +fi + + if test "$halfops" = "yes" ; then + +$as_echo "#define HALFOPS 1" >>confdefs.h + + fi + + + # Check whether --enable-debugging was given. +if test "${enable_debugging+set}" = set; then : + enableval=$enable_debugging; debugging="$enableval" +else + debugging="no" +fi + + if test "$debugging" = "yes" ; then + +$as_echo "#define DEBUG 1" >>confdefs.h + + CFLAGS="-Wall -g -O0" + else + +$as_echo "#define NDEBUG 1" >>confdefs.h + + fi + + + # Check whether --enable-warnings was given. +if test "${enable_warnings+set}" = set; then : + enableval=$enable_warnings; warnings="$enableval" +else + warnings="no" +fi + + if test "$warnings" = "yes" ; then + CFLAGS="-Wall -Wextra -Wno-unused -Wcast-qual -Wcast-align -Wbad-function-cast -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wredundant-decls -Wshadow -Wwrite-strings -Wundef" + fi + + + + prefix_NONE= + exec_prefix_NONE= + test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix + test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix + eval ac_define_dir="\"$prefix\"" + eval ac_define_dir="\"$ac_define_dir\"" + PREFIX="$ac_define_dir" + + +cat >>confdefs.h <<_ACEOF +#define PREFIX "$ac_define_dir" +_ACEOF + + test "$prefix_NONE" && prefix=NONE + test "$exec_prefix_NONE" && exec_prefix=NONE + + + prefix_NONE= + exec_prefix_NONE= + test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix + test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix + eval ac_define_dir="\"$sysconfdir\"" + eval ac_define_dir="\"$ac_define_dir\"" + SYSCONFDIR="$ac_define_dir" + + +cat >>confdefs.h <<_ACEOF +#define SYSCONFDIR "$ac_define_dir" +_ACEOF + + test "$prefix_NONE" && prefix=NONE + test "$exec_prefix_NONE" && exec_prefix=NONE + + + prefix_NONE= + exec_prefix_NONE= + test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix + test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix + eval ac_define_dir="\"$libdir\"" + eval ac_define_dir="\"$ac_define_dir\"" + LIBDIR="$ac_define_dir" + + +cat >>confdefs.h <<_ACEOF +#define LIBDIR "$ac_define_dir" +_ACEOF + + test "$prefix_NONE" && prefix=NONE + test "$exec_prefix_NONE" && exec_prefix=NONE + + + prefix_NONE= + exec_prefix_NONE= + test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix + test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix + eval ac_define_dir="\"$datadir\"" + eval ac_define_dir="\"$ac_define_dir\"" + DATADIR="$ac_define_dir" + + +cat >>confdefs.h <<_ACEOF +#define DATADIR "$ac_define_dir" +_ACEOF + + test "$prefix_NONE" && prefix=NONE + test "$exec_prefix_NONE" && exec_prefix=NONE + + + prefix_NONE= + exec_prefix_NONE= + test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix + test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix + eval ac_define_dir="\"$localstatedir\"" + eval ac_define_dir="\"$ac_define_dir\"" + LOCALSTATEDIR="$ac_define_dir" + + +cat >>confdefs.h <<_ACEOF +#define LOCALSTATEDIR "$ac_define_dir" +_ACEOF + + test "$prefix_NONE" && prefix=NONE + test "$exec_prefix_NONE" && exec_prefix=NONE + + +ac_config_files="$ac_config_files Makefile contrib/Makefile contrib/help/Makefile src/Makefile libltdl/Makefile messages/Makefile modules/Makefile modules/core/Makefile doc/Makefile help/Makefile help/opers/Makefile help/users/Makefile tools/Makefile" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${INSTALL_LTDL_TRUE}" && test -z "${INSTALL_LTDL_FALSE}"; then + as_fn_error $? "conditional \"INSTALL_LTDL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CONVENIENCE_LTDL_TRUE}" && test -z "${CONVENIENCE_LTDL_FALSE}"; then + as_fn_error $? "conditional \"CONVENIENCE_LTDL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +LT_CONFIG_H=config.h + + _ltdl_libobjs= + _ltdl_ltlibobjs= + if test -n "$_LT_LIBOBJS"; then + # Remove the extension. + _lt_sed_drop_objext='s/\.o$//;s/\.obj$//' + for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | sed "$_lt_sed_drop_objext" | sort -u`; do + _ltdl_libobjs="$_ltdl_libobjs $lt_libobj_prefix$i.$ac_objext" + _ltdl_ltlibobjs="$_ltdl_ltlibobjs $lt_libobj_prefix$i.lo" + done + fi + ltdl_LIBOBJS=$_ltdl_libobjs + + ltdl_LTLIBOBJS=$_ltdl_ltlibobjs + + + +if test -z "${ENABLE_SSL_TRUE}" && test -z "${ENABLE_SSL_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_SSL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by ircd-hybrid $as_me 8.0.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to <bugs@ircd-hybrid.org>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +ircd-hybrid config.status 8.0.0 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "contrib/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/Makefile" ;; + "contrib/help/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/help/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "libltdl/Makefile") CONFIG_FILES="$CONFIG_FILES libltdl/Makefile" ;; + "messages/Makefile") CONFIG_FILES="$CONFIG_FILES messages/Makefile" ;; + "modules/Makefile") CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;; + "modules/core/Makefile") CONFIG_FILES="$CONFIG_FILES modules/core/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "help/Makefile") CONFIG_FILES="$CONFIG_FILES help/Makefile" ;; + "help/opers/Makefile") CONFIG_FILES="$CONFIG_FILES help/opers/Makefile" ;; + "help/users/Makefile") CONFIG_FILES="$CONFIG_FILES help/users/Makefile" ;; + "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' <confdefs.h | sed ' +s/'"$ac_delim"'/"\\\ +"/g' >>$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="" + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..cb32be3 --- /dev/null +++ b/configure.ac @@ -0,0 +1,191 @@ +# Inspired by work Copyright (C) 2006 Luca Filipozzi +# vim: set fdm=marker ts=2 sw=2 et: + +AC_REVISION([$Id$]) + +AC_PREREQ(2.69) +AC_INIT([ircd-hybrid], [8.0.0], [bugs@ircd-hybrid.org]) +AM_INIT_AUTOMAKE(1.12.4) +AM_MAINTAINER_MODE +AC_CONFIG_HEADER(config.h) +AC_CONFIG_SRCDIR(src/ircd.c) + +# Checks for programs. +AC_PROG_CC_C99 +AS_IF([test "$ac_cv_prog_cc_c99" = "no"], + [AC_MSG_ERROR([no suitable C99 compiler found. Aborting.])]) +AC_PROG_YACC +AM_PROG_LEX +AC_PROG_INSTALL + +# Initializing libtool. +LT_CONFIG_LTDL_DIR([libltdl]) +LT_INIT([dlopen disable-static]) +LTDL_INIT([recursive convenience]) +LIBTOOL="$LIBTOOL --silent" + +# Checks for libraries. +AX_CHECK_LIB_IPV4 +AX_CHECK_LIB_IPV6 + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_BIGENDIAN + +# Checks for library functions. +AC_CHECK_FUNCS_ONCE(mmap \ + strtok_r \ + usleep \ + strlcat \ + strlcpy) + +# Checks for header files. +AC_CHECK_HEADERS_ONCE(crypt.h \ + sys/resource.h \ + sys/param.h \ + types.h \ + socket.h \ + sys/wait.h \ + wait.h) + +AC_SEARCH_LIBS(crypt, crypt) + +AC_ARG_ENABLE(libpcre, + [AS_HELP_STRING([--disable-libpcre],[Disable PCRE support])], [], + [AC_CHECK_HEADER(pcre.h, + [AC_SEARCH_LIBS(pcre_study, pcre, + [AC_DEFINE(HAVE_LIBPCRE, 1, [Define to 1 if libpcre (-lpcre) is available.])])])], []) + +dnl Openssl checks +AC_ARG_ENABLE(openssl, +[ --enable-openssl[=DIR] Enable OpenSSL support (DIR optional). + --disable-openssl Disable OpenSSL support. ], +[ cf_enable_openssl=$enableval ], +[ cf_enable_openssl="auto" ]) +AC_MSG_CHECKING([for OpenSSL]) +if test "$cf_enable_openssl" != "no"; then + cf_openssl_basedir="" + if test "$cf_enable_openssl" != "auto" && + test "$cf_enable_openssl" != "yes"; then + dnl Support for --enable-openssl=/some/place + cf_openssl_basedir="${cf_enable_openssl}" + else + dnl Do the auto-probe here. Check some common directory paths. + for dirs in /usr/local/ssl /usr/pkg /usr/local /usr/lib /usr/lib/ssl\ + /opt /opt/openssl /usr/local/openssl; do + if test -f "${dirs}/include/openssl/opensslv.h"; then + cf_openssl_basedir="${dirs}" + break + fi + done + unset dirs + fi + + dnl Now check cf_openssl_found to see if we found anything. + if test ! -z "$cf_openssl_basedir"; then + if test -f "${cf_openssl_basedir}/include/openssl/opensslv.h"; then + CPPFLAGS="-I${cf_openssl_basedir}/include $CPPFLAGS" + LDFLAGS="-L${cf_openssl_basedir}/lib $LDFLAGS" + else + dnl OpenSSL wasn't found in the directory specified. Naughty + dnl administrator... + cf_openssl_basedir="" + fi + else + dnl Check for stock FreeBSD 4.x and 5.x systems, since their files + dnl are in /usr/include and /usr/lib. In this case, we don't want to + dnl change INCLUDES or LIBS, but still want to enable OpenSSL. + dnl We can't do this check above, because some people want two versions + dnl of OpenSSL installed (stock FreeBSD 4.x/5.x and /usr/local/ssl) + dnl and they want /usr/local/ssl to have preference. + if test -f "/usr/include/openssl/opensslv.h"; then + cf_openssl_basedir="/usr" + fi + fi + + dnl If we have a basedir defined, then everything is okay. Otherwise, + dnl we have a problem. + if test ! -z "$cf_openssl_basedir"; then + AC_MSG_RESULT([$cf_openssl_basedir]) + cf_enable_openssl="yes" + else + AC_MSG_RESULT([not found. Please check your path.]) + cf_enable_openssl="no" + fi + unset cf_openssl_basedir +else + dnl If --disable-openssl was specified + AC_MSG_RESULT([disabled]) +fi + +AS_IF([test "$cf_enable_openssl" != "no"], + [AC_MSG_CHECKING(for OpenSSL 0.9.8 or above) + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([ + #include <openssl/opensslv.h> + #include <stdlib.h>], + [[ exit(!(OPENSSL_VERSION_NUMBER >= 0x00908000)); ]])], + [cf_openssl_version_ok=yes], + [cf_openssl_version_ok=no], + [cf_openssl_version_ok=no]) + + AS_IF([test "$cf_openssl_version_ok" = "yes"], + [AC_MSG_RESULT(found) + + AC_CHECK_LIB(crypto, RSA_free) + AS_IF([test "$ac_cv_lib_crypto_RSA_free" = "yes"], + [AC_CHECK_LIB(ssl, SSL_connect)]) + ],[AC_MSG_RESULT(no - OpenSSL support disabled) + cf_enable_openssl="no"])]) + +AM_CONDITIONAL(ENABLE_SSL, [test "$ac_cv_lib_ssl_SSL_connect" = yes]) + + +AC_ARG_ENABLE(assert, AS_HELP_STRING([--enable-assert], + [Enable assert() statements]), + [assert=$enableval], [assert=no]) + +AS_IF([test "$assert" = "no"], + [AC_DEFINE(NDEBUG, 1, [Define to disable assert() statements.])]) + + +AC_DEFINE([NICKNAMEHISTORYLENGTH], 16384, [Size of the WHOWAS array.]) +AC_DEFINE([CHANNEL_HEAP_SIZE], 1024, [Size of the channel heap.]) +AC_DEFINE([BAN_HEAP_SIZE], 1024, [Size of the ban heap.]) +AC_DEFINE([CLIENT_HEAP_SIZE], 1024, [Size of the client heap.]) +AC_DEFINE([LCLIENT_HEAP_SIZE], 512, [Size of the local client heap.]) +AC_DEFINE([DNODE_HEAP_SIZE], 1024, [Size of the dlink_node heap.]) +AC_DEFINE([DBUF_HEAP_SIZE], 512, [Size of the dbuf heap.]) +AC_DEFINE([AUTH_HEAP_SIZE], 256, [Size of the auth heap.]) +AC_DEFINE([DNS_HEAP_SIZE], 256, [Size of the dns heap.]) + + +# Argument processing. +AX_ARG_ENABLE_IOLOOP_MECHANISM +AX_ARG_WITH_NICKLEN +AX_ARG_WITH_TOPICLEN +AX_ARG_ENABLE_HALFOPS +AX_ARG_ENABLE_DEBUGGING +AX_ARG_ENABLE_WARNINGS + +AC_DEFINE_DIR([PREFIX],[prefix],[Set to prefix.]) +AC_DEFINE_DIR([SYSCONFDIR],[sysconfdir],[Set to sysconfdir.]) +AC_DEFINE_DIR([LIBDIR],[libdir],[Set to libdir.]) +AC_DEFINE_DIR([DATADIR],[datadir],[Set to datadir.]) +AC_DEFINE_DIR([LOCALSTATEDIR],[localstatedir],[Set to localstatedir.]) + +AC_CONFIG_FILES( \ + Makefile \ + contrib/Makefile \ + contrib/help/Makefile \ + src/Makefile \ + libltdl/Makefile \ + messages/Makefile \ + modules/Makefile \ + modules/core/Makefile \ + doc/Makefile \ + help/Makefile \ + help/opers/Makefile \ + help/users/Makefile \ + tools/Makefile) + +AC_OUTPUT diff --git a/contrib/Makefile.am b/contrib/Makefile.am new file mode 100644 index 0000000..22015c9 --- /dev/null +++ b/contrib/Makefile.am @@ -0,0 +1,44 @@ +AUTOMAKE_OPTIONS = foreign +MODULE_FLAGS = -module -avoid-version + +AM_CPPFLAGS = -I$(top_srcdir)/include +modulesdir = $(pkglibdir)/modules/autoload + +modules_LTLIBRARIES = example_module.la \ + ip_cloaking.la \ + m_change.la \ + m_clearchan.la \ + m_ctrace.la \ + m_force.la \ + m_ltrace.la \ + m_ojoin.la \ + m_operspy.la \ + m_opme.la \ + m_webirc.la + +example_module_la_LDFLAGS = $(MODULE_FLAGS) +ip_cloaking_la_LDFLAGS = $(MODULE_FLAGS) +m_change_la_LDFLAGS = $(MODULE_FLAGS) +m_clearchan_la_LDFLAGS = $(MODULE_FLAGS) +m_ctrace_la_LDFLAGS = $(MODULE_FLAGS) +m_force_la_LDFLAGS = $(MODULE_FLAGS) +m_ltrace_la_LDFLAGS = $(MODULE_FLAGS) +m_ojoin_la_LDFLAGS = $(MODULE_FLAGS) +m_operspy_la_LDFLAGS = $(MODULE_FLAGS) +m_opme_la_LDFLAGS = $(MODULE_FLAGS) +m_webirc_la_LDFLAGS = $(MODULE_FLAGS) + + +example_module_la_SOURCES = example_module.c +ip_cloaking_la_SOURCES = ip_cloaking.c +m_change_la_SOURCES = m_change.c +m_clearchan_la_SOURCES = m_clearchan.c +m_ctrace_la_SOURCES = m_ctrace.c +m_force_la_SOURCES = m_force.c +m_ltrace_la_SOURCES = m_ltrace.c +m_ojoin_la_SOURCES = m_ojoin.c +m_operspy_la_SOURCES = m_operspy.c +m_opme_la_SOURCES = m_opme.c +m_webirc_la_SOURCES = m_webirc.c + +modules: $(modules_LTLIBRARIES) diff --git a/contrib/Makefile.in b/contrib/Makefile.in new file mode 100644 index 0000000..bd63c4b --- /dev/null +++ b/contrib/Makefile.in @@ -0,0 +1,733 @@ +# Makefile.in generated by automake 1.12.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(modulesdir)" +LTLIBRARIES = $(modules_LTLIBRARIES) +example_module_la_LIBADD = +am_example_module_la_OBJECTS = example_module.lo +example_module_la_OBJECTS = $(am_example_module_la_OBJECTS) +example_module_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(example_module_la_LDFLAGS) $(LDFLAGS) -o $@ +ip_cloaking_la_LIBADD = +am_ip_cloaking_la_OBJECTS = ip_cloaking.lo +ip_cloaking_la_OBJECTS = $(am_ip_cloaking_la_OBJECTS) +ip_cloaking_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(ip_cloaking_la_LDFLAGS) $(LDFLAGS) -o $@ +m_change_la_LIBADD = +am_m_change_la_OBJECTS = m_change.lo +m_change_la_OBJECTS = $(am_m_change_la_OBJECTS) +m_change_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_change_la_LDFLAGS) $(LDFLAGS) -o $@ +m_clearchan_la_LIBADD = +am_m_clearchan_la_OBJECTS = m_clearchan.lo +m_clearchan_la_OBJECTS = $(am_m_clearchan_la_OBJECTS) +m_clearchan_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_clearchan_la_LDFLAGS) $(LDFLAGS) -o $@ +m_ctrace_la_LIBADD = +am_m_ctrace_la_OBJECTS = m_ctrace.lo +m_ctrace_la_OBJECTS = $(am_m_ctrace_la_OBJECTS) +m_ctrace_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_ctrace_la_LDFLAGS) $(LDFLAGS) -o $@ +m_force_la_LIBADD = +am_m_force_la_OBJECTS = m_force.lo +m_force_la_OBJECTS = $(am_m_force_la_OBJECTS) +m_force_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_force_la_LDFLAGS) $(LDFLAGS) -o $@ +m_ltrace_la_LIBADD = +am_m_ltrace_la_OBJECTS = m_ltrace.lo +m_ltrace_la_OBJECTS = $(am_m_ltrace_la_OBJECTS) +m_ltrace_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_ltrace_la_LDFLAGS) $(LDFLAGS) -o $@ +m_ojoin_la_LIBADD = +am_m_ojoin_la_OBJECTS = m_ojoin.lo +m_ojoin_la_OBJECTS = $(am_m_ojoin_la_OBJECTS) +m_ojoin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_ojoin_la_LDFLAGS) $(LDFLAGS) -o $@ +m_operspy_la_LIBADD = +am_m_operspy_la_OBJECTS = m_operspy.lo +m_operspy_la_OBJECTS = $(am_m_operspy_la_OBJECTS) +m_operspy_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_operspy_la_LDFLAGS) $(LDFLAGS) -o $@ +m_opme_la_LIBADD = +am_m_opme_la_OBJECTS = m_opme.lo +m_opme_la_OBJECTS = $(am_m_opme_la_OBJECTS) +m_opme_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_opme_la_LDFLAGS) $(LDFLAGS) -o $@ +m_webirc_la_LIBADD = +am_m_webirc_la_OBJECTS = m_webirc.lo +m_webirc_la_OBJECTS = $(am_m_webirc_la_OBJECTS) +m_webirc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_webirc_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(example_module_la_SOURCES) $(ip_cloaking_la_SOURCES) \ + $(m_change_la_SOURCES) $(m_clearchan_la_SOURCES) \ + $(m_ctrace_la_SOURCES) $(m_force_la_SOURCES) \ + $(m_ltrace_la_SOURCES) $(m_ojoin_la_SOURCES) \ + $(m_operspy_la_SOURCES) $(m_opme_la_SOURCES) \ + $(m_webirc_la_SOURCES) +DIST_SOURCES = $(example_module_la_SOURCES) $(ip_cloaking_la_SOURCES) \ + $(m_change_la_SOURCES) $(m_clearchan_la_SOURCES) \ + $(m_ctrace_la_SOURCES) $(m_force_la_SOURCES) \ + $(m_ltrace_la_SOURCES) $(m_ojoin_la_SOURCES) \ + $(m_operspy_la_SOURCES) $(m_opme_la_SOURCES) \ + $(m_webirc_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBDIR = @LIBDIR@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PREFIX = @PREFIX@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +MODULE_FLAGS = -module -avoid-version +AM_CPPFLAGS = -I$(top_srcdir)/include +modulesdir = $(pkglibdir)/modules/autoload +modules_LTLIBRARIES = example_module.la \ + ip_cloaking.la \ + m_change.la \ + m_clearchan.la \ + m_ctrace.la \ + m_force.la \ + m_ltrace.la \ + m_ojoin.la \ + m_operspy.la \ + m_opme.la \ + m_webirc.la + +example_module_la_LDFLAGS = $(MODULE_FLAGS) +ip_cloaking_la_LDFLAGS = $(MODULE_FLAGS) +m_change_la_LDFLAGS = $(MODULE_FLAGS) +m_clearchan_la_LDFLAGS = $(MODULE_FLAGS) +m_ctrace_la_LDFLAGS = $(MODULE_FLAGS) +m_force_la_LDFLAGS = $(MODULE_FLAGS) +m_ltrace_la_LDFLAGS = $(MODULE_FLAGS) +m_ojoin_la_LDFLAGS = $(MODULE_FLAGS) +m_operspy_la_LDFLAGS = $(MODULE_FLAGS) +m_opme_la_LDFLAGS = $(MODULE_FLAGS) +m_webirc_la_LDFLAGS = $(MODULE_FLAGS) +example_module_la_SOURCES = example_module.c +ip_cloaking_la_SOURCES = ip_cloaking.c +m_change_la_SOURCES = m_change.c +m_clearchan_la_SOURCES = m_clearchan.c +m_ctrace_la_SOURCES = m_ctrace.c +m_force_la_SOURCES = m_force.c +m_ltrace_la_SOURCES = m_ltrace.c +m_ojoin_la_SOURCES = m_ojoin.c +m_operspy_la_SOURCES = m_operspy.c +m_opme_la_SOURCES = m_opme.c +m_webirc_la_SOURCES = m_webirc.c +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign contrib/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign contrib/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-modulesLTLIBRARIES: $(modules_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(modules_LTLIBRARIES)'; test -n "$(modulesdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(modulesdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(modulesdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(modulesdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(modulesdir)"; \ + } + +uninstall-modulesLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(modules_LTLIBRARIES)'; test -n "$(modulesdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(modulesdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(modulesdir)/$$f"; \ + done + +clean-modulesLTLIBRARIES: + -test -z "$(modules_LTLIBRARIES)" || rm -f $(modules_LTLIBRARIES) + @list='$(modules_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +example_module.la: $(example_module_la_OBJECTS) $(example_module_la_DEPENDENCIES) $(EXTRA_example_module_la_DEPENDENCIES) + $(example_module_la_LINK) -rpath $(modulesdir) $(example_module_la_OBJECTS) $(example_module_la_LIBADD) $(LIBS) +ip_cloaking.la: $(ip_cloaking_la_OBJECTS) $(ip_cloaking_la_DEPENDENCIES) $(EXTRA_ip_cloaking_la_DEPENDENCIES) + $(ip_cloaking_la_LINK) -rpath $(modulesdir) $(ip_cloaking_la_OBJECTS) $(ip_cloaking_la_LIBADD) $(LIBS) +m_change.la: $(m_change_la_OBJECTS) $(m_change_la_DEPENDENCIES) $(EXTRA_m_change_la_DEPENDENCIES) + $(m_change_la_LINK) -rpath $(modulesdir) $(m_change_la_OBJECTS) $(m_change_la_LIBADD) $(LIBS) +m_clearchan.la: $(m_clearchan_la_OBJECTS) $(m_clearchan_la_DEPENDENCIES) $(EXTRA_m_clearchan_la_DEPENDENCIES) + $(m_clearchan_la_LINK) -rpath $(modulesdir) $(m_clearchan_la_OBJECTS) $(m_clearchan_la_LIBADD) $(LIBS) +m_ctrace.la: $(m_ctrace_la_OBJECTS) $(m_ctrace_la_DEPENDENCIES) $(EXTRA_m_ctrace_la_DEPENDENCIES) + $(m_ctrace_la_LINK) -rpath $(modulesdir) $(m_ctrace_la_OBJECTS) $(m_ctrace_la_LIBADD) $(LIBS) +m_force.la: $(m_force_la_OBJECTS) $(m_force_la_DEPENDENCIES) $(EXTRA_m_force_la_DEPENDENCIES) + $(m_force_la_LINK) -rpath $(modulesdir) $(m_force_la_OBJECTS) $(m_force_la_LIBADD) $(LIBS) +m_ltrace.la: $(m_ltrace_la_OBJECTS) $(m_ltrace_la_DEPENDENCIES) $(EXTRA_m_ltrace_la_DEPENDENCIES) + $(m_ltrace_la_LINK) -rpath $(modulesdir) $(m_ltrace_la_OBJECTS) $(m_ltrace_la_LIBADD) $(LIBS) +m_ojoin.la: $(m_ojoin_la_OBJECTS) $(m_ojoin_la_DEPENDENCIES) $(EXTRA_m_ojoin_la_DEPENDENCIES) + $(m_ojoin_la_LINK) -rpath $(modulesdir) $(m_ojoin_la_OBJECTS) $(m_ojoin_la_LIBADD) $(LIBS) +m_operspy.la: $(m_operspy_la_OBJECTS) $(m_operspy_la_DEPENDENCIES) $(EXTRA_m_operspy_la_DEPENDENCIES) + $(m_operspy_la_LINK) -rpath $(modulesdir) $(m_operspy_la_OBJECTS) $(m_operspy_la_LIBADD) $(LIBS) +m_opme.la: $(m_opme_la_OBJECTS) $(m_opme_la_DEPENDENCIES) $(EXTRA_m_opme_la_DEPENDENCIES) + $(m_opme_la_LINK) -rpath $(modulesdir) $(m_opme_la_OBJECTS) $(m_opme_la_LIBADD) $(LIBS) +m_webirc.la: $(m_webirc_la_OBJECTS) $(m_webirc_la_DEPENDENCIES) $(EXTRA_m_webirc_la_DEPENDENCIES) + $(m_webirc_la_LINK) -rpath $(modulesdir) $(m_webirc_la_OBJECTS) $(m_webirc_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example_module.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_cloaking.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_change.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_clearchan.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_ctrace.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_force.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_ltrace.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_ojoin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_operspy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_opme.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_webirc.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscopelist: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(modulesdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-modulesLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-modulesLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-modulesLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-modulesLTLIBRARIES cscopelist ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-modulesLTLIBRARIES \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-modulesLTLIBRARIES + + +modules: $(modules_LTLIBRARIES) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/README b/contrib/README new file mode 100644 index 0000000..32c107c --- /dev/null +++ b/contrib/README @@ -0,0 +1,122 @@ +$Id$ +----------------------------------------------- + +ircd-hybrid contributive add-ons :: + +This directory contains contributive modules, patches and other add-ons +that have been created by other people, or are not suitable to be included +into the main ircd-hybrid tree for various reasons. The coding team does +not officially support modules, patches and add-ons nor do they guarantee +that any of them will work to their intended capacity. + +It is to be noted WITH feeling, that not all of these modules, patches +or add-ons have been thoroughly tested, only that they've been tested +enough to see if they compile or work. This is one of the main driving +reasons why many of these are not in the main ircd-hybrid tree. At least +one or two of the modules in contrib have been known to core servers when +used. Heed this warning! + +To reiterate, ONE OR MORE OF THESE MAY AND PROBABLY WILL CORE YOUR SERVER. +USE AT YOUR OWN RISK. Reading this dicticates that you agree to the stated +fact. + +Modules :: +----------------------------------------------- +ip_cloaking.c -- This module enables IP/hostname cloaking support for + ircd-hybrid. It adds a CRC32 encrypted based cloaking + known to be used by other daemons such as Unreal IRCd + but with some modifications and different hashing + methods. Please read README.cloaking before you compile + and load this module, it contains VERY important + information. + + +m_change.c -- This module will allow IRC operators to alter the ident, + hostname or gecos (realname) fields of a given user. + + Syntax: CHGIDENT <nickname> <newident> + CHGHOST <nickname> <newhostname> + CHGNAME <nickname> <newname> + + Example: CHGIDENT lart llama + CHGHOST lart i.hate.packets + CHGNAME lart oorgle + + +m_clearchan.c -- Similar to the OperServ command CLEARCHAN, this module + will clear all users out of a channel, joins the person + who issued it, and locks the channel. It should be noted + that this command can be abused heavily. + + Syntax: CLEARCHAN <channel> + + Example: CLEARCHAN #warez + + +m_ctrace.c -- This module will perform a trace on a certain class. Valid + classes would be servers, users, operators or any custom + one you defined in class {} blocks. + + Syntax: CTRACE <class> + + Example: CTRACE users + + +m_force.c -- This module will force a user to either part or join a + channel with an optional status (@%+) + + Syntax: FORCEJOIN <nickname> [status]<channel> + FORCEPART <nickname> <channel> + + Example: FORCEJOIN nick @#chitchat + FORCEPART lamer #chitchat + + +m_ltrace.c -- This module will give a limited trace. This is similar to + TRACE except that it only reports current operators and servers. + + Syntax: LTRACE [nick|mask [server]] + + Example: LTRACE god + LTRACE node.server.com + + +m_ojoin.c -- This module will add the ability to join any channel no + matter what modes or limits are set with an optional + status (@%+) It should be noted that this command can be + abused heavily. + + Syntax: OJOIN [status]<channel> + + Example: OJOIN @#private + + +m_operspy.c -- This module will allow operators with access to spy on + users. It should be noted the notion of this module + practically invalidates any form of privacy. + + Syntax: OPERSPY <LIST/WHO/MODE/WHOIS/NAMES> <parameter> + + +m_opme.c -- This module will allow an IRC operator to op themselves in + an opless channel should the need arise. + + Syntax: OPME <channel> + Example: OPME #orphanchan + + +m_webirc.c -- Adds CGI:IRC/WebIRC support. A special auth{} block is + required in order to enable WebIRC support. For more + details check m_webirc.c + + +example_module.c -- This is an example module template to help users create + their own modules. + + +Help Files :: +----------------------------------------------- + +Each contrib module listed here has an accompanying help page or set of +help pages. They will be installed when you issue 'make install' inside +the contrib directory. To view them do /QUOTE HELP COMMAND. diff --git a/contrib/README.cloaking b/contrib/README.cloaking new file mode 100644 index 0000000..a89aa15 --- /dev/null +++ b/contrib/README.cloaking @@ -0,0 +1,87 @@ +ircd-hybrid IP/hostname cloaking README: +----------------------------------------------- +$Id$ + +Copyright (c) 2005 by Alan 'knight-' LeVee of ChatJunkies IRC Network +----------------------------------------------- + +This README file is designed to cover the aspects of the IP cloaking features +new to hybrid in the contrib module named ip_cloaking.c. The basis for the IP +cloaking is to add some level of privacy for local users to have by cloaking, or +rather masking a part of their hostname with a CRC32 polymorphism hash. + +This will make the necessary additions to the source code to allow IP cloaking +to work as well as adding in a new user mode known as +h. Normally on most IRC +daemons such as UnrealIRCd or ircu2, IP masking is assigned the user mode +x but +since we use +x for external operator messages we used +h as the next logical +step. + +Basically the IP cloaking is a proof of concept utilising a CRC32 based salt +encryption method that UnrealIRCd uses but with some changes and bit stuffing +and bit shifting. However, before you compile the contrib module, it is +*strongly* recommended that you modify the +ip_cloaking.c module and edit the following: + +#define KEY +#define KEY2 +#define KEY3 + +With different numbers than are present in the provided module. This insures +that no one can really decipher the secret keys because they'll go on the basis +that they are stock and not modified. To get proper or good entropy on random +numbers rather than trying to guess them it is a good idea to use an entropy +variable or device to grab them. If you have BASH available you can use the +randomization variable called ${RANDOM} to get your bits. You need at least 3 +secret keys in order for this to work, there is no preset requirement as to how +many numbers per key is required but it should have at least 4 to 6 numbers on +each block. If you want to do it easily and you have bash you can do the +following command in a BASH shell: + +$ echo -e "#define KEY ${RANDOM}\n#define KEY2 ${RANDOM}\n#define KEY3 +${RANDOM}" + +You'll get an output similar to this: + +#define KEY 935 +#define KEY2 23539 +#define KEY3 22522 + +Once you run that command you can copy and paste the output into ip_cloaking.c +and compile the module. However all servers *must* use the same secret keys in +order for this to work properly or you'll run into problems especially for +channel bans. + +Since you will also need the module m_change.so to go with IP cloaking it is +best just to cd into the contrib. directory and build all the modules like so: + +cd contrib; make install + +Then you'll need to edit etc/ircd.conf and add the following lines to the +modules {} block so you can load the module: + +module = "m_change.so"; +module = "ip_cloaking.so"; + +Please note that *all* servers *must* have these modules loaded or IP cloaking +will *not* work. Once this is done you can activate the IP cloaking by passing +the following user mode: + +/MODE nickname +h + +You should then recieve a message: + +--- ec6f50f-8f92678.ypwest01.mi.comcast.net :is your visible host + +This means that anyone who runs WHOIS on you will receive that as the host +response. However, if hide_spoof_ips is set to no yourself and IRC operators can +get your true IP from WHOIS but no one else. Once user mode +h is set however, +it cannot be unset (ala ircu2). Also as of right now, IP cloaking does not +support IPv6 users due to the rare use of IPv6 and the difficulty in coding +support for it. So if an IPv6 user tries to set +h they will get the following +message: + +--- *** Sorry, IP cloaking does not support IPv6 users! + +If you have any questions please direct them to knight- on irc.chatjunkies.org +in #cservice as this is not officially supported by the ircd-hybrid team. Thank +you, and enjoy! diff --git a/contrib/example_module.c b/contrib/example_module.c new file mode 100644 index 0000000..af62ee9 --- /dev/null +++ b/contrib/example_module.c @@ -0,0 +1,224 @@ +/************************************************************************ + * IRC - Internet Relay Chat, doc/example_module.c + * Copyright (C) 2001 Hybrid 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 1, 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. + * + * $Id$ + */ + +/* List of ircd includes from ../include/ + * These ones are necessary to build THIS module... + */ + +#include "stdinc.h" /* includes setup.h */ + +#include "client.h" /* Required for IsClient, etc. */ + +#include "send.h" /* sendto_one, most useful function of all time */ + +#include "parse.h" + +#include "modules.h" /* includes msg.h; use for the msgtab */ + +/* OTHER USEFUL INCLUDES: + * + * #include "handlers.h" <-- include this file to be able to use default + * functions in place of your own 'Access Denied' kind of function + * + * #include "numeric.h" <-- include this file to be able to use form_str, + * standard message formats (see messages.tab and *.lang in messages/) + * Examples are strewn all across the ircd code, so just grep a bit to + * find one! + * + * #include "irc_string.h" <-- best to include this if you use *any* + * string comparison or parsing functions, although they may be available + * natively for your OS the prototypes in irc_string.h may be required for + * others. */ + +/* + * Declare the void's initially up here, as modules don't have an + * include file, we will normally have client_p, source_p, parc + * and parv[] where: + * + * client_p == client issuing command + * source_p == where the command came from + * parc == the number of parameters + * parv == an array of the parameters + */ + + +/* + * mr_test + * parv[0] = sender prefix + * parv[1] = parameter + */ + +/* + * Here we have the functions themselves that we declared above, + * and the fairly normal C coding + */ +static void +mr_test(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc == 1) + sendto_one(source_p, ":%s NOTICE %s :You are unregistered and sent no parameters", + me.name, source_p->name); + else + sendto_one(source_p, ":%s NOTICE %s :You are unregistered and sent parameter: %s", + me.name, source_p->name, parv[1]); +} + +/* + * m_test + * parv[0] = sender prefix + * parv[1] = parameter + */ +static void +m_test(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc == 1) + sendto_one(source_p, ":%s NOTICE %s :You are a normal user, and sent no parameters", + me.name, source_p->name); + else + sendto_one(source_p, ":%s NOTICE %s :You are a normal user, and send parameters: %s", + me.name, source_p->name, parv[1]); +} + +/* + * ms_test + * parv[0] = sender prefix + * parv[1] = parameter + */ +static void +ms_test(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc == 1) + { + if (IsServer(source_p)) + sendto_one(source_p, ":%s NOTICE %s :You are a server, and sent no parameters", + me.name, source_p->name); + else + sendto_one(source_p, ":%s NOTICE %s :You are a remote client, and sent no parameters", + me.name, source_p->name); + } + else + { + if (IsServer(source_p)) + sendto_one(source_p, ":%s NOTICE %s :You are a server, and sent parameters: %s", + me.name, source_p->name, parv[1]); + else + sendto_one(source_p, ":%s NOTICE %s :You are a remote client, and sent parameters: %s", + me.name, source_p->name, parv[1]); + } +} + +/* + * mo_test + * parv[0] = sender prefix + * parv[1] = parameter + */ +static void +mo_test(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc == 1) + sendto_one(source_p, ":%s NOTICE %s :You are an operator, and sent no parameters", + me.name, source_p->name); + else + sendto_one(source_p, ":%s NOTICE %s :You are an operator, and sent parameters: %s", + me.name, source_p->name, parv[1]); +} + +/* + * Show the commands this module can handle in a msgtab + * and give the msgtab a name, here its test_msgtab + */ +static struct Message test_msgtab = { + + /* Fields are in order: + *-> "COMMAND", 0, 0, parc_count, maxparc, MFLG_SLOW, 0, + * + * where: + * COMMAND == the /command you want + * parc_count == the number of parameters needed + * (the clients name is one param, parv[0]) + * maxparc == the maximum parameters we allow + * the 0's and MFLG_SLOW should not be changed.. + */ + + /* + * This would add the command "TEST" which requires no additional + * parameters + */ + "TEST", 0, 0, 1, MAXPARA, MFLG_SLOW, 0, + + /* Fields are in order: + *-> {unregged, regged, remote, encap, oper, dummy} + * + * where: + * unregged == function to call for unregistered clients + * regged == function to call for normal users + * remote == function to call for servers/remote users + * encap == function to call for encap'd server/remote commands + * oper == function to call for operators + * dummy == function called when client is quarantined + * + * There are also some pre-coded functions for use: + * m_unregistered: prevent the client using this if unregistered + * m_not_oper: tell the client it requires being an operator + * m_ignore: ignore the command when it comes from certain types + * rfc1459_command_send_error: give an error when the command comes from certain types + */ + { mr_test, m_test, ms_test, m_ignore, mo_test, m_ignore } + + /* It is normal for unregistered functions to be prefixed with mr_ + * " " normal users to be prefixed with m_ + * " " remote clients to be prefixed with ms_ + * " " operators to be prefixed with mo_ + */ +}; +/* That's the msgtab finished */ + +/* Here we tell it what to do when the module is loaded */ +static void +module_init(void) +{ + /* This will add the commands in test_msgtab (which is above) */ + mod_add_cmd(&test_msgtab); +} + +/* here we tell it what to do when the module is unloaded */ +static void +module_exit(void) +{ + /* This will remove the commands in test_msgtab (which is above) */ + mod_del_cmd(&test_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; + +/* END OF EXAMPLE MODULE */ diff --git a/contrib/help/Makefile.in b/contrib/help/Makefile.in new file mode 100644 index 0000000..4e83932 --- /dev/null +++ b/contrib/help/Makefile.in @@ -0,0 +1,53 @@ +# Makefile to install help files +# $Id$ + +INSTALL= @INSTALL@ +INSTALL_DATA= @INSTALL_DATA@ +RM= @RM@ + +prefix= @prefix@ +datarootdir = $(DESTDIR)@datarootdir@ +exec_prefix= @execprefix@ +datadir = ${DESTDIR}@datadir@ +helpdir = ${datadir}/help +uhelpdir = ${helpdir}/users +ohelpdir = ${helpdir}/opers + +SYMLINKS= topic accept cmode admin names links away whowas \ + version kick who invite quit join list nick oper part \ + time motd userhost users whois ison lusers user help \ + pass error challenge knock ping pong flags +all: +build: +clean: +depend: + +install: + @echo installing help files... + -@if test ! -d $(helpdir); then \ + echo "mkdir $(helpdir)"; \ + mkdir -p $(helpdir); \ + echo "mkdir $(uhelpdir)"; \ + mkdir $(uhelpdir); \ + echo "mkdir $(ohelpdir)"; \ + mkdir $(ohelpdir); \ + fi + @for help in opers/*; do \ + if [ -f $$help ]; then \ + ${INSTALL_DATA} $$help $(ohelpdir); \ + fi \ + done + @for help in users/*; do \ + if [ -f $$help ]; then \ + $(INSTALL_DATA) $$help $(uhelpdir); \ + fi \ + done + @for link in $(SYMLINKS); do \ + rm -f $(uhelpdir)/$$link; \ + ln -s $(ohelpdir)/$$link $(uhelpdir); \ + done + +distclean: + ${RM} -f Makefile + +depend: diff --git a/contrib/help/opers/chghost b/contrib/help/opers/chghost new file mode 100644 index 0000000..1018830 --- /dev/null +++ b/contrib/help/opers/chghost @@ -0,0 +1,7 @@ +# $Id$ +CHGHOST [nickname] <hostname> + +The CHGHOST command takes two arguments. The first argument is optional and +can be the nickname of a user you wish to change the host of. If no +argument for the nickname is supplied, then it will change your host instead. +The second argument is the hostname you wish to use. diff --git a/contrib/help/opers/chgident b/contrib/help/opers/chgident new file mode 100644 index 0000000..67cf164 --- /dev/null +++ b/contrib/help/opers/chgident @@ -0,0 +1,7 @@ +# $Id$ +CHGIDENT [nickname] <ident> + +The CHGIDENT command takes two arguments. The first argument is optional and +can be the nickname of a user you wish to alter the ident of. If no +argument for the nickname is supplied it will change your ident instead. +The second argument is the ident you wish to use. diff --git a/contrib/help/opers/chgname b/contrib/help/opers/chgname new file mode 100644 index 0000000..9a92100 --- /dev/null +++ b/contrib/help/opers/chgname @@ -0,0 +1,7 @@ +# $Id$ +CHGNAME [nickname] <realname> + +The CHGNAME command takes two arguments. The first argument is optional and +can be the nickname of a user you wish to alter the gecos of. If no +argument for the nickname is supplied it will change your gecos instead. +The second argument is the gecos you wish to use. diff --git a/contrib/help/opers/classlist b/contrib/help/opers/classlist new file mode 100644 index 0000000..3ff353b --- /dev/null +++ b/contrib/help/opers/classlist @@ -0,0 +1,8 @@ +# $Id$ +CLASSLIST <class> + +The CLASSLIST command will show complete totals of a class you wish to see. + +For example if you want to see the totals for the class users you would do: + +CLASSLIST users - Shows the totals in the users class. diff --git a/contrib/help/opers/clearchan b/contrib/help/opers/clearchan new file mode 100644 index 0000000..3fb2d6a --- /dev/null +++ b/contrib/help/opers/clearchan @@ -0,0 +1,8 @@ +# $Id$ +CLEARCHAN <channel> + +The CLEARCHAN command will essentially take over a channel by purging all +the modes and user's privileges (e.g. voice, half-op, chanop), then +kicking all the users out. + +This command requires that you PART the channel first. diff --git a/contrib/help/opers/ctrace b/contrib/help/opers/ctrace new file mode 100644 index 0000000..2939bf0 --- /dev/null +++ b/contrib/help/opers/ctrace @@ -0,0 +1,9 @@ +# $Id$ +CTRACE <class> + +The CTRACE command will do a trace of users depending on class. Similar +to TRACE but class specific. + +For example if you want to do a trace on the clients in the users class: + +CTRACE users - Shows the totals in the users class. diff --git a/contrib/help/opers/forcejoin b/contrib/help/opers/forcejoin new file mode 100644 index 0000000..455dc95 --- /dev/null +++ b/contrib/help/opers/forcejoin @@ -0,0 +1,9 @@ +# $Id$ +FORCEJOIN <nickname> <channel> + +The FORCEJOIN command requires two arguments to be given. The first +argument is the nickname of the user you wish to execute the command +on, and the second argument is the destination channel they are to join. + +The command can also be used to force join a user to a channel that does +not exist. diff --git a/contrib/help/opers/forcepart b/contrib/help/opers/forcepart new file mode 100644 index 0000000..3ab351c --- /dev/null +++ b/contrib/help/opers/forcepart @@ -0,0 +1,6 @@ +# $Id$ +FORCEPART <nickname> <channel> + +The FORCEPART command requires two arguments to be given. The first +argument is the nickname of the user you wish to execute the command +on, and the second argument is the destination channel they are to part. diff --git a/contrib/help/opers/index b/contrib/help/opers/index new file mode 100644 index 0000000..c4e55ca --- /dev/null +++ b/contrib/help/opers/index @@ -0,0 +1,34 @@ +# $Id$ +Help topics available to opers: + +CAPAB CAPTURE CBURST CHGHOST +CHGIDENT CHGNAME CLASSLIST CLEARCHAN +CLIENT CLOSE CONNECT CRYPTLINK +CTRACE DELSPOOF DIE DLINE +DROP EOB ETRACE FORCEJOIN +FORCEPART GLINE HASH JUPE +KILL KLINE KNOCKLL LLJOIN +LLNICK LOCOPS LTRACE MKPASSWD +MODLIST MODLOAD MODRESTART MODUNLOAD +NBURST NOTICE OJOIN OMOTD +OPERWALL OPME POST PRIVMSG +REHASH RESTART RESV RKLINE +RXLINE SERVER SET SJOIN +SPOOF SQUIT STATS SVINFO +SVSNICK TESTGECOS TESTLINE TESTMASK +TRACE UHELP UMODE UNCAPTURE +UNDLINE UNGLINE UNKLINE UNRESV +UNXLINE WALLOPS XLINE + +Help topics available to users: + +ACCEPT ADMIN AWAY CHALLENGE +CMODE ERROR FLAGS HELP +INFO INVITE ISON JOIN +KICK KNOCK LINKS LIST +LUSERS MAP MOTD NAMES +NICK NOTICE OPER PART +PASS PING PONG PRIVMSG +QUIT STATS TIME TOPIC +UMODE USER USERHOST USERS +VERSION WHO WHOIS WHOWAS diff --git a/contrib/help/opers/ltrace b/contrib/help/opers/ltrace new file mode 100644 index 0000000..6d9402c --- /dev/null +++ b/contrib/help/opers/ltrace @@ -0,0 +1,5 @@ +# $Id$ +LTRACE [nickname/server mask] + +This command is similar to TRACE, but it doesn't display plain users +or definitions of connection classes. diff --git a/contrib/help/opers/ojoin b/contrib/help/opers/ojoin new file mode 100644 index 0000000..f1c9525 --- /dev/null +++ b/contrib/help/opers/ojoin @@ -0,0 +1,12 @@ +# $Id$ +OJOIN [flags]<channel> + +The OJOIN command requires only one argument with optional status flags. +Valid mode flags are @ % and +. This allows operators to join any channel +with the given status. + +Examples: +OJOIN @#secretchan - Will join you to #secretchan with chan ops. +OJOIN +#secretchan - Will join you to #secretchan with voice. + +This also works on local channels as well. diff --git a/contrib/help/opers/opme b/contrib/help/opers/opme new file mode 100644 index 0000000..db474dd --- /dev/null +++ b/contrib/help/opers/opme @@ -0,0 +1,5 @@ +# $Id$ +OPME <channel> + +OPME will give chanop status to the operator in the given channel. +OPME will only work if the channel is opless. diff --git a/contrib/help/users/index b/contrib/help/users/index new file mode 100644 index 0000000..2cdeba9 --- /dev/null +++ b/contrib/help/users/index @@ -0,0 +1,13 @@ +# $Id$ +Help topics available to users: + +ACCEPT ADMIN AWAY CHALLENGE +CMODE ERROR FLAGS HELP +INFO INVITE ISON JOIN +KICK KNOCK LINKS LIST +LUSERS MAP MOTD NAMES +NICK NOTICE OPER PART +PASS PING PONG PRIVMSG +QUIT STATS TIME TOPIC +UMODE USER USERHOST USERS +VERSION WHO WHOIS WHOWAS diff --git a/contrib/ip_cloaking.c b/contrib/ip_cloaking.c new file mode 100644 index 0000000..d9c2d68 --- /dev/null +++ b/contrib/ip_cloaking.c @@ -0,0 +1,474 @@ +/* MODULE CONFIGURATION FOLLOWS -- please read!! */ + +/* Change these numbers to something else. Please + * make sure that they match on ALL servers + * to avoid problems! + */ +#define KEY 23857 +#define KEY2 38447 +#define KEY3 64709 + +/* END OF MODULE CONFIGURATION */ + +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon (ircd). + * ip_cloaking.c: Provides hostname (partial) cloaking for clients. + * + * Copyright (c) 2005 by the past and present ircd coders, and others. + * + * 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 you 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 + * MERCHANTABILILTY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have recieved 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$ + */ + +/* + * Originally re-written from AustNet's VirtualWorld Code. + * Virtual World written by Roger 'RogerY' Yerramesetti <rogery@austnet.org> + * + * Re-written using the crc32 encryption implementation by //ylo based on the original + * implementation by Gary S. Brown. + * + * HiddenHost implementation based on the code from Unreal IRCd by + * RaYmAn, NiQuiL, narf, Griever (great thinking) eternal, bball, JK.@ roxnet.org + * + * Additional ideas and code by ShadowMaster, [-Th3Dud3-] (RageIRCd), Solaris @ Demonkarma.net, + * Alan 'knight-' LeVee of the ChatJunkies IRC Network and doughk_ff7. + */ + +#include "stdinc.h" +#include "whowas.h" +#include "channel_mode.h" +#include "client.h" +#include "hash.h" +#include "hook.h" +#include "irc_string.h" +#include "ircd.h" +#include "ircd_defs.h" +#include "numeric.h" +#include "s_serv.h" +#include "s_user.h" +#include "send.h" +#include "conf.h" +#include "modules.h" +#include "memory.h" +#include "log.h" +#include "sprintf_irc.h" +#include "userhost.h" + +static unsigned int umode_vhost = 0; +static int vhost_ipv6_err; +static dlink_node *prev_enter_umode; +static dlink_node *prev_umode; +static void *reset_ipv6err_flag(va_list); +static void *h_set_user_mode(va_list); + +/* + * The implementation originally comes from Gary S. Brown. The tables + * are a direct transplant of his original concept and have been + * changed for randomization purposes. Minor changes were also made + * to the crc32-function by //ylo. + * + * knight- + */ + +/* ============================================================= + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + * + * First, the polynomial itself and its stable of feedback terms. The + * polynomial is: + * + * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 + * + * Note that we take it "backwards" and put the highest-order term in + * the lowest-order bit. The X^32 term is "implied"; the LSB is the + * X^31 term, etc. The X^0 term (usually shown as "+1") results in + * the MSB being 1. + * + * Note that the usual hardware shift register implementation, which + * is what we're using (we're merely optimizing it by doing eight-bit + * chunks at a time) shifts bits into the lowest-order term. In our + * implementation, that means shifting towards the right. Why do we + * do it this way? Because the calculated CRC must be transmitted in + * order from highest-order term to lowest-order term. UARTs transmit + * characters in order from LSB to MSB. By storing the CRC this way, + * we and it to the UART in the order low-byte to high-byte; the UART + * sends each low-bit to high-bit; and the result is transmission bit + * by bit from highest-order to lowest-order term without requiring any + * bit shuffling on our part. Reception works similarly. + * + * The feedback term table consists of 256, 32-bit entries. Notes: + * + * The table can be generated at runtime if desired; code to do so + * is shown later. It might not be obvious, but the feedback terms + * simply represent the results of eight shift/xor operations for + * all combinations of data and CRC register values. + * + * The values must be right shifted by eight bits by the "updcrc" + * logic; the shift must be unsigned (bring in zeroes). On some hardware + * you could probably optimize the shift in assembler by using byte-swap + * instructions. + * + * polynomial $edb88320 + * + * -------------------------------------------------------------------- + */ + +static unsigned long crc32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +static unsigned long +crc32(const char *s, unsigned int len) +{ + unsigned int i; + unsigned long crc32val = 0; + + for (i = 0; i < len; i++) + crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); + + return crc32val; +} + +/* + * str2arr() + * + * converts IPv4 address segments into arrays + * for encryption + * + * inputs - address parvs, strings and deliminator + * outputs - array + * side effects - not IPv6 friendly + */ +static int +str2arr(char **pparv, char *string, const char *delim) +{ + char *tok; + int pparc = 0; + + /* Diane had suggested to use this method rather than while() -- knight */ + for (tok = strtok(string, delim); tok != NULL; tok = strtok(NULL, delim)) + { + pparv[pparc++] = tok; + } + + return pparc; +} + +/* + * make_virthost() + * + * curr = current hostname/ip + * host = current host socket + * new = encrypted hostname/ip + */ +static void +make_virthost(char *curr, char *host, char *new) +{ + char mask[HOSTLEN + 1]; + char *parv[HOSTLEN + 1], *parv2[HOSTLEN + 1], s[HOSTLEN + 1], s2[HOSTLEN + 1]; + int parc = 0, parc2 = 0, len = 0; + unsigned long hash[8]; + + strlcpy(s2, curr, HOSTLEN + 1); + strlcpy(s, host, HOSTLEN + 1); + + parc = str2arr(parv, s, "."); + parc2 = str2arr(parv2, s2, "."); + + if (!parc2) + return; + + hash[0] = ((crc32 (parv[3], strlen (parv[3])) + KEY) ^ KEY2) ^ KEY3; + hash[1] = ((KEY2 ^ crc32 (parv[2], strlen (parv[2]))) + KEY3) ^ KEY; + hash[2] = ((crc32 (parv[1], strlen (parv[1])) + KEY3) ^ KEY) ^ KEY2; + hash[3] = ((KEY3 ^ crc32 (parv[0], strlen (parv[0]))) + KEY2) ^ KEY; + + hash[0] <<= 2; + hash[0] >>= 2; + hash[0] &= 0x3FFFFFFF; + hash[0] &= 0xFFFFFFFF; + hash[1] <<= 2; + hash[1] >>= 2; + hash[1] &= 0x7FFFFFFF; + hash[1] &= 0x3FFFFFFF; + hash[2] <<= 2; + hash[2] >>= 2; + hash[2] &= 0x7FFFFFFF; + hash[2] &= 0xFFFFFFFF; + hash[3] <<= 2; + hash[3] >>= 2; + hash[3] &= 0x3FFFFFFF; + hash[3] &= 0x7FFFFFFF; + + /* IPv4 */ + if (parc2 == 4 || parc2 < 2) + { + len = strlen (parv2[3]); + + if (strchr("0123456789", parv2[3][len - 1]) || parc2 < 2) + { + ircsprintf(mask, "%s.%s.%s.%lx", + parv2[parc2 - 4], parv2[parc2 - 3], + parv2[parc2 - 2], hash[3]); + } + else + { + /* isp.tld */ + ircsprintf(mask, "%lx-%lx.%s.%s", + hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]); + } + } + else + { + if (parc2 >= 4) + { + /* isp.sub.tld or district.isp.tld */ + ircsprintf(mask, "%lx-%lx.%s.%s.%s", + hash[3], hash[1], parv2[parc2 - 3], parv2[parc2 - 2], + parv2[parc2 - 1]); + } + else + { + /* isp.tld */ + ircsprintf(mask, "%lx-%lx.%s.%s", + hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]); + } + + if (parc2 >= 5) + { + /* zone.district.isp.tld or district.isp.sub.tld */ + ircsprintf(mask, "%lx-%lx.%s.%s.%s.%s", + hash[1], hash[0], parv2[parc2 - 4], parv2[parc2 - 3], + parv2[parc2 - 2], parv2[parc2 - 1]); + } + else + { + /* isp.tld */ + ircsprintf(mask, "%lx-%lx.%s.%s", + hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]); + } + } + + strlcpy(new, mask, HOSTLEN + 1); +} + +/* + * set_vhost() + * + * inputs - pointer to given client to set IP cloak. + * outputs - NONE + * side effects - NONE + */ +static void +set_vhost(struct Client *client_p, struct Client *source_p, + struct Client *target_p) +{ + target_p->umodes |= umode_vhost; + + if (IsUserHostIp(target_p)) + delete_user_host(target_p->username, target_p->host, !MyConnect(target_p)); + + SetIPSpoof(target_p); + make_virthost(target_p->host, target_p->sockhost, target_p->host); + + add_user_host(target_p->username, target_p->host, !MyConnect(target_p)); + SetUserHost(target_p); + + clear_ban_cache_client(target_p); + + if (IsClient(target_p)) + sendto_server(client_p, CAP_ENCAP, NOCAPS, + ":%s ENCAP * CHGHOST %s %s", + me.name, target_p->name, target_p->host); + + sendto_one(target_p, form_str(RPL_HOSTHIDDEN), + me.name, target_p->name, target_p->host); +} + +static void * +reset_ipv6err_flag(va_list args) +{ + struct Client *client_p = va_arg(args, struct Client *); + struct Client *source_p = va_arg(args, struct Client *); + + vhost_ipv6_err = 0; + + return pass_callback(prev_enter_umode, client_p, source_p); +} + +static void * +h_set_user_mode(va_list args) +{ + struct Client *client_p = va_arg(args, struct Client *); + struct Client *target_p = va_arg(args, struct Client *); + int what = va_arg(args, int); + unsigned int flag = va_arg(args, unsigned int); + + if (flag == umode_vhost) + { + if (what == MODE_ADD) + { + /* Automatically break if any of these conditions are met. -- knight- */ + if (!MyConnect(target_p)) + return NULL; + + if (IsIPSpoof(target_p)) + return NULL; + + /* + * IPv6 could potentially core the server if a user connected via IPv6 sets +h + * so we need to check and break before that happens. -- knight- + */ +#ifdef IPV6 + if (target_p->localClient->aftype == AF_INET6) + { + if (!vhost_ipv6_err) + { + sendto_one(target_p, ":%s NOTICE %s :*** Sorry, IP cloaking " + "does not support IPv6 users!", me.name, target_p->name); + vhost_ipv6_err = 1; + } + } + else +#endif + set_vhost(client_p, target_p, target_p); + } + + return NULL; + } + + return pass_callback(prev_umode, client_p, target_p, what, flag); +} + +static void +module_init(void) +{ + if (!user_modes['h']) + { + unsigned int all_umodes = 0, i; + + for (i = 0; i < 128; i++) + all_umodes |= user_modes[i]; + + for (umode_vhost = 1; umode_vhost && (all_umodes & umode_vhost); + umode_vhost <<= 1); + + if (!umode_vhost) + { + ilog(LOG_TYPE_IRCD, "You have more than 32 usermodes, " + "IP cloaking not installed"); + sendto_realops_flags(UMODE_ALL, L_ALL, "You have more than " + "32 usermodes, IP cloaking not installed"); + return; + } + + user_modes['h'] = umode_vhost; + assemble_umode_buffer(); + } + else + { + ilog(LOG_TYPE_IRCD, "Usermode +h already in use, IP cloaking not installed"); + sendto_realops_flags(UMODE_ALL, L_ALL, "Usermode +h already in use, " + "IP cloaking not installed"); + return; + } + + prev_enter_umode = install_hook(entering_umode_cb, reset_ipv6err_flag); + prev_umode = install_hook(umode_cb, h_set_user_mode); +} + +static void +module_exit(void) +{ + if (umode_vhost) + { + dlink_node *ptr; + + DLINK_FOREACH(ptr, local_client_list.head) + { + struct Client *cptr = ptr->data; + cptr->umodes &= ~umode_vhost; + } + + user_modes['h'] = 0; + assemble_umode_buffer(); + + uninstall_hook(entering_umode_cb, reset_ipv6err_flag); + uninstall_hook(umode_cb, h_set_user_mode); + } +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_change.c b/contrib/m_change.c new file mode 100644 index 0000000..b81b137 --- /dev/null +++ b/contrib/m_change.c @@ -0,0 +1,267 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_change.c: Allows changing user/host/real of connected clients. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "irc_string.h" +#include "numeric.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "conf.h" +#include "log.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "s_user.h" +#include "hash.h" +#include "userhost.h" +#include "channel_mode.h" + + +static void +mo_chgident(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + + if (MyClient(source_p) && !HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "CHGIDENT"); + return; + } + + if (EmptyString(parv[2])) + { + parv[2] = parv[1]; + target_p = source_p; + + if (!IsClient(target_p)) + return; + } + else { + target_p = hash_find_client(parv[1]); + + if (target_p == NULL || !IsClient(target_p)) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, parv[1]); + return; + } + } + + if (strlen(parv[2]) > USERLEN || !*parv[2] || !valid_username(parv[2])) + { + sendto_one(source_p, ":%s NOTICE %s :Invalid username", + me.name, source_p->name); + return; + } + + if (IsUserHostIp(target_p)) + delete_user_host(target_p->username, target_p->host, !MyConnect(target_p)); + + strlcpy(target_p->username, parv[2], sizeof(target_p->username)); + + add_user_host(target_p->username, target_p->host, !MyConnect(target_p)); + SetUserHost(target_p); + + if (MyClient(source_p)) + { + sendto_server(client_p, NOCAPS, NOCAPS, ":%s ENCAP * CHGIDENT %s %s", + source_p->name, target_p->name, parv[2]); + sendto_one(source_p, ":%s NOTICE %s :%s changed to %s@%s", + me.name, source_p->name, target_p->name, target_p->username, + target_p->host); + } + + if (MyClient(target_p)) + { + if (IsClient(source_p)) + sendto_one(target_p, ":%s NOTICE %s :You are now %s@%s", + me.name, target_p->name, target_p->username, target_p->host); + + clear_ban_cache_client(target_p); + } +} + +static void +mo_chghost(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + + if (MyClient(source_p) && !HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "CHGHOST"); + return; + } + + if (EmptyString(parv[2])) + { + parv[2] = parv[1]; + target_p = source_p; + + if (!IsClient(target_p)) + return; + } + else { + target_p = hash_find_client(parv[1]); + + if (target_p == NULL || !IsClient(target_p)) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, parv[1]); + return; + } + } + + if (strlen(parv[2]) > HOSTLEN || !*parv[2] || !valid_hostname(parv[2])) + { + sendto_one(source_p, ":%s NOTICE %s :Invalid hostname", + me.name, source_p->name); + return; + } + + if (IsUserHostIp(target_p)) + delete_user_host(target_p->username, target_p->host, !MyConnect(target_p)); + + strlcpy(target_p->host, parv[2], sizeof(target_p->host)); + SetIPSpoof(target_p); + + add_user_host(target_p->username, target_p->host, !MyConnect(target_p)); + SetUserHost(target_p); + + if (MyClient(source_p)) + { + sendto_server(client_p, NOCAPS, NOCAPS, ":%s ENCAP * CHGHOST %s %s", + source_p->name, target_p->name, parv[2]); + sendto_one(source_p, ":%s NOTICE %s :%s changed to %s@%s", + me.name, source_p->name, target_p->name, target_p->username, + target_p->host); + } + + if (MyClient(target_p)) + { + if (IsClient(source_p)) + sendto_one(target_p, ":%s NOTICE %s :You are now %s@%s", + me.name, target_p->name, target_p->username, target_p->host); + clear_ban_cache_client(target_p); + } +} + +static void +mo_chgname(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + + if (MyClient(source_p) && !HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "CHGNAME"); + return; + } + + if (EmptyString(parv[2])) + { + parv[2] = parv[1]; + target_p = source_p; + } + else if ((target_p = hash_find_client(parv[1])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, parv[1]); + return; + } + + if (strlen(parv[2]) > REALLEN || !*parv[2]) + { + sendto_one(source_p, ":%s NOTICE %s :Invalid realname", + me.name, source_p->name); + return; + } + + if (parc > 3 && MyClient(source_p)) + sendto_one(source_p, ":%s NOTICE %s :Warning -- too many parameters " + "for CHGNAME. You are probably missing a : before the new " + "IRC name.", me.name, source_p->name); + + strlcpy(target_p->info, parv[2], sizeof(target_p->info)); + + if (MyClient(source_p)) + { + sendto_server(client_p, NOCAPS, NOCAPS, ":%s ENCAP * CHGNAME %s :%s", + source_p->name, target_p->name, parv[2]); + sendto_one(source_p, ":%s NOTICE %s :%s realname changed to [%s]", + me.name, source_p->name, target_p->name, target_p->info); + } + + if (MyClient(target_p) && IsClient(source_p)) + sendto_one(target_p, ":%s NOTICE %s :Your realname is now [%s]", + me.name, target_p->name, target_p->info); +} + +static struct Message chgident_msgtab = { + "CHGIDENT", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, mo_chgident, mo_chgident, mo_chgident, m_ignore} +}; + +static struct Message chghost_msgtab = { + "CHGHOST", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, mo_chghost, mo_chghost, mo_chghost, m_ignore} +}; + +static struct Message chgname_msgtab = { + "CHGNAME", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, mo_chgname, mo_chgname, mo_chgname, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&chgident_msgtab); + mod_add_cmd(&chghost_msgtab); + mod_add_cmd(&chgname_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&chgname_msgtab); + mod_del_cmd(&chghost_msgtab); + mod_del_cmd(&chgident_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_clearchan.c b/contrib/m_clearchan.c new file mode 100644 index 0000000..e818fa3 --- /dev/null +++ b/contrib/m_clearchan.c @@ -0,0 +1,269 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_clearchan.c: Performs a channel takeover + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "log.h" +#include "s_serv.h" +#include "send.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "hash.h" +#include "parse.h" +#include "modules.h" +#include "conf.h" + + +static void kick_list(struct Client *, struct Channel *); +static void remove_our_modes(struct Channel *); +static void remove_a_mode(struct Channel *, int, char); + + +/* +** mo_clearchan +** parv[0] = sender prefix +** parv[1] = channel +*/ +static void +mo_clearchan(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Channel *chptr = NULL; + + /* admins only */ + if (!HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + + if ((chptr = hash_find_channel(parv[1])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, parv[1]); + return; + } + + if (IsMember(source_p, chptr)) + { + sendto_one(source_p, ":%s NOTICE %s :*** Please part %s before using CLEARCHAN", + me.name, source_p->name, chptr->chname); + return; + } + + sendto_wallops_flags(UMODE_WALLOP, &me, "CLEARCHAN called for [%s] by %s!%s@%s", + chptr->chname, source_p->name, source_p->username, source_p->host); + sendto_server(NULL, NOCAPS, NOCAPS, + ":%s WALLOPS :CLEARCHAN called for [%s] by %s!%s@%s", + me.name, chptr->chname, source_p->name, source_p->username, + source_p->host); + ilog(LOG_TYPE_IRCD, "CLEARCHAN called for [%s] by %s!%s@%s", + chptr->chname, source_p->name, source_p->username, source_p->host); + + /* + * Kill all the modes we have about the channel.. + * making everyone a peon + */ + remove_our_modes(chptr); + + /* SJOIN the user to give them ops, and lock the channel */ + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s JOIN %lu %s +ntsi", + source_p->id, (unsigned long)(chptr->channelts - 1), + chptr->chname); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s SJOIN %lu %s +ntsi :@%s", + me.name, (unsigned long)(chptr->channelts - 1), + chptr->chname, source_p->name); + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN %s", + source_p->name, source_p->username, + source_p->host, chptr->chname); + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s +o %s", + me.name, chptr->chname, source_p->name); + + + /* + * Take the TS down by 1, so we don't see the channel taken over + * again. + */ + if (chptr->channelts) + --chptr->channelts; + + chptr->mode.mode = MODE_SECRET | MODE_TOPICLIMIT | + MODE_INVITEONLY | MODE_NOPRIVMSGS; + + set_channel_topic(chptr, "", "", 0); + chptr->mode.key[0] = '\0'; + + /* Kick the users out and join the oper */ + kick_list(source_p, chptr); +} + +static void +kick_list(struct Client *source_p, struct Channel *chptr) +{ + dlink_node *ptr = NULL, *ptr_next = NULL; + struct Membership *ms = NULL; + + DLINK_FOREACH(ptr, chptr->members.head) + { + ms = ptr->data; + + sendto_channel_local(ALL_MEMBERS, 0, chptr, + ":%s!%s@%s KICK %s %s CLEARCHAN", + source_p->name, source_p->username, + source_p->host, chptr->chname, ms->client_p->name); + sendto_server(NULL, NOCAPS, NOCAPS, + ":%s KICK %s %s :CLEARCHAN", source_p->name, + chptr->chname, ms->client_p->name); + } + + add_user_to_channel(chptr, source_p, CHFL_CHANOP, 0); + + DLINK_FOREACH_SAFE(ptr, ptr_next, chptr->members.head) + { + ms = ptr->data; + + if (ms->client_p != source_p) + remove_user_from_channel(ms); + } + + /* + * Join the user themselves to the channel down here, so they dont see a nicklist + * or people being kicked + */ + sendto_one(source_p, ":%s!%s@%s JOIN %s", + source_p->name, source_p->username, + source_p->host, chptr->chname); + channel_member_names(source_p, chptr, 1); +} + +/* remove_our_modes() + * + * inputs - hide from ops or not int flag + * - pointer to channel to remove modes from + * - client pointer + * output - NONE + * side effects - Go through the local members, remove all their + * chanop modes etc., this side lost the TS. + */ +static void +remove_our_modes(struct Channel *chptr) +{ + remove_a_mode(chptr, CHFL_CHANOP, 'o'); +#ifdef HALFOPS + remove_a_mode(chptr, CHFL_HALFOP, 'h'); +#endif + remove_a_mode(chptr, CHFL_VOICE, 'v'); + + /* Clear all +beI modes */ + free_channel_list(&chptr->banlist); + free_channel_list(&chptr->exceptlist); + free_channel_list(&chptr->invexlist); +} + +/* remove_a_mode() + * + * inputs - + * output - NONE + * side effects - remove ONE mode from a channel + */ +static void +remove_a_mode(struct Channel *chptr, int mask, char flag) +{ + const dlink_node *ptr = NULL; + char lmodebuf[MODEBUFLEN]; + const char *lpara[4] = { "", "", "", "" }; + char *mbuf = lmodebuf; + int count = 0; + + *mbuf++ = '-'; + + DLINK_FOREACH(ptr, chptr->members.head) + { + struct Membership *ms = ptr->data; + if ((ms->flags & mask) == 0) + continue; + + ms->flags &= ~mask; + + lpara[count++] = ms->client_p->name; + + *mbuf++ = flag; + + if (count == 4) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s %s %s %s %s %s", + me.name, chptr->chname, lmodebuf, lpara[0], + lpara[1], lpara[2], lpara[3]); + + mbuf = lmodebuf; + *mbuf++ = '-'; + count = 0; + lpara[0] = lpara[1] = lpara[2] = lpara[3] = ""; + } + } + + if (count != 0) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s %s %s %s %s %s", + me.name, chptr->chname, lmodebuf, lpara[0], + lpara[1], lpara[2], lpara[3]); + } +} + +static struct Message clearchan_msgtab = { + "CLEARCHAN", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_clearchan, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&clearchan_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&clearchan_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_ctrace.c b/contrib/m_ctrace.c new file mode 100644 index 0000000..629b7a4 --- /dev/null +++ b/contrib/m_ctrace.c @@ -0,0 +1,197 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_ctrace.c: Traces a given class + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "s_bsd.h" +#include "conf.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" + +static void do_ctrace(struct Client *, int, char *[]); +static void report_this_status(struct Client *, struct Client *); + + +/* +** mo_ctrace +** parv[0] = sender prefix +** parv[1] = classname +*/ +static void +mo_ctrace(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "CTRACE"); + return; + } + + do_ctrace(source_p, parc, parv); +} + +/* + * do_ctrace + */ +static void +do_ctrace(struct Client *source_p, int parc, char *parv[]) +{ + char *class_looking_for = parv[1]; + const char *class_name = NULL; + dlink_node *ptr; + + sendto_realops_flags(UMODE_SPY, L_ALL, + "CTRACE requested by %s (%s@%s) [%s]", + source_p->name, source_p->username, + source_p->host, source_p->servptr->name); + + /* report all direct connections */ + DLINK_FOREACH(ptr, local_client_list.head) + { + struct Client *target_p = ptr->data; + + class_name = get_client_class(target_p); + if ((class_name != NULL) && match(class_looking_for, class_name)) + report_this_status(source_p, target_p); + } + + sendto_one(source_p, form_str(RPL_ENDOFTRACE), me.name, + source_p->name, class_looking_for); +} + +/* + * report_this_status + * + * inputs - pointer to client to report to + * - pointer to client to report about + * output - counter of number of hits + * side effects - NONE + */ +static void +report_this_status(struct Client *source_p, struct Client *target_p) +{ + const char *name = NULL; + const char *class_name = NULL; + + name = get_client_name(target_p, HIDE_IP); + class_name = get_client_class(target_p); + + switch(target_p->status) + { + case STAT_CLIENT: + + if ((HasUMode(source_p, UMODE_OPER) && + (MyClient(source_p) || !HasUMode(target_p, UMODE_INVISIBLE))) + || HasUMode(target_p, UMODE_OPER)) + { + if (HasUMode(target_p, UMODE_ADMIN) && !ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + HasUMode(source_p, UMODE_ADMIN) ? target_p->sockhost : "255.255.255.255", + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else if (HasUMode(target_p, UMODE_OPER)) + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost, + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + else + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEUSER), + me.name, source_p->name, class_name, name, + IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost, + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else + sendto_one(source_p, form_str(RPL_TRACEUSER), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + } + break; + case STAT_SERVER: + if (!HasUMode(source_p, UMODE_ADMIN)) + name = get_client_name(target_p, MASK_IP); + + sendto_one(source_p, form_str(RPL_TRACESERVER), + me.name, source_p->name, class_name, 0, + 0, name, *(target_p->serv->by) ? + target_p->serv->by : "*", "*", + me.name, CurrentTime - target_p->localClient->lasttime); + break; + + default: /* ...we actually shouldn't come here... --msa */ + sendto_one(source_p, form_str(RPL_TRACENEWTYPE), me.name, + source_p->name, name); + break; + } +} + +static struct Message ctrace_msgtab = { + "CTRACE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_ctrace, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&ctrace_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&ctrace_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_force.c b/contrib/m_force.c new file mode 100644 index 0000000..9e8265b --- /dev/null +++ b/contrib/m_force.c @@ -0,0 +1,329 @@ +/* contrib/m_force.c + * Copyright (C) 2002, 2003, 2004, 2005 Hybrid Development Team + * + * 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.The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "irc_string.h" +#include "numeric.h" +#include "fdlist.h" +#include "hash.h" +#include "s_bsd.h" +#include "conf.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "channel.h" +#include "channel_mode.h" + + +/* m_forcejoin() + * parv[0] = sender prefix + * parv[1] = user to force + * parv[2] = channel to force them into + */ +static void +mo_forcejoin(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + struct Channel *chptr = NULL; + unsigned int type = 0; + char mode = '\0'; + char sjmode = '\0'; + char *newch = NULL; + dlink_node *ptr = NULL; + + if (!HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + + if ((target_p = hash_find_client(parv[1])) == NULL || !IsClient(target_p)) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, parv[1]); + return; + } + + if (!MyConnect(target_p)) + { + if (target_p->from != client_p) + { + if (IsCapable(target_p->from, CAP_ENCAP)) + sendto_one(target_p, ":%s ENCAP %s FORCEJOIN %s %s", + source_p->name, target_p->from->name, + target_p->name, parv[2]); + else + sendto_one(target_p, ":%s FORCEJOIN %s %s", + source_p->name, target_p->name, parv[2]); + } + + return; + } + + /* select our modes from parv[2] if they exist... (chanop)*/ + switch (*parv[2]) + { + case '@': + type = CHFL_CHANOP; + mode = 'o'; + sjmode = '@'; + parv[2]++; + break; +#ifdef HALFOPS + case '%': + type = CHFL_HALFOP; + mode = 'h'; + sjmode = '%'; + parv[2]++; + break; +#endif + case '+': + type = CHFL_VOICE; + mode = 'v'; + sjmode = '+'; + parv[2]++; + break; + default: + type = 0; + mode = sjmode = '\0'; /* make sure sjmode is 0. sjoin depends on it */ + break; + } + + if ((chptr = hash_find_channel(parv[2])) != NULL) + { + if (IsMember(target_p, chptr)) + { + sendto_one(source_p, ":%s NOTICE %s :*** Notice -- %s is already in %s", + me.name, source_p->name, target_p->name, chptr->chname); + return; + } + + add_user_to_channel(chptr, target_p, type, 0); + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN :%s", + target_p->name, target_p->username, + target_p->host, chptr->chname); + + if (sjmode) + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s +%c %s", + me.name, chptr->chname, mode, target_p->name); + + if (chptr->chname[0] == '#') + { + if (sjmode) + { + DLINK_FOREACH (ptr, serv_list.head) + { + struct Client *serv_p = ptr->data; + if (serv_p == target_p->from || IsDead(serv_p)) + continue; + + sendto_one(serv_p, ":%s SJOIN %lu %s + :%c%s", + ID_or_name(&me, serv_p), (unsigned long)chptr->channelts, + chptr->chname, (sjmode == '%' && + !IsCapable(serv_p, CAP_HOPS)) ? '@' : sjmode, + ID_or_name(target_p, serv_p)); + } + } + else + { + sendto_server(target_p, CAP_TS6, NOCAPS, + ":%s SJOIN %lu %s + :%s", + me.id, (unsigned long)chptr->channelts, + chptr->chname, target_p->id); + sendto_server(target_p, NOCAPS, CAP_TS6, + ":%s SJOIN %lu %s + :%s", + me.name, (unsigned long)chptr->channelts, + chptr->chname, target_p->name); + } + } + + if (chptr->topic[0]) + { + sendto_one(target_p, form_str(RPL_TOPIC), + me.name, target_p->name, + chptr->chname, chptr->topic); + sendto_one(target_p, form_str(RPL_TOPICWHOTIME), + me.name, target_p->name, chptr->chname, + chptr->topic_info, chptr->topic_time); + } + + target_p->localClient->last_join_time = CurrentTime; + channel_member_names(target_p, chptr, 1); + } + else + { + newch = parv[2]; + + if (!check_channel_name(newch, 1)) + { + sendto_one(source_p, form_str(ERR_BADCHANNAME), + me.name, source_p->name, newch); + return; + } + + chptr = make_channel(newch); + add_user_to_channel(chptr, target_p, CHFL_CHANOP, 0); + + sendto_server(target_p, CAP_TS6, NOCAPS, + ":%s SJOIN %lu %s +nt :@%s", + me.id, (unsigned long)chptr->channelts, + chptr->chname, ID(target_p)); + sendto_server(target_p, NOCAPS, CAP_TS6, + ":%s SJOIN %lu %s +nt :@%s", + me.name, (unsigned long)chptr->channelts, + chptr->chname, target_p->name); + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN :%s", + target_p->name, target_p->username, + target_p->host, chptr->chname); + + chptr->mode.mode |= MODE_TOPICLIMIT | MODE_NOPRIVMSGS; + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s +nt", + me.name, chptr->chname); + + target_p->localClient->last_join_time = CurrentTime; + channel_member_names(target_p, chptr, 1); + + /* we do this to let the oper know that a channel was created, this will be + * seen from the server handling the command instead of the server that + * the oper is on. + */ + sendto_one(source_p, ":%s NOTICE %s :*** Notice -- Creating channel %s", + me.name, source_p->name, chptr->chname); + } +} + +static void +mo_forcepart(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + struct Channel *chptr = NULL; + struct Membership *member = NULL; + + if (!HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + + /* if target_p == NULL then let the oper know */ + if ((target_p = hash_find_client(parv[1])) == NULL || !IsClient(target_p)) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, parv[1]); + return; + } + + if (!MyConnect(target_p)) + { + if (target_p->from != client_p) + { + if (IsCapable(target_p->from, CAP_ENCAP)) + sendto_one(target_p, ":%s ENCAP %s FORCEPART %s %s", + source_p->name, target_p->from->name, + target_p->name, parv[2]); + else + sendto_one(target_p, ":%s FORCEPART %s %s", + source_p->name, target_p->name, parv[2]); + } + + return; + } + + if ((chptr = hash_find_channel(parv[2])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, parv[2]); + return; + } + + if ((member = find_channel_link(target_p, chptr)) == NULL) + { + sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL), + me.name, source_p->name, chptr->chname, target_p->name); + return; + } + + sendto_server(target_p, CAP_TS6, NOCAPS, + ":%s PART %s :%s", ID(target_p), + chptr->chname, target_p->name); + sendto_server(target_p, NOCAPS, CAP_TS6, + ":%s PART %s :%s", target_p->name, + chptr->chname, target_p->name); + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s PART %s :%s", + target_p->name, target_p->username, + target_p->host, chptr->chname, + target_p->name); + remove_user_from_channel(member); +} + +static struct Message forcejoin_msgtab = { + "FORCEJOIN", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + { m_ignore, m_not_oper, mo_forcejoin, mo_forcejoin, mo_forcejoin, m_ignore } +}; + +static struct Message forcepart_msgtab = { + "FORCEPART", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + { m_ignore, m_not_oper, mo_forcepart, mo_forcepart, mo_forcepart, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&forcejoin_msgtab); + mod_add_cmd(&forcepart_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&forcejoin_msgtab); + mod_del_cmd(&forcepart_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_ltrace.c b/contrib/m_ltrace.c new file mode 100644 index 0000000..4f165da --- /dev/null +++ b/contrib/m_ltrace.c @@ -0,0 +1,341 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_ltrace.c: Traces a path to a client/server. + * + * Copyright (C) 2002 Hybrid 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 + * + * $Id$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "s_serv.h" +#include "conf.h" +#include "send.h" +#include "parse.h" +#include "modules.h" + +static void do_ltrace(struct Client *, int, char *[]); +static void report_this_status(struct Client *, struct Client *, int); + + +static void +trace_get_dependent(int *const server, + int *const client, const struct Client *target_p) +{ + const dlink_node *ptr = NULL; + + (*server)++; + (*client) += dlink_list_length(&target_p->serv->client_list); + + DLINK_FOREACH(ptr, target_p->serv->server_list.head) + trace_get_dependent(server, client, ptr->data); +} + +/* + * m_ltrace() + * + * parv[0] = sender prefix + * parv[1] = target client/server to trace + */ +static void +m_ltrace(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *tname = NULL; + + if (parc > 1) + tname = parv[1]; + else + tname = me.name; + sendto_one(source_p, form_str(RPL_ENDOFTRACE), + me.name, source_p->name, tname); +} + +/* + * do_ltrace + */ +static void +do_ltrace(struct Client *source_p, int parc, char *parv[]) +{ + struct Client *target_p = NULL; + int doall; + int wilds, dow; + dlink_node *ptr; + char *looking_for = parv[0]; + char *tname = parc > 1 ? parv[1] : me.name; + + switch (hunt_server(source_p->from, source_p, ":%s LTRACE :%s", 1,parc,parv)) + { + case HUNTED_PASS: /* note: gets here only if parv[1] exists */ + { + struct Client *ac2ptr = NULL; + + if ((ac2ptr = hash_find_client(tname)) == NULL) + DLINK_FOREACH(ptr, global_client_list.head) + { + ac2ptr = ptr->data; + + if (match(tname, ac2ptr->name)) + break; + else + ac2ptr = NULL; + } + + if (ac2ptr != NULL) + sendto_one(source_p, form_str(RPL_TRACELINK), me.name, looking_for, + ircd_version, tname, ac2ptr->from->name); + else + sendto_one(source_p, form_str(RPL_TRACELINK), me.name, looking_for, + ircd_version, tname, "ac2ptr_is_NULL!!"); + return; + } + case HUNTED_ISME: + break; + default: + return; + } + + sendto_realops_flags(UMODE_SPY, L_ALL, + "LTRACE requested by %s (%s@%s) [%s]", + source_p->name, source_p->username, + source_p->host, source_p->servptr->name); + + doall = (parv[1] && (parc > 1)) ? match(tname, me.name) : 1; + wilds = !parv[1] || strchr(tname, '*') || strchr(tname, '?'); + dow = wilds || doall; + + /* lusers cant issue ltrace.. */ + if (!dow) + { + const char* name; + const char* class_name; + + target_p = hash_find_client(tname); + + if (target_p && IsClient(target_p)) + { + name = get_client_name(target_p, HIDE_IP); + class_name = get_client_class(target_p); + + if (HasUMode(target_p, UMODE_OPER)) + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + } + + sendto_one(source_p, form_str(RPL_ENDOFTRACE), + me.name, source_p->name, tname); + return; + } + + /* report all opers */ + DLINK_FOREACH(ptr, local_client_list.head) + { + target_p = ptr->data; + + if (!HasUMode(target_p, UMODE_OPER)) + continue; + + if (!doall && wilds && !match(tname, target_p->name)) + continue; + + if (!dow && irccmp(tname, target_p->name)) + continue; + + report_this_status(source_p, target_p, dow); + } + + /* report all servers */ + DLINK_FOREACH(ptr, serv_list.head) + { + target_p = ptr->data; + + if (!doall && wilds && !match(tname, target_p->name)) + continue; + if (!dow && irccmp(tname, target_p->name)) + continue; + + report_this_status(source_p, target_p, dow); + } + + sendto_one(source_p, form_str(RPL_ENDOFTRACE), me.name, parv[0], tname); +} + +/* + * mo_ltrace + * parv[0] = sender prefix + * parv[1] = servername + */ +static void +mo_ltrace(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (!HasUMode(source_p, UMODE_OPER)) + { + sendto_one(source_p, form_str(RPL_ENDOFTRACE), me.name, parv[0], + parc > 1 ? parv[1] : me.name); + return; + } + + if (parc > 2) + if (hunt_server(client_p, source_p, ":%s LTRACE %s :%s", 2, parc, parv)) + return; + + do_ltrace(source_p, parc, parv); +} + +/* + * report_this_status + * + * inputs - pointer to client to report to + * - pointer to client to report about + * output - counter of number of hits + * side effects - NONE + */ +static void +report_this_status(struct Client *source_p, struct Client *target_p, + int dow) +{ + const char *name = NULL; + const char *class_name = NULL; + + name = get_client_name(target_p, HIDE_IP); + class_name = get_client_class(target_p); + + switch (target_p->status) + { + case STAT_CONNECTING: + sendto_one(source_p, form_str(RPL_TRACECONNECTING), me.name, + source_p->name, class_name, + HasUMode(source_p, UMODE_ADMIN) ? name : target_p->name); + break; + + case STAT_HANDSHAKE: + sendto_one(source_p, form_str(RPL_TRACEHANDSHAKE), me.name, + source_p->name, class_name, + HasUMode(source_p, UMODE_ADMIN) ? name : target_p->name); + break; + + case STAT_CLIENT: + if (HasUMode(target_p, UMODE_ADMIN)) + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + HasUMode(source_p, UMODE_ADMIN) ? target_p->sockhost : + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + else if (HasUMode(target_p, UMODE_OPER)) + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + me.name, source_p->name, class_name, name, + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + break; + + case STAT_SERVER: + { + int clients = 0; + int servers = 0; + + trace_get_dependent(&servers, &clients, target_p); + + if (!HasUMode(source_p, UMODE_ADMIN)) + name = get_client_name(target_p, MASK_IP); + + sendto_one(source_p, form_str(RPL_TRACESERVER), + me.name, source_p->name, class_name, servers, + clients, name, *(target_p->serv->by) ? + target_p->serv->by : "*", "*", + me.name, CurrentTime - target_p->localClient->lasttime); + break; + } + + case STAT_ME: + case STAT_UNKNOWN: + break; + + default: /* ...we actually shouldn't come here... --msa */ + sendto_one(source_p, form_str(RPL_TRACENEWTYPE), me.name, + source_p->name, name); + break; + } +} + +static struct Message ltrace_msgtab = { + "LTRACE", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_ltrace, mo_ltrace, m_ignore, mo_ltrace, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(<race_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(<race_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_ojoin.c b/contrib/m_ojoin.c new file mode 100644 index 0000000..e0ff868 --- /dev/null +++ b/contrib/m_ojoin.c @@ -0,0 +1,173 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_ojoin.c: Allows opers join channels with @%+ modes + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "irc_string.h" +#include "hash.h" +#include "s_serv.h" +#include "modules.h" +#include "channel_mode.h" +#include "parse.h" + + +/* mo_ojoin() + * parv[0] = sender prefix + * parv[1] = channels separated by commas + */ +static void +mo_ojoin(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Channel *chptr = NULL; + const char *prefix = ""; + char modeletter = '\0'; + char *name = parv[1]; + char *t = NULL; + unsigned int flags = 0; + dlink_node *ptr; + + /* admins only */ + if (!HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + + for (name = strtoken(&t, name, ","); name; + name = strtoken(&t, NULL, ",")) + { + switch (*name) + { + case '@': + prefix = "@"; + flags = CHFL_CHANOP; + modeletter = 'o'; + ++name; + break; +#ifdef HALFOPS + case '%': + prefix = "%"; + flags = CHFL_HALFOP; + modeletter = 'h'; + ++name; + break; +#endif + case '+': + prefix = "+"; + flags = CHFL_VOICE; + modeletter = 'v'; + ++name; + break; + case '#': + prefix = ""; + flags = 0; + modeletter = '\0'; + break; + + default: + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, name); + continue; + } + + /* Error checking here */ + if ((chptr = hash_find_channel(name)) == NULL) + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, name); + else if (IsMember(source_p, chptr)) + sendto_one(source_p, ":%s NOTICE %s :Please part %s before using OJOIN", + me.name, source_p->name, name); + else + { + add_user_to_channel(chptr, source_p, flags, 0); + + DLINK_FOREACH(ptr, serv_list.head) + { + struct Client *serv_p = ptr->data; + + sendto_one(serv_p, ":%s SJOIN %lu %s + :%s%s", ID_or_name(&me, serv_p), + (unsigned long)chptr->channelts, chptr->chname, + (*prefix == '%' && !IsCapable(serv_p, CAP_HOPS)) ? + "@" : prefix, ID_or_name(source_p, serv_p)); + } + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN %s", + source_p->name, source_p->username, + source_p->host, + chptr->chname); + + if (modeletter != '\0') + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s +%c %s", + me.name, chptr->chname, modeletter, source_p->name); + + /* send the topic... */ + if (chptr->topic[0]) + { + sendto_one(source_p, form_str(RPL_TOPIC), + me.name, source_p->name, chptr->chname, + chptr->topic); + sendto_one(source_p, form_str(RPL_TOPICWHOTIME), + me.name, source_p->name, chptr->chname, + chptr->topic_info, chptr->topic_time); + } + + source_p->localClient->last_join_time = CurrentTime; + channel_member_names(source_p, chptr, 1); + } + } +} + +static struct Message ojoin_msgtab = { + "OJOIN", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_ojoin, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&ojoin_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&ojoin_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_operspy.c b/contrib/m_operspy.c new file mode 100644 index 0000000..9fdf0c1 --- /dev/null +++ b/contrib/m_operspy.c @@ -0,0 +1,641 @@ +/************************************************************************ + * IRC - Internet Relay Chat, contrib/m_operspy.c + * Copyright (C) 2002 William Bierman III and the Hybrid 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 1, 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. + * + * $Id$ + */ + +/*** PLEASE READ ME ***/ +/* + * This module gives an extraordinary amount of power to the opers + * who have the access to use it. It allows for users' privacy to + * be pretty much obliterated. The Hybrid Team assumes absolutely + * no responsibility for this file's (mis)use. + * + * - billy-jon + */ + +#include "stdinc.h" +#include "list.h" +#include "irc_string.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "ircd.h" +#include "sprintf_irc.h" +#include "numeric.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "conf.h" +#include "log.h" +#include "s_serv.h" +#include "s_misc.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "hash.h" + +/* enable logging of OPERSPY functions */ +#define OPERSPY_LOG + +/* enable this to log all local/remote operspy usage to a logfile */ +#define OPERSPY_LOGFILE + +/* enable this to send incoming operspy usage to connected +y (UMODE_SPY) opers */ +#define OPERSPY_NOTICE + +/* enable OPERSPY version of LIST */ +#define OPERSPY_LIST + +/* enable OPERSPY version of MODE */ +#define OPERSPY_MODE + +/* enable OPERSPY version of NAMES */ +#define OPERSPY_NAMES + +/* enable OPERSPY version of WHO */ +#define OPERSPY_WHO + +/* enable OPERSPY version of WHOIS */ +#define OPERSPY_WHOIS + +/* enable OPERSPY version of TOPIC */ +#define OPERSPY_TOPIC + +#define IsOperspy(x) (HasUMode(x, UMODE_OPER) && MyClient(x) && HasUMode(x, UMODE_ADMIN)) + +/* extensions for OPERSPY WHO */ +static void do_who(struct Client *, struct Client *, char *, const char *); +static void who_global(struct Client *, char *, int); +static void do_who_on_channel(struct Client *, struct Channel *, char *); + +static void operspy_list(struct Client *, int, char *[]); +static void operspy_mode(struct Client *, int, char *[]); +static void operspy_names(struct Client *, int, char *[]); +static void operspy_topic(struct Client *, int, char *[]); +static void operspy_who(struct Client *, int, char *[]); +static void operspy_whois(struct Client *, int, char *[]); +#ifdef OPERSPY_LOG +static void operspy_log(struct Client *, const char *, const char *); +#endif + + +static const struct operspy_s { + const char *const cmd; + void (*const func_p)(struct Client *, int, char *[]); +} operspy_table[] = { +#ifdef OPERSPY_LIST + { "LIST", operspy_list }, +#endif +#ifdef OPERSPY_MODE + { "MODE", operspy_mode }, +#endif +#ifdef OPERSPY_NAMES + { "NAMES", operspy_names }, +#endif +#ifdef OPERSPY_TOPIC + { "TOPIC", operspy_topic }, +#endif +#ifdef OPERSPY_WHO + { "WHO", operspy_who }, +#endif +#ifdef OPERSPY_WHOIS + { "WHOIS", operspy_whois }, +#endif + { NULL, NULL } +}; + +static void +ms_operspy(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ +#ifdef OPERSPY_LOG + operspy_log(source_p, parv[1], parv[2]); +#endif +} + +/* mo_operspy() + * parv[1] = operspy command + * parv[2] = command parameter + */ +static void +mo_operspy(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char cmdbuf[IRCD_BUFSIZE] = "<NONE>"; /* in case everything is undef'd */ + size_t bcnt = 0; + const struct operspy_s *optr = NULL; + + if (!IsOperspy(client_p)) + { + sendto_one(client_p, form_str(ERR_NOPRIVILEGES), + me.name, client_p->name); + return; + } + + assert(client_p == source_p); + + for (optr = operspy_table; optr->cmd; ++optr) + { + if (!irccmp(optr->cmd, parv[1])) + { + (*optr->func_p)(client_p, parc, parv); + return; + } + } + + for (optr = operspy_table; optr->cmd; ++optr) + { + /* str*cat is slow and sucks */ + bcnt += strlcpy(cmdbuf+bcnt, optr->cmd, sizeof(cmdbuf)-bcnt); + if ((optr + 1)->cmd != NULL && bcnt < (sizeof(cmdbuf)-2)) + { + cmdbuf[bcnt++] = ','; + cmdbuf[bcnt++] = ' '; + } + } + + sendto_one(client_p, ":%s NOTICE %s :%s is not a valid option. Choose from %s", + me.name, client_p->name, parv[1], cmdbuf); +} + +static void +operspy_list(struct Client *client_p, int parc, char *parv[]) +{ + const dlink_node *ptr = NULL; +#ifdef OPERSPY_LOG + operspy_log(client_p, "LIST", parv[2]); +#endif + + if (*parv[2] == '\0') + return; + + sendto_one(client_p, form_str(RPL_LISTSTART), + me.name, client_p->name); + + DLINK_FOREACH(ptr, global_channel_list.head) + { + const struct Channel *chptr_list = ptr->data; + + if (match_chan(parv[2], chptr_list->chname)) + { + sendto_one(client_p, form_str(RPL_LIST), me.name, client_p->name, + chptr_list->chname, dlink_list_length(&chptr_list->members), + chptr_list->topic); + } + } + + sendto_one(client_p, form_str(RPL_LISTEND), + me.name, client_p->name); +} + +static void +operspy_mode(struct Client *client_p, int parc, char *parv[]) +{ + /* needed to preserve actual client status */ + int c_status = 0; + char modebuf[MODEBUFLEN]; + char parabuf[MODEBUFLEN]; + struct Channel *chptr_mode = NULL; + + if ((chptr_mode = hash_find_channel(parv[2])) == NULL) + { + /* + * according to m_mode.c, the channel *could* exist on the uplink still, + * but I don't see how. Even if it does, we won't be able to spy without + * info. + */ + sendto_one(client_p, form_str(ERR_NOSUCHCHANNEL), + me.name, client_p->name, parv[2]); + return; + } + +#ifdef OPERSPY_LOG + operspy_log(client_p, "MODE", parv[2]); +#endif + + /* + * XXX - this is a dirty nasty kludge to trick channel_modes() + * into giving us the key + */ + c_status = client_p->status; + client_p->status = STAT_SERVER; + + channel_modes(chptr_mode, client_p, modebuf, parabuf); + client_p->status = c_status; + + sendto_one(client_p, form_str(RPL_CHANNELMODEIS), + me.name, client_p->name, parv[2], modebuf, parabuf); + sendto_one(client_p, form_str(RPL_CREATIONTIME), + me.name, client_p->name, parv[2], chptr_mode->channelts); +} + +static void +operspy_names(struct Client *client_p, int parc, char *parv[]) +{ + /* as with mode, must preserve channel modes */ + struct Channel *chptr_names = NULL; + + if ((chptr_names = hash_find_channel(parv[2])) == NULL) + { + sendto_one(client_p, form_str(ERR_NOSUCHCHANNEL), + me.name, client_p->name, parv[2]); + return; + } + +#ifdef OPERSPY_LOG + operspy_log(client_p, "NAMES", parv[2]); +#endif + + /* + * the way to go with this, rather than temporarily setting -sp, + * is to temporarily add our client to the member list. then + * we can also list +i users. an unfortunate side-effect of this + * is that your nickname shows up in the list. for now, there is + * no easy way around it. + */ + if (IsMember(client_p, chptr_names)) + channel_member_names(client_p, chptr_names, 1); + else + { + add_user_to_channel(chptr_names, client_p, CHFL_CHANOP, 0); + channel_member_names(client_p, chptr_names, 1); + remove_user_from_channel(find_channel_link(client_p, chptr_names)); + } +} + +static void +operspy_topic(struct Client *client_p, int parc, char *parv[]) +{ + const struct Channel *chptr_topic = NULL; + + if ((chptr_topic = hash_find_channel(parv[2])) == NULL) + { + sendto_one(client_p, form_str(ERR_NOSUCHCHANNEL), + me.name, client_p->name, parv[2]); + return; + } + +#ifdef OPERSPY_LOG + operspy_log(client_p, "TOPIC", parv[2]); +#endif + + if (chptr_topic->topic[0] == '\0') + sendto_one(client_p, form_str(RPL_NOTOPIC), + me.name, client_p->name, parv[2]); + else + { + sendto_one(client_p, form_str(RPL_TOPIC), me.name, client_p->name, + chptr_topic->chname, chptr_topic->topic); + sendto_one(client_p, form_str(RPL_TOPICWHOTIME), me.name, + client_p->name, chptr_topic->chname, chptr_topic->topic_info, + chptr_topic->topic_time); + } +} + +static void +operspy_who(struct Client *client_p, int parc, char *parv[]) +{ + char *mask = parc > 2 ? parv[2] : NULL; + int server_oper = parc > 3 ? (*parv[3] == 'o') : 0; + struct Channel *chptr_who = NULL; + struct Client *target_p_who = NULL; + + if (mask != NULL) + { + collapse(mask); + + if (*mask == '\0') + { + sendto_one(client_p, form_str(RPL_ENDOFWHO), + me.name, client_p->name, "*"); + return; + } + } + else + { +#ifdef OPERSPY_LOG + operspy_log(client_p, "WHO", "*"); +#endif + who_global(client_p, NULL, server_oper); + sendto_one(client_p, form_str(RPL_ENDOFWHO), + me.name, client_p->name, "*"); + return; + } + + /* /who #channel */ + if (IsChanPrefix(*mask)) + { + if ((chptr_who = hash_find_channel(mask)) != NULL) + { +#ifdef OPERSPY_LOG + operspy_log(client_p, "WHO", mask); +#endif + do_who_on_channel(client_p, chptr_who, chptr_who->chname); + } + + sendto_one(client_p, form_str(RPL_ENDOFWHO), + me.name, client_p->name, mask); + return; + } + + /* /who nick */ + if ((target_p_who = find_person(client_p, mask)) != NULL) + { +#ifdef OPERSPY_LOG + /* "nick!user@host server\0" */ + char nuh[NICKLEN + 1 + USERLEN + 1 + HOSTLEN + 1 + HOSTLEN + 1]; + + snprintf(nuh, sizeof(nuh), "%s!%s@%s %s", target_p_who->name, + target_p_who->username, target_p_who->host, + target_p_who->servptr->name); + operspy_log(client_p, "WHO", nuh); +#endif + + if (target_p_who->channel.head != NULL) + { + chptr_who = + ((struct Membership *)target_p_who->channel.head->data)->chptr; + + do_who(client_p, target_p_who, chptr_who->chname, + get_member_status(target_p_who->channel.head->data, 0)); + } + else + do_who(client_p, target_p_who, NULL, ""); + + sendto_one(client_p, form_str(RPL_ENDOFWHO), + me.name, client_p->name, mask); + return; + } + +#ifdef OPERSPY_LOG + operspy_log(client_p, "WHO", parv[2]); +#endif + + /* /who 0 */ + if (!strcmp(mask, "0")) + who_global(client_p, NULL, server_oper); + else + who_global(client_p, mask, server_oper); + + /* nothing else? end of /who. */ + sendto_one(client_p, form_str(RPL_ENDOFWHO), + me.name, client_p->name, mask); +} + +static void +operspy_whois(struct Client *client_p, int parc, char *parv[]) +{ + const dlink_node *lp; + struct Channel *chptr_whois = NULL; + struct Client *a2client_p; + struct Client *target_p = NULL; + char buf[IRCD_BUFSIZE]; +#ifdef OPERSPY_LOG + /* "nick!user@host server\0" */ + char nuh[NICKLEN + 1 + USERLEN + 1 + HOSTLEN + 1 + HOSTLEN + 1]; +#endif + char *t = NULL; + int mlen, tlen; + int cur_len = 0; + int reply_to_send = 0; + + if (has_wildcards(parv[2])) + { + sendto_one(client_p, ":%s NOTICE %s :Do not use wildcards with this.", + me.name, client_p->name); + return; + } + + if ((target_p = find_person(client_p, parv[2])) == NULL) + { + sendto_one(client_p, form_str(ERR_NOSUCHNICK), + me.name, client_p->name, parv[2]); + return; + } + +#ifdef OPERSPY_LOG + snprintf(nuh, sizeof(nuh), "%s!%s@%s %s", + target_p->name, target_p->username, target_p->host, + target_p->servptr->name); + operspy_log(client_p, "WHOIS", nuh); +#endif + + a2client_p = target_p->servptr; + + sendto_one(client_p, form_str(RPL_WHOISUSER), me.name, + client_p->name, target_p->name, target_p->username, + target_p->host, target_p->info); + mlen = ircsprintf(buf, form_str(RPL_WHOISCHANNELS), me.name, + client_p->name, target_p->name, ""); + cur_len = mlen; + t = buf + mlen; + + DLINK_FOREACH(lp, target_p->channel.head) + { + chptr_whois = ((struct Membership *)lp->data)->chptr; + + if ((cur_len + strlen(chptr_whois->chname) + 2) > (IRCD_BUFSIZE - 4)) + { + sendto_one(client_p, "%s", buf); + cur_len = mlen; + t = buf + mlen; + } + + tlen = ircsprintf(t, "%s%s%s ", + ShowChannel(client_p, chptr_whois) ? "" : "%", + get_member_status((struct Membership *)lp->data, 1), + chptr_whois->chname); + t += tlen; + cur_len += tlen; + reply_to_send = 1; + } + + if (reply_to_send == 1) + sendto_one(client_p, "%s", buf); + + sendto_one(client_p, form_str(RPL_WHOISSERVER), me.name, + client_p->name, target_p->name, a2client_p->name, + a2client_p->info); + + if (HasUMode(target_p, UMODE_OPER)) + sendto_one(client_p, form_str(HasUMode(target_p, UMODE_ADMIN) ? RPL_WHOISADMIN : + RPL_WHOISOPERATOR), me.name, client_p->name, target_p->name); + + if (MyConnect(target_p)) + sendto_one(client_p, form_str(RPL_WHOISIDLE), me.name, + client_p->name, target_p->name, + CurrentTime - target_p->localClient->last_privmsg, + target_p->localClient->firsttime); + sendto_one(client_p, form_str(RPL_ENDOFWHOIS), + me.name, client_p->name, parv[2]); +} + +/* extensions for OPERSPY WHO */ +static void +do_who(struct Client *source_p, struct Client *target_p, + char *chname, const char *op_flags) +{ + char status[8]; + + snprintf(status, sizeof(status), "%c%s%s", target_p->away[0] ? 'G' : 'H', + HasUMode(target_p, UMODE_OPER) ? "*" : "", op_flags); + sendto_one(source_p, form_str(RPL_WHOREPLY), me.name, source_p->name, + (chname) ? (chname) : "*", + target_p->username, + target_p->host, target_p->servptr->name, target_p->name, + status, target_p->hopcount, target_p->info); +} + +static void +who_global(struct Client *source_p, char *mask, int server_oper) +{ + struct Client *target_p; + dlink_node *lp; + int maxmatches = 500; + + /* list all matching visible clients */ + DLINK_FOREACH(lp, global_client_list.head) + { + target_p = lp->data; + + if (!IsClient(target_p)) + continue; + + if (server_oper && !HasUMode(target_p, UMODE_OPER)) + continue; + + if (!mask || + match(mask, target_p->name) || match(mask, target_p->username) || + match(mask, target_p->host) || match(mask, target_p->servptr->name) || + match(mask, target_p->info) || + (MyClient(target_p) && match(mask, target_p->sockhost))) + { + if (dlink_list_length(&target_p->channel)) + { + struct Channel *chptr; + static char fl[5]; + + chptr = ((struct Membership *)(target_p->channel.head->data))->chptr; + snprintf(fl, sizeof(fl), "%s", + get_member_status((struct Membership *)(target_p->channel.head->data), 0)); + + do_who(source_p, target_p, chptr->chname, fl); + } + else + do_who(source_p, target_p, NULL, ""); + + if (maxmatches > 0) + { + if (--maxmatches == 0) + return; + } + } + } +} + +static void +do_who_on_channel(struct Client *source_p, struct Channel *chptr, + char *chname) +{ + dlink_node *ptr; + struct Membership *ms; + + DLINK_FOREACH(ptr, chptr->members.head) + { + ms = ptr->data; + do_who(source_p, ms->client_p, chname, get_member_status(ms, 0)); + } +} + +#ifdef OPERSPY_LOG +static void +operspy_log(struct Client *source_p, const char *command, const char *target) +{ + struct ConfItem *conf = NULL; +#ifdef OPERSPY_LOGFILE + FILE *operspy_fb; + dlink_node *cnode; + const char *opername = source_p->name; + char linebuf[IRCD_BUFSIZE], logfile[IRCD_BUFSIZE]; +#endif + + assert(source_p != NULL); + +#ifdef OPERSPY_LOGFILE + if (HasUMode(source_p, UMODE_OPER) && MyClient(source_p)) + { + DLINK_FOREACH(cnode, source_p->localClient->confs.head) + { + conf = cnode->data; + + if (conf->type == OPER_TYPE) + opername = conf->name; + } + } + else if (!MyClient(source_p)) + opername = "remote"; + + snprintf(logfile, sizeof(logfile), "%s/operspy.%s.log", LOGPATH, opername); + if ((operspy_fb = fopen(logfile, "a")) == NULL) + return; + + snprintf(linebuf, sizeof(linebuf), "[%s] OPERSPY %s %s %s\n", + smalldate(CurrentTime), + get_oper_name(source_p), + command, target); + fputs(linebuf, operspy_fb); + fclose(operspy_fb); +#endif + +#ifdef OPERSPY_NOTICE + sendto_realops_flags(UMODE_SPY, L_ALL, "OPERSPY %s %s %s", + get_oper_name(source_p), command, target); +#endif + + if (MyClient(source_p)) + sendto_match_servs(source_p, "*", CAP_ENCAP, "ENCAP * OPERSPY %s :%s", + command, target); +} +#endif /* OPERSPY_LOG */ + +static struct Message operspy_msgtab = { + "OPERSPY", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + {m_ignore, m_not_oper, ms_operspy, ms_operspy, mo_operspy, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&operspy_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&operspy_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_opme.c b/contrib/m_opme.c new file mode 100644 index 0000000..4b5517a --- /dev/null +++ b/contrib/m_opme.c @@ -0,0 +1,150 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_opme.c: Regains ops on opless channels + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "log.h" +#include "s_serv.h" +#include "send.h" +#include "irc_string.h" +#include "hash.h" +#include "parse.h" +#include "modules.h" + + +static int +chan_is_opless(const struct Channel *const chptr) +{ + const dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, chptr->members.head) + if (((struct Membership *)ptr->data)->flags & CHFL_CHANOP) + return 0; + + return 1; +} + +/* + * mo_opme() + * parv[0] = sender prefix + * parv[1] = channel + */ +static void +mo_opme(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Channel *chptr = NULL; + struct Membership *member = NULL; + + if (!HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + + if ((chptr = hash_find_channel(parv[1])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, parv[1]); + return; + } + + if ((member = find_channel_link(source_p, chptr)) == NULL) + { + sendto_one(source_p, form_str(ERR_NOTONCHANNEL), + me.name, source_p->name, chptr->chname); + return; + } + + if (!chan_is_opless(chptr)) + { + sendto_one(source_p, ":%s NOTICE %s :%s Channel is not opless", + me.name, source_p->name, chptr->chname); + return; + } + + AddMemberFlag(member, CHFL_CHANOP); + + sendto_wallops_flags(UMODE_WALLOP, &me, "OPME called for [%s] by %s!%s@%s", + chptr->chname, source_p->name, source_p->username, + source_p->host); + sendto_server(NULL, NOCAPS, NOCAPS, + ":%s WALLOPS :OPME called for [%s] by %s!%s@%s", + me.name, chptr->chname, source_p->name, source_p->username, + source_p->host); + + ilog(LOG_TYPE_IRCD, "OPME called for [%s] by %s!%s@%s", + chptr->chname, source_p->name, source_p->username, + source_p->host); + + sendto_server(NULL, CAP_TS6, NOCAPS, + ":%s PART %s", ID(source_p), chptr->chname); + sendto_server(NULL, NOCAPS, CAP_TS6, + ":%s PART %s", source_p->name, chptr->chname); + + sendto_server(NULL, CAP_TS6, NOCAPS, + ":%s SJOIN %lu %s + :@%s", + me.id, (unsigned long)chptr->channelts, + chptr->chname, ID(source_p)); + sendto_server(NULL, NOCAPS, CAP_TS6, + ":%s SJOIN %lu %s + :@%s", + me.name, (unsigned long)chptr->channelts, + chptr->chname, source_p->name); + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s +o %s", + me.name, chptr->chname, source_p->name); +} + +static struct Message opme_msgtab = { + "OPME", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_opme, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&opme_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&opme_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/contrib/m_webirc.c b/contrib/m_webirc.c new file mode 100644 index 0000000..72d688b --- /dev/null +++ b/contrib/m_webirc.c @@ -0,0 +1,208 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_webirc.c: Makes CGI:IRC users appear as coming from their real host + * + * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center + * Copyright (C) 2002-2006 ircd-ratbox development team + * Copyright (C) 1996-2012 Hybrid 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 + * + * $Id$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "irc_string.h" +#include "hash.h" +#include "parse.h" +#include "modules.h" +#include "conf.h" +#include "hostmask.h" + +/* + * Usage: + * + * auth { + * user = "webirc@<cgiirc ip>"; # if identd used, put ident username instead + * password = "<password>"; # encryption possible + * spoof = "webirc." + * class = "users"; + * encrypted = yes; # [Using encryption is highly recommended] + * }; + * + * Possible flags: + * kline_exempt - k/g lines on the cgiirc ip are ignored + * gline_exempt - glines on the cgiirc ip are ignored + * + * dlines are checked on the cgiirc ip (of course). + * k/d/g/x lines, auth blocks, user limits, etc are checked using the + * real host/ip. + * + * The password should be specified unencrypted in webirc_password in + * cgiirc.config + */ + +static int +invalid_hostname(const char *hostname) +{ + const char *p = hostname; + unsigned int has_sep = 0; + + assert(p != NULL); + + if (*p == '.' || *p == ':') + return 1; + + for (; *p; ++p) + { + if (!IsHostChar(*p)) + return 1; + if (*p == '.' || *p == ':') + ++has_sep; + } + + return !has_sep; +} + +/* + * mr_webirc + * parv[0] = sender prefix + * parv[1] = password + * parv[2] = fake username (we ignore this) + * parv[3] = fake hostname + * parv[4] = fake ip + */ +static void +mr_webirc(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) +{ + struct AccessItem *aconf = NULL; + struct ConfItem *conf = NULL; + struct addrinfo hints, *res; + + assert(source_p == client_p); + + if (invalid_hostname(parv[4])) + { + sendto_one(source_p, ":%s NOTICE %s :CGI:IRC: Invalid IP", me.name, + source_p->name[0] ? source_p->name : "*"); + return; + } + + aconf = find_address_conf(source_p->host, + IsGotId(source_p) ? source_p->username : "webirc", + &source_p->localClient->ip, + source_p->localClient->aftype, parv[1]); + if (aconf == NULL || !IsConfClient(aconf)) + return; + + conf = unmap_conf_item(aconf); + + if (!IsConfDoSpoofIp(aconf) || irccmp(conf->name, "webirc.")) + { + sendto_one(source_p, ":%s NOTICE %s :Not a CGI:IRC auth block", me.name, + source_p->name[0] ? source_p->name : "*"); + return; + } + + if (EmptyString(aconf->passwd)) + { + sendto_one(source_p, ":%s NOTICE %s :CGI:IRC auth blocks must have a password", + me.name, source_p->name[0] ? source_p->name : "*"); + return; + } + + if (!match_conf_password(parv[1], aconf)) + { + sendto_one(source_p, ":%s NOTICE %s :CGI:IRC password incorrect", + me.name, source_p->name[0] ? source_p->name : "*"); + return; + } + + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + + if (getaddrinfo(parv[4], NULL, &hints, &res)) + { + + sendto_one(source_p, ":%s NOTICE %s :Invalid CGI:IRC IP %s", me.name, + source_p->name[0] ? source_p->name : "*", parv[4]); + return; + } + + assert(res != NULL); + + memcpy(&source_p->localClient->ip, res->ai_addr, res->ai_addrlen); + source_p->localClient->ip.ss_len = res->ai_addrlen; + source_p->localClient->ip.ss.ss_family = res->ai_family; + source_p->localClient->aftype = res->ai_family; + freeaddrinfo(res); + + strlcpy(source_p->sockhost, parv[4], sizeof(source_p->sockhost)); + + if (strlen(parv[3]) <= HOSTLEN) + strlcpy(source_p->host, parv[3], sizeof(source_p->host)); + else + strlcpy(source_p->host, source_p->sockhost, sizeof(source_p->host)); + + /* Check dlines now, k/glines will be checked on registration */ + if ((aconf = find_dline_conf(&client_p->localClient->ip, + client_p->localClient->aftype))) + { + if (!(aconf->status & CONF_EXEMPTDLINE)) + { + exit_client(client_p, &me, "D-lined"); + return; + } + } + + sendto_one(source_p, ":%s NOTICE %s :CGI:IRC host/IP set to %s %s", me.name, + source_p->name[0] ? source_p->name : "*", parv[3], parv[4]); +} + +static struct Message webirc_msgtab = { + "WEBIRC", 0, 0, 5, 0, MFLG_SLOW, 0, + { mr_webirc, m_ignore, m_ignore, m_ignore, m_ignore, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&webirc_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&webirc_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; @@ -0,0 +1,780 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2012-07-12.20; # UTC + +# Copyright (C) 1999-2012 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' "$nl" < "$tmpdepfile" | +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependent.h'. + # Do two passes, one to just change these to + # '$object: dependent.h' and one to simply 'dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'. + # However on + # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\': + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + # tcc 0.9.26 (FIXME still under development at the moment of writing) + # will emit a similar output, but also prepend the continuation lines + # with horizontal tabulation characters. + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form 'foo.o: dependent.h', + # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'. + # Do two passes, one to just change these to + # '$object: dependent.h' and one to simply 'dependent.h:'. + sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \ + < "$tmpdepfile" > "$depfile" + sed ' + s/[ '"$tab"'][ '"$tab"']*/ /g + s/^ *// + s/ *\\*$// + s/^[^:]*: *// + /^$/d + /:$/d + s/$/ :/ + ' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + base=`echo "$source" | sed -e 's|^.*/||' -e 's/\.[-_a-zA-Z0-9]*$//'` + tmpdepfile="$base.d" + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir="$base.d-lock" + trap "echo '$0: caught signal, cleaning up...' >&2; rm -rf $lockdir" 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0 ; do + # mkdir is a portable test-and-set. + if mkdir $lockdir 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rm -rf $lockdir + break + else + ## the lock is being held by a different process, + ## wait until the winning process is done or we timeout + while test -d $lockdir && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test "$stat" = 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' "$nl" < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/doc/CIDR.txt b/doc/CIDR.txt new file mode 100644 index 0000000..e17098a --- /dev/null +++ b/doc/CIDR.txt @@ -0,0 +1,316 @@ +$Id$ + +CIDR Information +---------------- + Presently, we all use IPv4. The format of IPv4 is the following: + +A.B.C.D + + Where letters 'A' through 'D' are 8-bit values. In English, this + means each digit can have a value of 0 to 255. Example: + +129.56.4.234 + + Digits are called octets. Oct meaning 8, hence 8-bit values. An + octet cannot be greater than 255, and cannot be less than 0 (eg. a + negative number). + + CIDR stands for "classless inter domain routing", details covered + in RFC's 1518 and 1519. It was introduced mainly due to waste within + A and B classes space. The goal was to make it possible to use + smaller nets than it would seem from (above) IP classes, for instance + by dividing one B class into 256 "C like" classes. The other goal was + to allow aggregation of routing information, so that routers could use + one aggregated route (like 194.145.96.0/20) instead of + advertising 16 C classes. + + Class A are all these addresses which first bit is "0", + bitmap: 0nnnnnnn.hhhhhhhh.hhhhhhhh.hhhhhhhh (n=net, h=host) + IP range is 0.0.0.0 - 127.255.255.255 + + Class B are all these addresses which first two bits are "10", + bitmap: 10nnnnnn.nnnnnnnn.hhhhhhhh.hhhhhhhh (n=net, h=host) + IP range is 128.0.0.0 - 191.255.255.255 + + Class C are all these addresses which first three bits are "110", + bitmap: 110nnnnn.nnnnnnnn.nnnnnnnn.hhhhhhhh (n=net, h=host) + IP range is 192.0.0.0 - 223.255.255.255 + + Class D are all these addresses which first four bits are "1110", + this is multicast class and net/host bitmap doesn't apply here + IP range is 224.0.0.0 - 239.255.255.255 + I bet they will never IRC, unless someone creates multicast IRC :) + + Class E are all these addresses which first five bits are "11110", + this class is reserved for future use + IP range is 240.0.0.0 - 247.255.255.255 + + So, here is how CIDR notation comes into play. + + For those of you who have real basic exposure to how networks are + set up, you should be aware of the term "netmask." Basically, this + is a IPv4 value which specifies the "size" of a network. You can + assume the word "size" means "range" if you want. + + A chart describing the different classes in CIDR format and their + wildcard equivalents would probably help at this point: + +CIDR version dot notation (netmask) Wildcard equivalent +----------------------------------------------------------------- +A.0.0.0/8 A.0.0.0/255.0.0.0 A.*.*.* or A.* +A.B.0.0/16 A.B.0.0/255.255.0.0 A.B.*.* or A.B.* +A.B.C.0/24 A.B.C.0/255.255.255.0 A.B.C.* or A.B.C.* +A.B.C.D/32 A.B.C.D/255.255.255.255 A.B.C.D + + + The question on any newbies mind at this point is "So what do all + of those values & numbers actually mean?" + + Everything relating to computers is based on binary values (1s and + zeros). Binary plays a *tremendous* role in CIDR notation. Let's + break it down to the following table: + + A B C D + -------- -------- -------- -------- +/8 == 11111111 . 00000000 . 00000000 . 00000000 == 255.0.0.0 +/16 == 11111111 . 11111111 . 00000000 . 00000000 == 255.255.0.0 +/24 == 11111111 . 11111111 . 11111111 . 00000000 == 255.255.255.0 +/32 == 11111111 . 11111111 . 11111111 . 11111111 == 255.255.255.255 + + The above is basically a binary table for the most common netblock + sizes. The "1"s you see above are the 8-bit values for each octet. + If you split an 8-bit value into each of it's bits, you find the + following: + +00000000 +^^^^^^^^_ 1sts place (1) +|||||||__ 2nds place (2) +||||||___ 3rds place (4) +|||||____ 4ths place (8) +||||_____ 5ths place (16) +|||______ 6ths place (32) +||_______ 7ths place (64) +|________ 8ths place (128) + + Now, since computers consider zero a number, you pretty much have + to subtract one (so-to-speak; this is not really how its done, but + just assume it's -1 :-) ) from all the values possible. Some + examples of decimal values in binary: + +15 == 00001111 (from left to right: 8+4+2+1) +16 == 00010000 (from left to right: 16) +53 == 00110101 (from left to right: 32+16+4+1) +79 == 01001111 (from left to right: 64+8+4+1) +254 == 11111110 (from left to right: 128+64+32+16+8+4+2) + + So, with 8 bits, the range (as I said before) is zero to 255. + + If none of this is making sense to you at this point, you should + back up and re-read all of the above. I realize it's a lot, but + it'll do you some good to re-read it until you understand :-). + + So, let's modify the original table a bit by providing CIDR info + for /1 through /8: + + A B C D + -------- -------- -------- -------- +/1 == 10000000 . 00000000 . 00000000 . 00000000 == 128.0.0.0 +/2 == 11000000 . 00000000 . 00000000 . 00000000 == 192.0.0.0 +/3 == 11100000 . 00000000 . 00000000 . 00000000 == 224.0.0.0 +/4 == 11110000 . 00000000 . 00000000 . 00000000 == 240.0.0.0 +/5 == 11111000 . 00000000 . 00000000 . 00000000 == 248.0.0.0 +/6 == 11111100 . 00000000 . 00000000 . 00000000 == 252.0.0.0 +/7 == 11111110 . 00000000 . 00000000 . 00000000 == 254.0.0.0 +/8 == 11111111 . 00000000 . 00000000 . 00000000 == 255.0.0.0 + + At this point, all of this should making a lot of sense, and you + should be able to see the precision that you can get by using CIDR + at this point. If not, well, I guess the best way to put it would + be that wildcards always assume /8, /16, or /24 (yes hello Piotr, + we can argue this later: I am referring to IPs *ONLY*, not domains + or FQDNs :-) ). + + This table will provide a reference to all of the IPv4 CIDR values + +cidr|netmask (dot notation) +----+--------------------- +/1 | 128.0.0.0 +/2 | 192.0.0.0 +/3 | 224.0.0.0 +/4 | 240.0.0.0 +/5 | 248.0.0.0 +/6 | 252.0.0.0 +/7 | 254.0.0.0 +/8 | 255.0.0.0 +/9 | 255.128.0.0 +/10 | 255.192.0.0 +/11 | 255.224.0.0 +/12 | 255.240.0.0 +/13 | 255.248.0.0 +/14 | 255.252.0.0 +/15 | 255.254.0.0 +/16 | 255.255.0.0 +/17 | 255.255.128.0 +/18 | 255.255.192.0 +/19 | 255.255.224.0 +/20 | 255.255.240.0 +/21 | 255.255.248.0 +/22 | 255.255.252.0 +/23 | 255.255.254.0 +/24 | 255.255.255.0 +/25 | 255.255.255.128 +/26 | 255.255.255.192 +/27 | 255.255.255.224 +/28 | 255.255.255.240 +/29 | 255.255.255.248 +/30 | 255.255.255.252 +/31 | 255.255.255.254 +/32 | 255.255.255.255 + + So, let's take all of the information above, and apply it to a + present-day situation on IRC. + + Let's say you have a set of flooding clients who all show up from + the following hosts. For lack-of a better example, I'll use a + subnet here at Best: + +nick1 (xyz@shell9.ba.best.com) [206.184.139.140] +nick2 (abc@shell8.ba.best.com) [206.184.139.139] +nick3 (foo@shell12.ba.best.com) [206.184.139.143] + + Most people will assume the they were all in the same class C + (206.184.139.0/24 or 206.184.139.*). + + This, as a matter of fact, is not true. Now, the reason *I* know + this is solely because I work on the network here; those IPs are + not delegated to a class C, but two portions of a class C (128 IPs + each). That means the class C is actually split into these two + portions: + +Netblock IP range +-------- -------- +206.184.139.0/25 206.184.139.0 to 206.184.139.127 +206.184.139.128/25 206.184.139.128 to 206.184.139.255 + + For the record, 206.184.139.0 and 206.184.139.128 are both known as + "network addresses" (not to be confused with "netblocks" or "Ethernet + hardware addresses" or "MAC addresses"). Network addresses are + *ALWAYS EVEN*. + + 206.184.139.127 and 206.184.139.255 are what are known as broadcast + addresses. Broadcast addresses are *ALWAYS ODD*. + + Now, the aforementioned list of clients are in the 2nd subnet shown + above, not the first. The reason for this should be obvious. + + The remaining question is, "Well that's nice, you know what the netblock + is for Best. What about us? We don't know that!" + + Believe it or not, you can find out the network block size by using + whois -h WHOIS.ARIN.NET on the IP in question. ARIN keeps a list of + all network blocks and who owns them -- quite useful, trust me. I + think I use ARIN 5 or 6 times a day, especially when dealing with + D-lines. Example: + +$ whois -h whois.arin.net 206.184.139.140 +Best Internet Communications, Inc. (NETBLK-NBN-206-184-BEST) +345 East Middlefield Road +Mountain View, CA 94043 + +Netname: NBN-206-184-BEST +Netblock: 206.184.0.0 - 206.184.255.255 +Maintainer: BEST + + Does this mean you should D-line 206.184.0.0/16? Probably not. + That's an entire class B-sized block, while you're only trying + to deny access to a subnetted class C. + + So then how do you get the *real* info? Well, truth is, you don't. + You have to pretty much take a guess at what it is, if ARIN reports + something that's overly vague. Best, for example, was assigned the + above class B-sized block. We can subnet it however we want without + reporting back to ARIN how we have it subnetted. We own the block, + and that's all that matters (to ARIN). + + Not all subnets are like this, however. Smaller subnets you may + find partitioned and listed on ARIN; I've seen /29 blocks for DSL + customers show up in ARIN before. + + So, use ARIN any chance you get. The more precision the better! + + Now, there is a small issue I want to address regarding use of CIDR + notation. Let's say you D-line the following in CIDR format (hi + sion ;-) ): + +205.100.132.18/24 + + Entries like this really makes my blood boil, solely because it adds + excessive confusion and is just basically pointless. If you + examine the above, you'll see the /24 is specifying an entire + class C -- so then what's the purpose of using .18 versus .0? + + There IS no purpose. The netmask itself will mask out the .18 and + continue to successfully use 205.100.132.0/24. + + Doing things this way just adds confusion, especially on non-octet- + aligned subnets (such as /8, /16, /24, or /32). Seeing that on a + /27 or a /19 might make people go "wtf?" + + I know for a fact this doc lacks a lot of necessary information, + like how the actual netmask/CIDR value play a role in "masking out" + the correct size, and what to do is WHOIS.ARIN.NET returns no + netblock information but instead a few different company names with + NIC handles. I'm sure you can figure this stuff out on your own, + or just ask an administrator friend of yours who DOES know. A lot + of us admins are BOFH types, but if you ask us the right questions, + you'll benefit from the answer quite thoroughly. + + Oh, I almost forgot. Most Linux systems use a different version of + "whois" than FreeBSD does. The syntax for whois on Linux is + "whois <INFO>@whois.arin.net", while under FreeBSD it is + "whois -h whois.arin.net <INFO>" Debian uses yet another version + of whois that is incompatible with the above syntax options. + + Note that the FreeBSD whois client has shortcuts for the most commonly + used whois servers. "whois -a <INFO>" is the shortcut for ARIN. + + Also note that ARIN is not authoritative for all IP blocks on the + Internet. Take for example 212.158.123.66. A whois query to ARIN + will return the following information: + +$ whois -h whois.arin.net 212.158.123.66 +European Regional Internet Registry/RIPE NCC (NET-RIPE-NCC-) + These addresses have been further assigned to European users. + Contact information can be found in the RIPE database, via the + WHOIS and TELNET servers at whois.ripe.net, and at + http://www.ripe.net/db/whois.html + + Netname: RIPE-NCC-212 + Netblock: 212.0.0.0 - 212.255.255.255 + Maintainer: RIPE + + This query tells us that it is a European IP block, and is further + handled by RIPE's whois server. We must then query whois.ripe.net + to get more information. + +$ whois -h whois.ripe.net 212.158.123.66 + +% Rights restricted by copyright. See + http://www.ripe.net/ripencc/pub-services/db/copyright.html + +inetnum: 212.158.120.0 - 212.158.123.255 +netname: INSNET-P2P +descr: Point to Point Links for for London Nodes +country: GB +--snip-- + + This tells us the actual IP block that the query was a part of. + + Other whois servers that you may see blocks referred to are: + whois.ripn.net for Russia, whois.apnic.net for Asia, Australia, and + the Pacific, and whois.6bone.net for IPv6 blocks. + +Contributed by Jeremy Chadwick <jdc@best.net> +Piotr Kucharski <chopin@sgh.waw.pl> +W. Campbell <wcampbel@botbay.net> and +Ariel Biener <ariel@fireball.tau.ac.il> diff --git a/doc/Doxyfile b/doc/Doxyfile new file mode 100644 index 0000000..bffa83e --- /dev/null +++ b/doc/Doxyfile @@ -0,0 +1,1635 @@ +# Doxyfile 1.7.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = ircd-hybrid-8 + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc/doxygen + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command <command> <input-file>, where <command> is the value of +# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = include \ + modules \ + src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.c \ + *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = src/conf_parser.c \ + src/conf_parser.h \ + src/conf_lexer.c + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = YES + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> +# Qt Help Project / Custom Filters</a>. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> +# Qt Help Project / Filter Attributes</a>. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = YES + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = NO + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..775eb45 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,3 @@ +AUTOMAKE_OPTIONS = foreign +man_MANS = ircd.8 +dist_sysconf_DATA = example.conf example.efnet.conf diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..3002666 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,526 @@ +# Makefile.in generated by automake 1.12.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = doc +DIST_COMMON = $(dist_sysconf_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man8dir = $(mandir)/man8 +am__installdirs = "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(sysconfdir)" +NROFF = nroff +MANS = $(man_MANS) +DATA = $(dist_sysconf_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBDIR = @LIBDIR@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PREFIX = @PREFIX@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +man_MANS = ircd.8 +dist_sysconf_DATA = example.conf example.efnet.conf +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign doc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man8: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man8dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.8[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) +install-dist_sysconfDATA: $(dist_sysconf_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(sysconfdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(sysconfdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sysconfdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(sysconfdir)" || exit $$?; \ + done + +uninstall-dist_sysconfDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(sysconfdir)'; $(am__uninstall_files_from_dir) +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the 'missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically 'make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(MANS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(sysconfdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-dist_sysconfDATA + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man8 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_sysconfDATA uninstall-man + +uninstall-man: uninstall-man8 + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_sysconfDATA \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-man8 install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am uninstall uninstall-am uninstall-dist_sysconfDATA \ + uninstall-man uninstall-man8 + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/doc/challenge.txt b/doc/challenge.txt new file mode 100644 index 0000000..c50ebb2 --- /dev/null +++ b/doc/challenge.txt @@ -0,0 +1,208 @@ + Oper Challenge and Response System + + $Id$ + + Copyright (c) 2001-2012 by ircd-hybrid team + + ---------------------------------------------------------------------- + + ircd-hybrid + + In an effort to reduce the damage caused to a network by a hacked O-line, + Hybrid supports an OpenSSL based challenge-response system. This new + system allows the admin to remove all oper block passwords from the conf + file. Authentication is done through a public/private key. + + ---------------------------------------------------------------------- + + Requirements + + The ircd must be compiled with the --enable-openssl option to configure. + If configure detects a working openssl library, --enable-openssl is + implicitly enabled. + + oper {} blocks should not have normal passwords, but should contain the + the name of the private key file. However it is possible for the user to + use both challenge and normal passwords, but this would defeat the purpose + of the challenge system. + + m_challenge.la must be loaded. + + The oper has their private key file and an implementation of the RSA + Respond tool available to be run. + + ---------------------------------------------------------------------- + + Process + + Each oper should have a private key file and a public key file. The keys + can be generated with the mkkeypair utility provided in tools/. + + The oper keeps their private key file in a safe place, and gives their + public key file to their admin(s). + + The admin will place an entry for the public key file into a field called + rsa_public_key_file of each oper's oper {} block in the conf file. + + The oper wishes to obtain their operator status, and issues the CHALLENGE + command. + + The server will print out a long hexadecimal string, that needs to be fed + to the respond utility provided in tools/rsa_respond. + + The respond program will generate an answer that is fed back to the + CHALLENGE command. + + ---------------------------------------------------------------------- + + Generating the Key Files + + The keys can be generated with the openssl command as follows: + + openssl genrsa -des3(1) -out rsa.key 1024(2) + openssl rsa -in rsa.key -pubout -out rsa.pub + + + (1) + The -des3 must be included in order to create a key with a + passphrase. Omitting this option will create a non protected key. + (2) + The key size must be 1024 or below. The challenge sent for a + longer keysize will be too long to fit into the ircd's 512 byte + line constraint. + + It is highly recommended that you set a password on your private key. + + The tools/mkkeypair utility cannot be used to create a key suitable for + use in CHALLENGE. + + ---------------------------------------------------------------------- + + Using CHALLENGE and respond + + Note: All examples assume the use of the stock respond client included + with the ircd-hybrid-8 source, run on a UNIX(c) platform. + + The administrator of the server you oper on should remove the password in + your oper {} block and replace it with an entry for your public key, so + that /oper will be disabled. + + Note: The public key is a VERY long string. + + The oper will issue /challenge oper_nick, and see something like below: + + *** 56F1FDAE4C590C524CF758917E62C2A2A1376CB9C4C2E7D411BB0AD9C4A + 605A2D05A94E7254197E9D71438B5FB565B6FD35465E462305F35F4A2D45311 + F983B3E062F635912FA155B4B1E18EAA782CC107F4C9DA83092658D16A2E88A + 6BCF9820F5A044A29CDD4C062F05BF509CA3B561375CBC4179BD1CF6026BDE9 + 60E52C6B + + Note: The challenge is all on one line. + + Note: With some clients, the oper will have to issue /quote CHALLENGE + instead of /challenge. + + The oper will then have to feed that challenge to the respond program. + + +------------------------------------------------------------------+ + | The respond utility's syntax is: | + | | + |$ ./respond private_key_file challenge_from_server | + | | + | | + | Example: | + | | + |wcampbel@botbay (rsa_respond): ./respond hwy.key \ | + |56F1FDAE4C590C524CF758917E62C2A2A1376CB9C4C2E7D411BB0AD9C4A605A2D0| + |5A94E7254197E9D71438B5FB565B6FD35465E462305F35F4A2D45311F983B3E062| + |F635912FA155B4B1E18EAA782CC107F4C9DA83092658D16A2E88A6BCF9820F5A04| + |4A29CDD4C062F05BF509CA3B561375CBC4179BD1CF6026BDE960E52C6B | + |Keyphrase: | + |6B882932DD00F86123869E401F7334B9B0D0018A60F1DE244E90E47246AA87C7 | + | | + | Note: The challenge parameter must be on one line. | + +------------------------------------------------------------------+ + + The keyphrase must be entered properly to get the response. The bottom + line is the response that must be sent back to the server. + + The oper will issue the following command in order to obtain operator + status: + + /challenge + +6B882932DD00F86123869E401F7334B9B0D0018A60F1DE244E90E47246AA87C7 + + Note: The '+' is needed + + If successful, the oper will obtain operator status on the server. + + +------------------------------------------------------------------------+ + | Warning | + |------------------------------------------------------------------------| + | If the CHALLENGE fails, and you use ircII, EPIC, or BX, you may get | + | disconnected with the client asking for the server password. This is a | + | client bug, not an ircd bug. | + +------------------------------------------------------------------------+ + + ---------------------------------------------------------------------- + + RSA Respond Tool + + The RSA Respond tool is a vital part of challenge/response system. In + order to function, the operator must have must have a way to quickly issue + the respond command, and to copy and paste data to and from the IRC + client. + + The respond source code is included with the ircd-hybrid source, in the + tools/rsa_respond directory. + + A copy of the source tar file is available on + http://www.wohmart.com/ircd/pub/irc_tools/rsa/rsa_respond-src-hyb7.tar.gz + + For Windows platforms, there are two available RSA Respond tools. One is a + text only port of the stock tool. The binary is available from + http://www.wohmart.com/ircd/pub/irc_tools/rsa/rsa_respond-bin.tar.gz. + The other tool is a GUI enabled version[3]. The source tree[4] is available + from http://www.wohmart.com/ircd/pub/irc_tools/rsa/winrespond-src.tar.gz. + A binary distribution is available from + http://www.wohmart.com/ircd/pub/irc_tools/rsa/winrespond-bin.tar.gz. + + With the appropriate version of the RSA Respond tool, any operator can + protect their privileged access to the server, with little additional + effort over using standard operator passwords. + + ---------------------------------------------------------------------- + + Benefits + + The greatest benefit of using the challenge/response system is that there + are no passwords sent over the network in plaintext. There are also no + credentials left on the server side, as only public keys are kept in the + conf. The use of public/private key encryption provides far greater + security over having a single password, and may (if the key is kept + secure, and has a good passphrase) virtually eliminate hacked O-lines. + + ---------------------------------------------------------------------- + + A. Numerics + + :server 381 user :You have entered... the Twilight Zone!. + :server 386 user :challenge-text + :server 464 user :Password Incorrect + :server 491 user :Only few of mere mortals may try to enter the twilight zone + + + Note: The text used can be changed by the server administrator. + + ---------------------------------------------------------------------- + + Notes + + [1] Some platforms may require Makefile changes in order to link in the + OpenSSL library. This may change in the future. + [2] Platforms known to function include: Linux, FreeBSD, Solaris, and + Cygwin. + [3] A screenshot of the program is available on + http://www.wohmart.com/ircd/pub/irc_tools/rsa/winrespond.png . + [4] The winrespond source depends on a working, up to date, Cygwin + installation. diff --git a/doc/example.conf b/doc/example.conf new file mode 100644 index 0000000..e260214 --- /dev/null +++ b/doc/example.conf @@ -0,0 +1,1232 @@ +/* doc/example.conf - ircd-hybrid-8 Example configuration file + * Copyright (C) 2000-2012 Hybrid Development Team + * + * Written by ejb, wcampbel, db, leeh and others + * Other example configurations can be found in the source dir under + * doc/. + * + * $Id$ + */ + +/* IMPORTANT NOTES: + * + * auth {} blocks MUST be specified in order of precedence. The first one + * that matches a user will be used. So place spoofs first, then specials, + * then general access. + * + * Shell style (#), C++ style (//) and C style comments are supported. + * + * Files may be included by either: + * .include "filename" + * .include <filename> + * + * Times/durations are written as: + * 12 hours 30 minutes 1 second + * + * Valid units of time: + * month, week, day, hour, minute, second + * + * Valid units of size: + * megabyte/mbyte/mb, kilobyte/kbyte/kb, byte + * + * Sizes and times may be singular or plural. + */ + +/* EFNET NOTE: + * + * This config file is NOT suitable for EFNet. EFNet admins should use + * example.efnet.conf + */ + +/* + * serverinfo {}: contains information about the server + */ +serverinfo { + /* + * name: the name of this server. This cannot be changed at runtime. + */ + name = "hades.arpa"; + + /* + * sid: a server's unique ID. This is three characters long and must + * be in the form [0-9][A-Z0-9][A-Z0-9]. The first character must be + * a digit, followed by 2 alpha-numerical letters. + * NOTE: The letters must be capitalized. This cannot be changed at runtime. + */ + sid = "_CHANGE_ME_"; + + /* + * description: the description of the server. + */ + description = "ircd-hybrid test server"; + + /* + * network info: the name and description of the network this server + * is on. Shown in the 005 reply and used with serverhiding. + */ + network_name = "MyNet"; + network_desc = "This is My Network"; + + /* + * hub: allow this server to act as a hub and have multiple servers + * connected to it. + */ + hub = no; + + /* + * vhost: the IP to bind to when we connect outward to ipv4 servers. + * This should be an ipv4 IP only, or "*" for INADDR_ANY. + */ + #vhost = "192.169.0.1"; + + /* + * vhost6: the IP to bind to when we connect outward to ipv6 servers. + * This should be an ipv6 IP only, or "*" for INADDR_ANY. + */ + #vhost6 = "3ffe:80e8:546::2"; + + /* max_clients: the maximum number of clients allowed to connect */ + max_clients = 512; + + /* + * rsa_private_key_file: the path to the file containing our + * rsa key for cryptlink. + * + * Example command to store a 2048 bit RSA keypair in + * rsa.key, and the public key in rsa.pub: + * + * openssl genrsa -out rsa.key 2048 + * openssl rsa -in rsa.key -pubout -out rsa.pub + * chown <ircd-user>.<ircd.group> rsa.key rsa.pub + * chmod 0600 rsa.key + * chmod 0644 rsa.pub + */ + #rsa_private_key_file = "/usr/local/ircd/etc/rsa.key"; + + /* + * ssl_certificate_file: the path to the file containing our + * ssl certificate for encrypted client connection. + * + * This assumes your private RSA key is stored in rsa.key. You + * MUST have an RSA key in order to generate the certificate + * + * openssl req -new -days 365 -x509 -key rsa.key -out cert.pem + * + * See http://www.openssl.org/docs/HOWTO/certificates.txt + * + * Please use the following values when generating the cert + * + * Organization Name: Network Name + * Organization Unit Name: changme.someirc.net + * Common Name: irc.someirc.net + * E-mail: you@domain.com + */ + #ssl_certificate_file = "/usr/local/ircd/etc/cert.pem"; + + /* + * ssl_dh_param_file: + * + * Path to the PEM encoded Diffie-Hellman parameter file. + * DH parameters are strictly required when using ciphers + * with EDH (ephemeral Diffie-Hellman) key exchange. + * + * A DH parameter file can be created by running: + * + * openssl dhparam -out dhparam.pem 1024 + * + * Prime size must be at least 1024 bits. Further information + * regarding specific OpenSSL dhparam command-line options + * can be found in the OpenSSL manual. + */ + #ssl_dh_param_file = "/usr/local/ircd/etc/dhparam.pem"; + + /* + * ssl_cipher_list: + * + * List of ciphers that are supported by _this_ server. Can be used to + * enforce specific ciphers for incoming SSL/TLS connections. + * If a client (which also includes incoming server connections) isn't + * capable of any cipher listed below, the connection will simply be + * rejected. + * + * A list of supported ciphers can be obtained by running: + * + * openssl ciphers -ssl3 -tls1 -v + * + * Multiple ciphers are separated by colons. The order of preference is + * from left to right. + */ + #ssl_cipher_list = "DHE-RSA-AES256-SHA:AES256-SHA"; + + /* + * ssl_server_method: + * ssl_client_method: + * + * SSL/TLS methods we provide for incoming (server method) and + * outgoing (client method) SSL/TLS connections. + * This can be either sslv3 for SSLv3, and/or tlsv1 for TLSv1. + */ + #ssl_server_method = tlsv1, sslv3; + #ssl_client_method = tlsv1; +}; + +/* + * admin {}: contains admin information about the server + */ +admin { + name = "Smurf target"; + description = "Main Server Administrator"; + email = "<syn@packets.r.us>"; +}; + +/* + * class {}: contains information about classes for users + */ +class { + /* name: the name of the class */ + name = "users"; + + /* + * ping_time: how often a client must reply to a PING from the + * server before they are dropped. + */ + ping_time = 90 seconds; + + /* + * number_per_ip: how many local users are allowed to connect + * from one IP (optional) + */ + number_per_ip = 2; + + /* + * max_local: how many local users are allowed to connect + * from one ident@host (optional) + */ + max_local = 2; + + /* + * max_global: network-wide limit of users per ident@host (optional) + */ + max_global = 10; + + /* + * max_number: the maximum number of users allowed in this class (optional) + */ + max_number = 100; + + /* + * the following lines are optional and allow you to define + * how many users can connect from one /NN subnet + */ + cidr_bitlen_ipv4 = 24; + cidr_bitlen_ipv6 = 120; + number_per_cidr = 16; + + /* + * sendq: the amount of data allowed in a clients send queue before + * they are dropped. + */ + sendq = 100 kbytes; + + /* + * recvq: maximum amount of data in a clients receive queue before + * they are dropped for flooding. Defaults to 2560 if the chosen + * value isn't within the range of 512 to 8000. + */ + recvq = 2560 bytes; +}; + +class { + name = "opers"; + ping_time = 90 seconds; + number_per_ip = 10; + max_number = 100; + sendq = 100 kbytes; +}; + +class { + name = "server"; + ping_time = 90 seconds; + + /* + * ping_warning: how fast a server must reply to a PING before + * a warning to opers is generated. + */ + ping_warning = 15 seconds; + + /* + * connectfreq: only used in server classes. Specifies the delay + * between autoconnecting to servers. + */ + connectfreq = 5 minutes; + + /* max number: the amount of servers to autoconnect to */ + max_number = 1; + + /* sendq: servers need a higher sendq as they send more data */ + sendq = 2 megabytes; +}; + +/* + * listen {}: contains information about the ports ircd listens on + */ +listen { + /* + * port: the specific port to listen on. If no host is specified + * before, it will listen on all available IPs. + * + * Ports are separated via a comma, a range may be specified using ".." + */ + + /* port: listen on all available IPs, ports 6665 to 6669 */ + port = 6665 .. 6669; + + /* + * Listen on 192.168.0.1/6697 with ssl enabled and hidden from STATS P + * unless you are an administrator. + * + * NOTE: The "flags" directive has to come before "port". Always! + * + * Currently available flags are: + * + * ssl - Port is for SSL client connections only + * server - Only server connections are permitted + * hidden - Port is hidden from /stats P, unless you're an admin + */ + flags = hidden, ssl; + host = "192.168.0.1"; + port = 6697; + + /* + * host: set a specific IP/host the ports after the line will listen + * on. This may be ipv4 or ipv6. + */ + host = "1.2.3.4"; + port = 7000, 7001; + + host = "3ffe:1234:a:b:c::d"; + port = 7002; +}; + +/* + * auth {}: allow users to connect to the ircd + */ +auth { + /* + * user: the user@host allowed to connect. Multiple user + * lines are permitted per auth block. + */ + user = "*@172.16.0.0/12"; + user = "*test@123D:B567:*"; + + /* password: an optional password that is required to use this block */ + password = "letmein"; + + /* + * encrypted: controls whether the auth password above has been + * encrypted. + */ + encrypted = yes; + + /* + * spoof: fake the users host to this. This is free-form, + * just do everyone a favor and don't abuse it. ('=' prefix on /stats I) + */ + spoof = "I.still.hate.packets"; + + /* class: the class the user is placed in */ + class = "opers"; + + /* + * need_password - don't allow users who haven't supplied the correct + * password to connect using another auth{} block + * ('&' prefix on /stats I if disabled) + * need_ident - require the user to have identd to connect ('+' prefix on /stats I) + * spoof_notice - enable spoofing notification to admins + * exceed_limit - allow a user to exceed class limits ('>' prefix on /stats I) + * kline_exempt - exempt this user from k/glines ('^' prefix on /stats I) + * gline_exempt - exempt this user from glines ('_' prefix on /stats I) + * resv_exempt - exempt this user from resvs ('$' prefix on /stats I) + * no_tilde - remove ~ from a user with no ident ('-' prefix on /stats I) + * can_flood - allow this user to exceed flood limits ('|' prefix on /stats I) + */ + flags = need_password, spoof_notice, exceed_limit, kline_exempt, + gline_exempt, resv_exempt, no_tilde, can_flood; +}; + +auth { + /* + * redirect: the server and port to redirect a user to. A user does + * not have to obey the redirection, the ircd just suggests an alternative + * server for them. + */ + redirserv = "this.is.not.a.real.server"; + redirport = 6667; + + user = "*.server"; + + /* class: a class is required even though it is not used */ + class = "users"; +}; + +auth { + user = "*@*"; + class = "users"; + flags = need_ident; +}; + +/* + * operator {}: defines ircd operators + * + * ircd-hybrid no longer supports local operators, privileges are + * controlled via flags. + */ +operator { + /* name: the name of the oper */ + name = "sheep"; + + /* + * user: the user@host required for this operator. Multiple + * user="" lines are supported. + */ + user = "*sheep@192.168.0.0/16"; + user = "*@127.0.0.0/8"; + + /* + * password: the password required to oper. By default this will + * need to be encrypted by using the provided mkpasswd tool. + * Several password hash algorithms are available depending + * on your system's crypt() implementation. For example, a modern + * glibc already has support for SHA-256/512, and MD5 encryption + * algorithms. + */ + password = "$5$x5zof8qe.Yc7/bPp$5zIg1Le2Lsgd4CvOjaD20pr5PmcfD7ha/9b2.TaUyG4"; + + /* + * encrypted: controls whether the oper password above has been + * encrypted. + */ + encrypted = yes; + + /* + * rsa_public_key_file: the public key for this oper when using Challenge. + * A password should not be defined when this is used, see + * doc/challenge.txt for more information. + */ +# rsa_public_key_file = "/usr/local/ircd/etc/oper.pub"; + + /* class: the class the oper joins when they successfully /oper */ + class = "opers"; + + /* + * umodes: default usermodes opers get when they /oper. If defined, + * it will override oper_umodes settings in general {}. + * Available usermodes: + * + * +b - bots - See bot and drone flooding notices + * +c - cconn - Client connection/quit notices + * +C - cconn_full - Client connection/quit notices full + * +D - deaf - Don't receive channel messages + * +d - debug - See debugging notices + * +f - full - See auth{} block full notices + * +G - softcallerid - Server Side Ignore for users not on your channels + * +g - callerid - Server Side Ignore (for privmsgs etc) + * +H - hidden - Hides operator status to other users + * +i - invisible - Not shown in NAMES or WHO unless you share a + * a channel + * +j - rej - See rejected client notices + * +k - skill - See server generated KILL messages + * +l - locops - See LOCOPS messages + * +n - nchange - See client nick changes + * +s - servnotice - See general server notices + * +u - unauth - See unauthorized client notices + * +w - wallop - See server generated WALLOPS + * +x - external - See remote server connection and split notices + * +y - spy - See LINKS, STATS, TRACE notices etc. + * +z - operwall - See oper generated WALLOPS + */ +# umodes = locops, servnotice, operwall, wallop; + + /* + * privileges: controls the activities and commands an oper is + * allowed to do on the server. All options default to no. + * Available options: + * + * module - allows MODULE + * global_kill - allows remote users to be /KILL'd + * remote - allows remote SQUIT and CONNECT + * remoteban - allows remote KLINE/UNKLINE + * dline - allows DLINE + * undline - allows UNDLINE + * kline - allows KILL and KLINE + * unkline - allows UNKLINE + * gline - allows GLINE + * xline - allows XLINE + * globops - allows GLOBOPS + * operwall - allows OPERWALL + * nick_changes - allows oper to see nickchanges via usermode +n + * rehash - allows oper to REHASH config + * die - allows DIE + * restart - allows RESTART + * set - allows SET + * admin - gives admin privileges. admins for example, + * may see the real IP addresses of servers. + */ + flags = global_kill, remote, kline, unkline, xline, globops, restart, + die, rehash, nick_changes, admin, operwall, module; +}; + +/* + * service {}: specifies what server may act as a network service + * + * NOTE: it is absolutely important that every single server on the network + * has the same service{} block. + */ +service { + name = "service.someserver"; + name = "stats.someserver"; +}; + +/* + * connect {}: controls servers we connect to + */ +connect { + /* name: the name of the server */ + name = "irc.uplink.com"; + + /* + * host: the host or IP to connect to. If a hostname is used it + * must match the reverse dns of the server. + */ + host = "192.168.0.1"; + + /* + * vhost: the IP to bind to when we connect outward to servers. + * serverinfo::vhost and serverinfo::vhost6 will be overridden + * by this directive. + */ + vhost = "192.168.0.2"; + + /* + * passwords: the passwords we send (OLD C:) and accept (OLD N:). + * The remote server will have these passwords reversed. + */ + send_password = "password"; + accept_password = "anotherpassword"; + + /* + * encrypted: controls whether the accept_password above has been + * encrypted. + */ + encrypted = no; + + /* port: the port to connect to this server on */ + port = 6666; + + /* + * hub_mask: the mask of servers that this server may hub. Multiple + * entries are permitted + */ + hub_mask = "*"; + + /* + * leaf_mask: the mask of servers this server may not hub. Multiple + * entries are permitted. Useful for forbidding EU -> US -> EU routes. + */ +# leaf_mask = "*.uk"; + + /* class: the class this server is in */ + class = "server"; + + /* + * ssl_cipher_list: + * + * List of ciphers that the server we are connecting to must support. + * If the server isn't capable of any cipher listed below, the + * connection will simply be rejected. + * Can be used to enforce stronger ciphers, even though this option + * is not necessarily required to establish a SSL/TLS connection. + * + * Multiple ciphers are separated by colons. The order of preference + * is from left to right. + */ + #ssl_cipher_list = "DHE-RSA-AES256-SHA:AES256-SHA"; + + /* + * autoconn - controls whether we autoconnect to this server or not, + * dependent on class limits. By default, this is disabled. + * ssl - Initiates a TLS/SSL connection. + */ +# flags = autoconn, ssl; +}; + +connect { + name = "ipv6.some.server"; + host = "3ffd:dead:beef::1"; + send_password = "password"; + accept_password = "password"; + port = 6666; + + /* + * aftype: controls whether the connection uses "ipv4" or "ipv6". + * Default is ipv4. + */ + aftype = ipv6; + class = "server"; +}; + +/* + * cluster {}: servers that share klines/unkline/xline/unxline/resv/unresv/locops + * automatically + */ +cluster { + /* + * name: the server to share with, this can take wildcards + * + * NOTE: only local actions will be clustered, meaning if + * the server receives a shared kline/unkline/etc, it + * will not be propagated to clustered servers. + * + * Remote servers are not necessarily required to accept + * clustered lines, they need a shared{} for *THIS* server + * in order to accept them. + */ + name = "*.arpa"; + + /* + * type: list of what to share, options are as follows: + * dline - share dlines + * undline - share undlines + * kline - share klines + * unkline - share unklines + * xline - share xlines + * unxline - share unxlines + * resv - share resvs + * unresv - share unresvs + * locops - share locops + * all - share all of the above (default) + */ + type = kline, unkline, locops, xline, resv; +}; + +/* + * shared {}: users that are allowed to remote kline + * + * NOTE: This can be effectively used for remote klines. + * Please note that there is no password authentication + * for users setting remote klines. You must also be + * /oper'd in order to issue a remote kline. + */ +shared { + /* + * name: the server the user must be on to set klines. If this is not + * specified, the user will be allowed to kline from all servers. + */ + name = "irc2.some.server"; + + /* + * user: the user@host mask that is allowed to set klines. If this is + * not specified, all users on the server above will be allowed to set + * a remote kline. + */ + user = "oper@my.host.is.spoofed"; + + /* + * type: list of what to share, options are as follows: + * dline - allow oper/server to dline + * undline - allow oper/server to undline + * kline - allow oper/server to kline + * unkline - allow oper/server to unkline + * xline - allow oper/server to xline + * unxline - allow oper/server to unxline + * resv - allow oper/server to resv + * unresv - allow oper/server to unresv + * locops - allow oper/server to locops - only used for servers that cluster + * all - allow oper/server to do all of the above (default) + */ + type = kline, unkline, resv; +}; + +/* + * kill {}: users that are not allowed to connect + * Oper issued klines will be added to the specified kline config + */ +kill { + user = "bad@*.hacked.edu"; + reason = "Obviously hacked account"; +}; + +kill { + user = "^O[[:alpha:]]?[[:digit:]]+(x\.o|\.xo)$@^[[:alnum:]]{4}\.evilnet.tld$"; + + /* + * NOTE: You have to set type=regex; when using a regular expression + * based user entry + */ + type = regex; +}; + +/* + * deny {}: IPs that are not allowed to connect (before DNS/ident lookup) + * Oper issued dlines will be added to the specified dline config + */ +deny { + ip = "10.0.1.0/24"; + reason = "Reconnecting vhosted bots"; +}; + +/* + * exempt {}: IPs that are exempt from deny {} and Dlines + */ +exempt { + ip = "192.168.0.0/16"; +}; + +/* + * resv {}: nicks and channels users may not use/join + */ +resv { + /* reason: the reason for the proceeding resv's */ + reason = "Reserved for services"; + + /* resv: the nicks and channels users may not join/use */ + nick = "Global"; + nick = "DevNull"; + nick = "BotServ"; + nick = "Services"; + nick = "StatServ"; + nick = "HelpServ"; + nick = "HostServ"; + nick = "NickServ"; + nick = "ChanServ"; + nick = "MemoServ"; + nick = "OperServ"; + channel = "#services"; + + /* resv: wildcard masks are also supported in nicks only */ + reason = "Clone bots"; + nick = "clone*"; +}; + +/* + * gecos {}: The X: replacement, used for banning users based on + * their "realname". + */ +gecos { + name = "*sex*"; + reason = "Possible spambot"; +}; + +gecos { + name = "sub7server"; + reason = "Trojan drone"; +}; + +gecos { + name = "*http*"; + reason = "Spambot"; +}; + +gecos { + name = "^\[J[0o]hn Do[3e]\]-[0-9]{2,5}$"; + + /* + * NOTE: You have to set type=regex; when using a regular expression + * based name entry + */ + type = regex; +}; + +/* + * channel {}: The channel block contains options pertaining to channels + */ +channel { + /* + * disable_fake_channels: this option, if set to 'yes', will + * disallow clients to create or join channels that have one + * of the following ASCII characters in their name: + * + * 2 | bold + * 3 | mirc color + * 15 | plain text + * 22 | reverse + * 29 | italic + * 31 | underline + * 160 | non-breaking space + */ + disable_fake_channels = yes; + + /* + * restrict_channels: reverse channel RESVs logic, only reserved + * channels are allowed + */ + restrict_channels = no; + + /* + * knock_delay: The amount of time a user must wait between issuing + * the knock command. + */ + knock_delay = 5 minutes; + + /* + * knock_delay_channel: How often a knock to any specific channel + * is permitted, regardless of the user sending the knock. + */ + knock_delay_channel = 1 minute; + + /* + * max_chans_per_user: The maximum number of channels a user can + * join/be on. + */ + max_chans_per_user = 25; + + /* + * max_chans_per_oper: The maximum number of channels an oper can + * join/be on. + */ + max_chans_per_oper = 50; + + /* quiet_on_ban: stop banned people talking in channels. */ + quiet_on_ban = yes; + + /* max_bans: maximum number of +b/e/I modes in a channel */ + max_bans = 100; + + /* + * how many joins in how many seconds constitute a flood, use 0 to + * disable. +b opers will be notified (changeable via /set) + */ + join_flood_count = 16; + join_flood_time = 8 seconds; + + /* + * splitcode: The ircd will now check splitmode every few seconds. + * + * Either split users or split servers can activate splitmode, but + * both conditions must be met for the ircd to deactivate splitmode. + * + * You may force splitmode to be permanent by /quote set splitmode on + */ + + /* + * default_split_user_count: when the usercount is lower than this level, + * consider ourselves split. This must be set for automatic splitmode. + */ + default_split_user_count = 0; + + /* + * default_split_server_count: when the servercount is lower than this, + * consider ourselves split. This must be set for automatic splitmode. + */ + default_split_server_count = 0; + + /* no_create_on_split: disallow users creating channels on split. */ + no_create_on_split = yes; + + /* no_join_on_split: disallow users joining channels at all on a split. */ + no_join_on_split = no; +}; + +/* + * serverhide {}: The serverhide block contains the options regarding + * serverhiding + */ +serverhide { + /* + * flatten_links: this option will show all servers in /links appear + * that they are linked to this current server + */ + flatten_links = no; + + /* + * links_delay: how often to update the links file when it is + * flattened. + */ + links_delay = 5 minutes; + + /* + * hidden: hide this server from a /links output on servers that + * support it. This allows hub servers to be hidden etc. + */ + hidden = no; + + /* + * hide_servers: hide remote servernames everywhere and instead use + * hidden_name and network_desc. + */ + hide_servers = no; + + /* + * Use this as the servername users see if hide_servers = yes. + */ + hidden_name = "*.hidden.com"; + + /* + * hide_server_ips: If this is disabled, opers will be unable to see + * servers ips and will be shown a masked ip, admins will be shown the + * real ip. + * + * If this is enabled, nobody can see a servers ip. *This is a kludge*, + * it has the side effect of hiding the ips everywhere, including + * logfiles. + * + * We recommend you leave this disabled, and just take care with who you + * give admin=yes; to. + */ + hide_server_ips = no; +}; + +/* + * general {}: The general block contains many of the options that were once + * compiled in options in config.h. The general block is read at start time. + */ +general { + /* services_name: servername of nick/channel services */ + services_name = "service.someserver"; + + /* max_watch: maximum WATCH entries a client can have. */ + max_watch = 60; + + /* gline_enable: enable glines, network wide temp klines */ + gline_enable = yes; + + /* + * gline_duration: the amount of time a gline will remain on your + * server before expiring + */ + gline_duration = 1 day; + + /* + * gline_request_duration: how long a pending G-line can be around. + * 10 minutes should be plenty + */ + gline_request_duration = 10 minutes; + + /* + * gline_min_cidr: the minimum required length of a CIDR bitmask + * for IPv4 based glines + */ + gline_min_cidr = 16; + + /* + * gline_min_cidr6: the minimum required length of a CIDR bitmask + * for IPv6 based glines + */ + gline_min_cidr6 = 48; + + /* + * Whether to automatically set mode +i on connecting users. + */ + invisible_on_connect = yes; + + /* + * Max time from the nickname change that still causes KILL + * automatically to switch for the current nick of that user. + */ + kill_chase_time_limit = 90 seconds; + + /* + * If hide_spoof_ips is disabled, opers will be allowed to see the real + * IP of spoofed users in /trace etc. If this is defined they will be + * shown a masked IP. + */ + hide_spoof_ips = yes; + + /* + * Ignore bogus timestamps from other servers. Yes, this will desync + * the network, but it will allow chanops to resync with a valid non TS 0 + * + * This should be enabled network wide, or not at all. + */ + ignore_bogus_ts = no; + + /* + * disable_auth: completely disable ident lookups; if you enable this, + * be careful of what you set need_ident to in your auth {} blocks + */ + disable_auth = no; + + /* disable_remote_commands: disable users doing commands on remote servers */ + disable_remote_commands = no; + + /* + * tkline_expire_notices: enables or disables temporary kline/xline + * expire notices. + */ + tkline_expire_notices = no; + + /* + * default_floodcount: the default value of floodcount that is configurable + * via /quote set floodcount. This is the amount of lines a user + * may send to any other user/channel in one second. + */ + default_floodcount = 10; + + /* + * failed_oper_notice: send a notice to all opers on the server when + * someone tries to OPER and uses the wrong password, host or ident. + */ + failed_oper_notice = yes; + + /* + * dots_in_ident: the amount of '.' characters permitted in an ident + * reply before the user is rejected. + */ + dots_in_ident = 2; + + /* + * min_nonwildcard: the minimum non wildcard characters in k/d/g lines + * placed via the server. klines hand placed are exempt from limits. + * wildcard chars: '.' ':' '*' '?' '@' '!' '#' + */ + min_nonwildcard = 4; + + /* + * min_nonwildcard_simple: the minimum non wildcard characters in + * gecos bans. wildcard chars: '*' '?' '#' + */ + min_nonwildcard_simple = 3; + + /* max_accept: maximum allowed /accept's for +g usermode */ + max_accept = 20; + + /* anti_nick_flood: enable the nickflood control code */ + anti_nick_flood = yes; + + /* nick flood: the nick changes allowed in the specified period */ + max_nick_time = 20 seconds; + max_nick_changes = 5; + + /* + * anti_spam_exit_message_time: the minimum time a user must be connected + * before custom quit messages are allowed. + */ + anti_spam_exit_message_time = 5 minutes; + + /* + * ts delta: the time delta allowed between server clocks before + * a warning is given, or before the link is dropped. all servers + * should run ntpdate/rdate to keep clocks in sync + */ + ts_warn_delta = 30 seconds; + ts_max_delta = 5 minutes; + + /* + * warn_no_nline: warn opers about servers that try to connect but + * we don't have a connect {} block for. Twits with misconfigured + * servers can get really annoying with this enabled. + */ + warn_no_nline = yes; + + /* + * stats_e_disabled: set this to 'yes' to disable "STATS e" for both + * operators and administrators. Doing so is a good idea in case + * there are any exempted (exempt{}) server IPs you don't want to + * see leaked. + */ + stats_e_disabled = no; + + /* stats_o_oper only: make stats o (opers) oper only */ + stats_o_oper_only = yes; + + /* stats_P_oper_only: make stats P (ports) oper only */ + stats_P_oper_only = yes; + + /* + * stats i oper only: make stats i (auth {}) oper only. set to: + * yes: show users no auth blocks, made oper only. + * masked: show users first matching auth block + * no: show users all auth blocks. + */ + stats_i_oper_only = yes; + + /* + * stats_k_oper_only: make stats k/K (klines) oper only. set to: + * yes: show users no auth blocks, made oper only + * masked: show users first matching auth block + * no: show users all auth blocks. + */ + stats_k_oper_only = yes; + + /* + * caller_id_wait: time between notifying a +g user that somebody + * is messaging them. + */ + caller_id_wait = 1 minute; + + /* + * opers_bypass_callerid: allows operators to bypass +g and message + * anyone who has it set (useful if you use services). + */ + opers_bypass_callerid = no; + + /* + * pace_wait_simple: time between use of less intensive commands + * (ADMIN, HELP, (L)USERS, VERSION, remote WHOIS) + */ + pace_wait_simple = 1 second; + + /* + * pace_wait: time between more intensive commands + * (AWAY, INFO, LINKS, MAP, MOTD, STATS, WHO, wildcard WHOIS, WHOWAS) + */ + pace_wait = 10 seconds; + + /* + * short_motd: send clients a notice telling them to read the motd + * instead of forcing a motd to clients who may simply ignore it. + */ + short_motd = no; + + /* + * ping_cookie: require clients to respond exactly to a ping command, + * can help block certain types of drones and FTP PASV mode spoofing. + */ + ping_cookie = no; + + /* no_oper_flood: increase flood limits for opers. */ + no_oper_flood = yes; + + /* + * true_no_oper_flood: completely eliminate flood limits for opers + * and for clients with can_flood = yes in their auth {} blocks + */ + true_no_oper_flood = yes; + + /* oper_pass_resv: allow opers to over-ride RESVs on nicks/channels */ + oper_pass_resv = yes; + + /* REMOVE ME. The following line checks you've been reading. */ + havent_read_conf = 1; + + /* + * max_targets: the maximum amount of targets in a single + * PRIVMSG/NOTICE. Set to 999 NOT 0 for unlimited. + */ + max_targets = 4; + + /* + * message_locale: the default message locale + * Use "standard" for the compiled in defaults. + * To install the translated messages, go into messages/ in the + * source directory and run `make install'. + */ + message_locale = "standard"; + + /* + * usermodes configurable: a list of usermodes for the options below + * + * +b - bots - See bot and drone flooding notices + * +c - cconn - Client connection/quit notices + * +C - cconn_full - Client connection/quit notices full + * +D - deaf - Don't receive channel messages + * +d - debug - See debugging notices + * +f - full - See auth{} block full notices + * +G - softcallerid - Server Side Ignore for users not on your channels + * +g - callerid - Server Side Ignore (for privmsgs etc) + * +H - hidden - Hides operator status to other users + * +i - invisible - Not shown in NAMES or WHO unless you share a + * a channel + * +j - rej - See rejected client notices + * +k - skill - See server generated KILL messages + * +l - locops - See LOCOPS messages + * +n - nchange - See client nick changes + * +s - servnotice - See general server notices + * +u - unauth - See unauthorized client notices + * +w - wallop - See server generated WALLOPS + * +x - external - See remote server connection and split notices + * +y - spy - See LINKS, STATS, TRACE notices etc. + * +z - operwall - See oper generated WALLOPS + */ + + /* oper_only_umodes: usermodes only opers may set */ + oper_only_umodes = bots, cconn, cconn_full, debug, full, hidden, skill, + nchange, rej, spy, external, operwall, + locops, unauth; + + /* oper_umodes: default usermodes opers get when they /oper */ + oper_umodes = bots, locops, servnotice, operwall, wallop; + + /* + * use_egd: if your system does not have *random devices yet you + * want to use OpenSSL and encrypted links, enable this. Beware - + * EGD is *very* CPU intensive when gathering data for its pool + */ +# use_egd = yes; + + /* + * egdpool_path: path to EGD pool. Not necessary for OpenSSL >= 0.9.7 + * which automatically finds the path. + */ +# egdpool_path = "/var/run/egd-pool"; + + /* + * throttle_time: the minimum amount of time between connections from + * the same ip. exempt {} blocks are excluded from this throttling. + * Offers protection against flooders who reconnect quickly. + * Set to 0 to disable. + */ + throttle_time = 10; +}; + +modules { + /* + * path: other paths to search for modules specified below + * and in "/module load". + */ + path = "/usr/local/ircd/lib/ircd-hybrid/modules"; + path = "/usr/local/ircd/lib/ircd-hybrid/modules/autoload"; + + /* module: the name of a module to load on startup/rehash */ + #module = "some_module.la"; +}; + +/* + * log {}: contains information about logfiles. + */ +log { + /* Do you want to enable logging to ircd.log? */ + use_logging = yes; + + file { + type = oper; + name = "/home/ircd/var/log/oper.log"; + size = unlimited; + }; + + file { + type = user; + name = "/home/ircd/var/log/user.log"; + size = 50 megabytes; + }; + + file { + type = kill; + name = "/home/ircd/var/log/kill.log"; + size = 50 megabytes; + }; + + file { + type = kline; + name = "/home/ircd/var/log/kline.log"; + size = 50 megabytes; + }; + + file { + type = dline; + name = "/home/ircd/var/log/dline.log"; + size = 50 megabytes; + }; + + file { + type = gline; + name = "/home/ircd/var/log/gline.log"; + size = 50 megabytes; + }; + + file { + type = debug; + name = "/home/ircd/var/log/debug.log"; + size = 50 megabytes; + }; +}; diff --git a/doc/example.efnet.conf b/doc/example.efnet.conf new file mode 100644 index 0000000..2af4d03 --- /dev/null +++ b/doc/example.efnet.conf @@ -0,0 +1,1260 @@ +/* doc/example.efnet.conf - ircd-hybrid-8 EFnet Example configuration file + * Copyright (C) 2000-2012 Hybrid Development Team + * + * Written by ejb, wcampbel, db, leeh and others + * Other example configurations can be found in the source dir under + * doc/. + * + * $Id$ + */ + +/* IMPORTANT NOTES: + * + * auth {} blocks MUST be specified in order of precedence. The first one + * that matches a user will be used. So place spoofs first, then specials, + * then general access. + * + * Shell style (#), C++ style (//) and C style comments are supported. + * + * Files may be included by either: + * .include "filename" + * .include <filename> + * + * Times/durations are written as: + * 12 hours 30 minutes 1 second + * + * Valid units of time: + * month, week, day, hour, minute, second + * + * Valid units of size: + * megabyte/mbyte/mb, kilobyte/kbyte/kb, byte + * + * Sizes and times may be singular or plural. + */ + +/* EFNET NOTE: + * + * This configuration file is a BASIC configuration file for use + * on EFnet. You MUST still take the time to set this file up + * properly. + * + * DISCLAIMER: This file was submitted by Disciple@EFnet and has + * since been modified by the Hybrid team. + */ + +/* + * serverinfo {}: contains information about the server + */ +serverinfo { + /* + * name: the name of this server. This cannot be changed at runtime. + */ + name = "efnet.irc"; + + /* + * sid: a server's unique ID. This is three characters long and must + * be in the form [0-9][A-Z0-9][A-Z0-9]. The first character must be + * a digit, followed by 2 alpha-numerical letters. + * NOTE: The letters must be capitalized. This cannot be changed at runtime. + */ + sid = "_CHANGE_ME_"; + + /* + * description: the description of the server. + */ + description = "ircd-hybrid test server"; + + /* + * network info: the name and description of the network this server + * is on. Shown in the 005 reply and used with serverhiding. + */ + network_name = "EFnet"; + network_desc = "Eris Free Network"; + + /* + * hub: allow this server to act as a hub and have multiple servers + * connected to it. + */ + hub = no; + + /* + * vhost: the IP to bind to when we connect outward to ipv4 servers. + * This should be an ipv4 IP only, or "*" for INADDR_ANY. + */ + #vhost = "192.169.0.1"; + + /* + * vhost6: the IP to bind to when we connect outward to ipv6 servers. + * This should be an ipv6 IP only, or "*" for INADDR_ANY. + */ + #vhost6 = "3ffe:80e8:546::2"; + + /* max_clients: the maximum number of clients allowed to connect */ + max_clients = 512; + + /* + * rsa_private_key_file: the path to the file containing our + * rsa key for cryptlink. + * + * Example command to store a 2048 bit RSA keypair in + * rsa.key, and the public key in rsa.pub: + * + * openssl genrsa -out rsa.key 2048 + * openssl rsa -in rsa.key -pubout -out rsa.pub + * chown <ircd-user>.<ircd.group> rsa.key rsa.pub + * chmod 0600 rsa.key + * chmod 0644 rsa.pub + */ + #rsa_private_key_file = "/usr/local/ircd/etc/rsa.key"; + + /* + * ssl_certificate_file: the path to the file containing our + * ssl certificate for encrypted client connection. + * + * This assumes your private RSA key is stored in rsa.key. You + * MUST have an RSA key in order to generate the certificate + * + * openssl req -new -days 365 -x509 -key rsa.key -out cert.pem + * + * See http://www.openssl.org/docs/HOWTO/certificates.txt + * + * Please use the following values when generating the cert + * + * Organization Name: Network Name + * Organization Unit Name: changme.someirc.net + * Common Name: irc.someirc.net + * E-mail: you@domain.com + */ + #ssl_certificate_file = "/usr/local/ircd/etc/cert.pem"; + + /* + * ssl_dh_param_file: + * + * Path to the PEM encoded Diffie-Hellman parameter file. + * DH parameters are strictly required when using ciphers + * with EDH (ephemeral Diffie-Hellman) key exchange. + * + * A DH parameter file can be created by running: + * + * openssl dhparam -out dhparam.pem 1024 + * + * Prime size must be at least 1024 bits. Further information + * regarding specific OpenSSL dhparam command-line options + * can be found in the OpenSSL manual. + */ + #ssl_dh_param_file = "/usr/local/ircd/etc/dhparam.pem"; + + /* + * ssl_cipher_list: + * + * List of ciphers that are supported by _this_ server. Can be used to + * enforce specific ciphers for incoming SSL/TLS connections. + * If a client (which also includes incoming server connections) isn't + * capable of any cipher listed below, the connection will simply be + * rejected. + * + * A list of supported ciphers can be obtained by running: + * + * openssl ciphers -ssl3 -tls1 -v + * + * Multiple ciphers are separated by colons. The order of preference is + * from left to right. + */ + #ssl_cipher_list = "DHE-RSA-AES256-SHA:AES256-SHA"; + + /* + * ssl_server_method: + * ssl_client_method: + * + * SSL/TLS methods we provide for incoming (server method) and + * outgoing (client method) SSL/TLS connections. + * This can be either sslv3 for SSLv3, and/or tlsv1 for TLSv1. + */ + #ssl_server_method = tlsv1, sslv3; + #ssl_client_method = tlsv1; +}; + +/* + * admin {}: contains admin information about the server + */ +admin { + name = "EFnet Admin"; + description = "Main Server Administrator"; + email = "<irc-admin@efnet.irc>"; +}; + +/* + * class {}: contains information about classes for users + */ +class { + /* name: the name of the class */ + name = "users"; + + /* + * ping_time: how often a client must reply to a PING from the + * server before they are dropped. + */ + ping_time = 90 seconds; + + /* + * number_per_ip: how many local users are allowed to connect + * from one IP (optional) + */ + number_per_ip = 2; + + /* + * max_local: how many local users are allowed to connect + * from one ident@host (optional) + */ + max_local = 2; + + /* + * max_global: network-wide limit of users per ident@host (optional) + */ + max_global = 10; + + /* + * max_number: the maximum number of users allowed in this class (optional) + */ + max_number = 100; + + /* + * the following lines are optional and allow you to define + * how many users can connect from one /NN subnet + */ + cidr_bitlen_ipv4 = 24; + cidr_bitlen_ipv6 = 120; + number_per_cidr = 16; + + /* + * sendq: the amount of data allowed in a clients send queue before + * they are dropped. + */ + sendq = 100 kbytes; + + /* + * recvq: maximum amount of data in a clients receive queue before + * they are dropped for flooding. Defaults to 2560 if the chosen + * value isn't within the range of 512 to 8000. + */ + recvq = 2560 bytes; +}; + +class { + name = "opers"; + + /* + * contrary to seeming popular belief, setting ping time + * higher for an oper is NOT doing them a favor. + * Since if a link is dead its dead and it means + * you have to use another nick long enough to kill the old one :-) + * Its much better to use a fairly standard 90 second ping time + */ + ping_time = 90 seconds; + number_per_ip = 10; + max_number = 100; + sendq = 1 mbyte; +}; + +class { + name = "server"; + + /* + * Same thing here. It's a fallacy to think increasing + * ping time for servers is a "good idea." All it leads to + * is "ghosting" on one end. Not a good idea. + */ + ping_time = 90 seconds; + + /* + * ping_warning: how fast a server must reply to a PING before + * a warning to opers is generated. + */ + ping_warning = 15 seconds; + + /* + * connectfreq: only used in server classes. Specifies the delay + * between autoconnecting to servers. + * + * Both comstud and I recommend 10 minutes a few years ago. + * 15 minutes might be right now. The reason you don't want it too + * low is, you make the servers reconnect too quickly with + * a large sendq, and they _will_ nick collide. badly. 5 minutes + * IS way too short. + */ + connectfreq = 15 minutes; + + /* max number: the amount of servers to autoconnect to */ + max_number = 1; + + /* sendq: servers need a higher sendq as they send more data */ + sendq = 15 megabytes; +}; + +/* + * listen {}: contains information about the ports ircd listens on + */ +listen { + /* + * port: the specific port to listen on. If no host is specified + * before, it will listen on all available IPs. + * + * Ports are separated via a comma, a range may be specified using ".." + */ + + /* port: listen on all available IPs, ports 6665 to 6669 */ + port = 6665 .. 6669; + + /* + * Listen on 192.168.0.1/6697 with ssl enabled and hidden from STATS P + * unless you are an administrator. + * + * NOTE: The "flags" directive has to come before "port". Always! + * + * Currently available flags are: + * + * ssl - Port is for SSL client connections only + * server - Only server connections are permitted + * hidden - Port is hidden from /stats P, unless you're an admin + */ + flags = hidden, ssl; + host = "192.168.0.1"; + port = 6697; + + /* + * host: set a specific IP/host the ports after the line will listen + * on. This may be ipv4 or ipv6. + */ + host = "1.2.3.4"; + port = 7000, 7001; + + host = "3ffe:1234:a:b:c::d"; + port = 7002; +}; + +/* + * auth {}: allow users to connect to the ircd + */ +auth { + /* + * user: the user@host allowed to connect. Multiple user + * lines are permitted per auth block. + */ + user = "*@172.16.0.0/12"; + user = "*test@123D:B567:*"; + + /* password: an optional password that is required to use this block */ + password = "letmein"; + + /* + * encrypted: controls whether the auth password above has been + * encrypted. + */ + encrypted = yes; + + /* + * spoof: fake the users host to this. This is free-form, + * just do everyone a favor and don't abuse it. ('=' prefix on /stats I) + */ + spoof = "I.still.hate.packets"; + + /* class: the class the user is placed in */ + class = "opers"; + + /* + * need_password - don't allow users who haven't supplied the correct + * password to connect using another auth{} block + * ('&' prefix on /stats I if disabled) + * need_ident - require the user to have identd to connect ('+' prefix on /stats I) + * spoof_notice - enable spoofing notification to admins + * exceed_limit - allow a user to exceed class limits ('>' prefix on /stats I) + * kline_exempt - exempt this user from k/glines ('^' prefix on /stats I) + * gline_exempt - exempt this user from glines ('_' prefix on /stats I) + * resv_exempt - exempt this user from resvs ('$' prefix on /stats I) + * no_tilde - remove ~ from a user with no ident ('-' prefix on /stats I) + * can_flood - allow this user to exceed flood limits ('|' prefix on /stats I) + */ + flags = need_password, spoof_notice, exceed_limit, kline_exempt, + gline_exempt, resv_exempt, no_tilde, can_flood; +}; + +auth { + /* + * redirect: the server and port to redirect a user to. A user does + * not have to obey the redirection, the ircd just suggests an alternative + * server for them. + */ + redirserv = "this.is.not.a.real.server"; + redirport = 6667; + + user = "*.server"; + + /* class: a class is required even though it is not used */ + class = "users"; +}; + +auth { + user = "*@*"; + class = "users"; + flags = need_ident; +}; + +/* + * operator {}: defines ircd operators + * + * ircd-hybrid no longer supports local operators, privileges are + * controlled via flags. + */ +operator { + /* name: the name of the oper */ + name = "sheep"; + + /* + * user: the user@host required for this operator. Multiple + * user="" lines are supported. + */ + user = "*sheep@192.168.0.0/16"; + user = "*@127.0.0.0/8"; + + /* + * password: the password required to oper. By default this will + * need to be encrypted by using the provided mkpasswd tool. + * Several password hash algorithms are available depending + * on your system's crypt() implementation. For example, a modern + * glibc already has support for SHA-256/512, and MD5 encryption + * algorithms. + */ + password = "$5$x5zof8qe.Yc7/bPp$5zIg1Le2Lsgd4CvOjaD20pr5PmcfD7ha/9b2.TaUyG4"; + + /* + * encrypted: controls whether the oper password above has been + * encrypted. + */ + encrypted = yes; + + /* + * rsa_public_key_file: the public key for this oper when using Challenge. + * A password should not be defined when this is used, see + * doc/challenge.txt for more information. + */ +# rsa_public_key_file = "/usr/local/ircd/etc/oper.pub"; + + /* class: the class the oper joins when they successfully /oper */ + class = "opers"; + + /* + * umodes: default usermodes opers get when they /oper. If defined, + * it will override oper_umodes settings in general {}. + * Available usermodes: + * + * +b - bots - See bot and drone flooding notices + * +c - cconn - Client connection/quit notices + * +C - cconn_full - Client connection/quit notices full + * +D - deaf - Don't receive channel messages + * +d - debug - See debugging notices + * +f - full - See auth{} block full notices + * +G - softcallerid - Server Side Ignore for users not on your channels + * +g - callerid - Server Side Ignore (for privmsgs etc) + * +H - hidden - Hides operator status to other users + * +i - invisible - Not shown in NAMES or WHO unless you share a + * a channel + * +j - rej - See rejected client notices + * +k - skill - See server generated KILL messages + * +l - locops - See LOCOPS messages + * +n - nchange - See client nick changes + * +s - servnotice - See general server notices + * +u - unauth - See unauthorized client notices + * +w - wallop - See server generated WALLOPS + * +x - external - See remote server connection and split notices + * +y - spy - See LINKS, STATS, TRACE notices etc. + * +z - operwall - See oper generated WALLOPS + */ +# umodes = locops, servnotice, operwall, wallop; + + /* + * privileges: controls the activities and commands an oper is + * allowed to do on the server. All options default to no. + * Available options: + * + * module - allows MODULE + * global_kill - allows remote users to be /KILL'd + * remote - allows remote SQUIT and CONNECT + * remoteban - allows remote KLINE/UNKLINE + * dline - allows DLINE + * undline - allows UNDLINE + * kline - allows KILL and KLINE + * unkline - allows UNKLINE + * gline - allows GLINE + * xline - allows XLINE + * globops - allows GLOBOPS + * operwall - allows OPERWALL + * nick_changes - allows oper to see nickchanges via usermode +n + * rehash - allows oper to REHASH config + * die - allows DIE + * restart - allows RESTART + * set - allows SET + * admin - gives admin privileges. admins for example, + * may see the real IP addresses of servers. + */ + flags = global_kill, remote, kline, unkline, xline, globops, restart, + die, rehash, nick_changes, admin, operwall, module; +}; + +/* + * connect {}: controls servers we connect to + */ +connect { + /* name: the name of the server */ + name = "irc.uplink.com"; + + /* + * host: the host or IP to connect to. If a hostname is used it + * must match the reverse dns of the server. + */ + host = "192.168.0.1"; + + /* + * vhost: the IP to bind to when we connect outward to servers. + * serverinfo::vhost and serverinfo::vhost6 will be overridden + * by this directive. + */ + vhost = "192.168.0.2"; + + /* + * passwords: the passwords we send (OLD C:) and accept (OLD N:). + * The remote server will have these passwords reversed. + */ + send_password = "password"; + accept_password = "anotherpassword"; + + /* + * encrypted: controls whether the accept_password above has been + * encrypted. + */ + encrypted = no; + + /* port: the port to connect to this server on */ + port = 6666; + + /* + * hub_mask: the mask of servers that this server may hub. Multiple + * entries are permitted + */ + hub_mask = "*"; + + /* + * leaf_mask: the mask of servers this server may not hub. Multiple + * entries are permitted. Useful for forbidding EU -> US -> EU routes. + */ +# leaf_mask = "*.uk"; + + /* class: the class this server is in */ + class = "server"; + + /* + * ssl_cipher_list: + * + * List of ciphers that the server we are connecting to must support. + * If the server isn't capable of any cipher listed below, the + * connection will simply be rejected. + * Can be used to enforce stronger ciphers, even though this option + * is not necessarily required to establish a SSL/TLS connection. + * + * Multiple ciphers are separated by colons. The order of preference + * is from left to right. + */ + #ssl_cipher_list = "DHE-RSA-AES256-SHA:AES256-SHA"; + + /* + * autoconn - controls whether we autoconnect to this server or not, + * dependent on class limits. By default, this is disabled. + * ssl - Initiates a TLS/SSL connection. + */ +# flags = autoconn, ssl; +}; + +connect { + name = "ipv6.some.server"; + host = "3ffd:dead:beef::1"; + send_password = "password"; + accept_password = "password"; + port = 6666; + + /* + * aftype: controls whether the connection uses "ipv4" or "ipv6". + * Default is ipv4. + */ + aftype = ipv6; + class = "server"; +}; + +/* + * cluster {}: servers that share klines/unkline/xline/unxline/resv/unresv/locops + * automatically + */ +cluster { + /* + * name: the server to share with, this can take wildcards + * + * NOTE: only local actions will be clustered, meaning if + * the server receives a shared kline/unkline/etc, it + * will not be propagated to clustered servers. + * + * Remote servers are not necessarily required to accept + * clustered lines, they need a shared{} for *THIS* server + * in order to accept them. + */ + name = "*.arpa"; + + /* + * type: list of what to share, options are as follows: + * dline - share dlines + * undline - share undlines + * kline - share klines + * unkline - share unklines + * xline - share xlines + * unxline - share unxlines + * resv - share resvs + * unresv - share unresvs + * locops - share locops + * all - share all of the above (default) + */ + type = kline, unkline, locops, xline, resv; +}; + +/* + * shared {}: users that are allowed to remote kline + * + * NOTE: This can be effectively used for remote klines. + * Please note that there is no password authentication + * for users setting remote klines. You must also be + * /oper'd in order to issue a remote kline. + */ +shared { + /* + * name: the server the user must be on to set klines. If this is not + * specified, the user will be allowed to kline from all servers. + */ + name = "irc2.some.server"; + + /* + * user: the user@host mask that is allowed to set klines. If this is + * not specified, all users on the server above will be allowed to set + * a remote kline. + */ + user = "oper@my.host.is.spoofed"; + + /* + * type: list of what to share, options are as follows: + * dline - allow oper/server to dline + * undline - allow oper/server to undline + * kline - allow oper/server to kline + * unkline - allow oper/server to unkline + * xline - allow oper/server to xline + * unxline - allow oper/server to unxline + * resv - allow oper/server to resv + * unresv - allow oper/server to unresv + * locops - allow oper/server to locops - only used for servers that cluster + * all - allow oper/server to do all of the above (default) + */ + type = kline, unkline, resv; +}; + +/* + * kill {}: users that are not allowed to connect + * Oper issued klines will be added to the specified kline config + */ +kill { + user = "bad@*.hacked.edu"; + reason = "Obviously hacked account"; +}; + +kill { + user = "^O[[:alpha:]]?[[:digit:]]+(x\.o|\.xo)$@^[[:alnum:]]{4}\.evilnet.tld$"; + + /* + * NOTE: You have to set type=regex; when using a regular expression + * based user entry + */ + type = regex; +}; + +/* + * deny {}: IPs that are not allowed to connect (before DNS/ident lookup) + * Oper issued dlines will be added to the specified dline config + */ +deny { + ip = "10.0.1.0/24"; + reason = "Reconnecting vhosted bots"; +}; + +/* + * exempt {}: IPs that are exempt from deny {} and Dlines + * + * EFnet Note: We really suggest to enable general::stats_e_disabled + * if you plan to exempt EFnet server IPs you don't want to show to + * other operators and/or administrators through "STATS e". + */ +exempt { + ip = "192.168.0.0/16"; +}; + +/* + * resv {}: nicks and channels users may not use/join + */ +resv { + /* reason: the reason for the proceeding resv's */ + reason = "There are no services on this network"; + + /* resv: the nicks and channels users may not join/use */ + nick = "nickserv"; + nick = "chanserv"; + nick = "operserv"; + nick = "JUPES"; + nick = "JUPE"; + nick = "CH?NF?X"; # CHANFIX (services.int) + + /* These are totally optional, but may be a good idea */ + nick = "oper"; + nick = "ircop"; + nick = "op"; + nick = "ident"; + nick = "pass"; + channel = "#jupedchan"; + + /* resv: wildcard masks are also supported in nicks only */ + reason = "Clone bots"; + nick = "clone*"; +}; + +/* + * gecos {}: The X: replacement, used for banning users based on + * their "realname". + */ +gecos { + name = "*sex*"; + reason = "Possible spambot"; +}; + +gecos { + name = "sub7server"; + reason = "Trojan drone"; +}; + +gecos { + name = "*http*"; + reason = "Spambot"; +}; + +gecos { + name = "^\[J[0o]hn Do[3e]\]-[0-9]{2,5}$"; + + /* + * NOTE: You have to set type=regex; when using a regular expression + * based name entry + */ + type = regex; +}; + +/* + * channel {}: The channel block contains options pertaining to channels + */ +channel { + /* + * disable_fake_channels: this option, if set to 'yes', will + * disallow clients to create or join channels that have one + * of the following ASCII characters in their name: + * + * 2 | bold + * 3 | mirc color + * 15 | plain text + * 22 | reverse + * 29 | italic + * 31 | underline + * 160 | non-breaking space + */ + disable_fake_channels = yes; + + /* + * restrict_channels: reverse channel RESVs logic, only reserved + * channels are allowed + */ + restrict_channels = no; + + /* + * knock_delay: The amount of time a user must wait between issuing + * the knock command. + */ + knock_delay = 5 minutes; + + /* + * knock_delay_channel: How often a knock to any specific channel + * is permitted, regardless of the user sending the knock. + */ + knock_delay_channel = 1 minute; + + /* + * max_chans_per_user: The maximum number of channels a user can + * join/be on. + */ + max_chans_per_user = 25; + + /* + * max_chans_per_oper: The maximum number of channels an oper can + * join/be on. + */ + max_chans_per_oper = 50; + + /* quiet_on_ban: stop banned people talking in channels. */ + quiet_on_ban = yes; + + /* max_bans: maximum number of +b/e/I modes in a channel */ + max_bans = 100; + + /* + * how many joins in how many seconds constitute a flood, use 0 to + * disable. +b opers will be notified (changeable via /set) + */ + join_flood_count = 16; + join_flood_time = 8 seconds; + + /* + * splitcode: The ircd will now check splitmode every few seconds. + * + * Either split users or split servers can activate splitmode, but + * both conditions must be met for the ircd to deactivate splitmode. + * + * You may force splitmode to be permanent by /quote set splitmode on + */ + + /* + * default_split_user_count: when the usercount is lower than this level, + * consider ourselves split. This must be set for automatic splitmode. + */ + default_split_user_count = 20000; + + /* + * default_split_server_count: when the servercount is lower than this, + * consider ourselves split. This must be set for automatic splitmode. + */ + default_split_server_count = 10; + + /* no_create_on_split: disallow users creating channels on split. */ + no_create_on_split = yes; + + /* no_join_on_split: disallow users joining channels at all on a split. */ + no_join_on_split = no; +}; + +/* + * serverhide {}: The serverhide block contains the options regarding + * serverhiding + */ +serverhide { + /* + * flatten_links: this option will show all servers in /links appear + * that they are linked to this current server + * + * EFnet Note: While this is not a requirement on EFnet, it + * may be a good idea. Except, it's useless + * unless the entire net runs it. + */ + flatten_links = no; + + /* + * links_delay: how often to update the links file when it is + * flattened. + */ + links_delay = 5 minutes; + + /* + * hidden: hide this server from a /links output on servers that + * support it. This allows hub servers to be hidden etc. + */ + hidden = no; + + /* + * hide_servers: hide remote servernames everywhere and instead use + * hidden_name and network_desc. + */ + hide_servers = no; + + /* + * Use this as the servername users see if hide_servers = yes. + */ + hidden_name = "*.hidden.com"; + + /* + * hide_server_ips: If this is disabled, opers will be unable to see + * servers ips and will be shown a masked ip, admins will be shown the + * real ip. + * + * If this is enabled, nobody can see a servers ip. *This is a kludge*, + * it has the side effect of hiding the ips everywhere, including + * logfiles. + * + * We recommend you leave this disabled, and just take care with who you + * give admin=yes; to. + */ + hide_server_ips = yes; +}; + +/* + * general {}: The general block contains many of the options that were once + * compiled in options in config.h. The general block is read at start time. + */ +general { + /* max_watch: maximum WATCH entries a client can have. */ + max_watch = 60; + + /* + * EFnet Note: This feature is required for European EFnet servers + * and is used by several North American servers. As + * such, it has been left on by default. If you + * do not want your server to participate in G:Lines + * you should disable this. + */ + + /* gline_enable: enable glines, network wide temp klines */ + gline_enable = yes; + + /* + * gline_duration: the amount of time a gline will remain on your + * server before expiring + */ + gline_duration = 1 day; + + /* + * gline_request_duration: how long a pending G-line can be around. + * 10 minutes should be plenty + */ + gline_request_duration = 10 minutes; + + /* + * gline_min_cidr: the minimum required length of a CIDR bitmask + * for IPv4 based glines + */ + gline_min_cidr = 16; + + /* + * gline_min_cidr6: the minimum required length of a CIDR bitmask + * for IPv6 based glines + */ + gline_min_cidr6 = 48; + + /* + * Whether to automatically set mode +i on connecting users. + */ + invisible_on_connect = yes; + + /* + * Max time from the nickname change that still causes KILL + * automatically to switch for the current nick of that user. + */ + kill_chase_time_limit = 90 seconds; + + /* + * If hide_spoof_ips is disabled, opers will be allowed to see the real + * IP of spoofed users in /trace etc. If this is defined they will be + * shown a masked IP. + */ + hide_spoof_ips = yes; + + /* + * Ignore bogus timestamps from other servers. Yes, this will desync + * the network, but it will allow chanops to resync with a valid non TS 0 + * + * This should be enabled network wide, or not at all. + */ + ignore_bogus_ts = no; + + /* + * disable_auth: completely disable ident lookups; if you enable this, + * be careful of what you set need_ident to in your auth {} blocks + */ + disable_auth = no; + + /* disable_remote_commands: disable users doing commands on remote servers */ + disable_remote_commands = no; + + /* + * tkline_expire_notices: enables or disables temporary kline/xline + * expire notices. + */ + tkline_expire_notices = no; + + /* + * default_floodcount: the default value of floodcount that is configurable + * via /quote set floodcount. This is the amount of lines a user + * may send to any other user/channel in one second. + */ + default_floodcount = 10; + + /* + * failed_oper_notice: send a notice to all opers on the server when + * someone tries to OPER and uses the wrong password, host or ident. + */ + failed_oper_notice = yes; + + /* + * dots_in_ident: the amount of '.' characters permitted in an ident + * reply before the user is rejected. + */ + dots_in_ident = 2; + + /* + * min_nonwildcard: the minimum non wildcard characters in k/d/g lines + * placed via the server. klines hand placed are exempt from limits. + * wildcard chars: '.' ':' '*' '?' '@' '!' '#' + */ + min_nonwildcard = 3; + + /* + * min_nonwildcard_simple: the minimum non wildcard characters in + * gecos bans. wildcard chars: '*' '?' '#' + */ + min_nonwildcard_simple = 3; + + /* max_accept: maximum allowed /accept's for +g usermode */ + max_accept = 20; + + /* anti_nick_flood: enable the nickflood control code */ + anti_nick_flood = yes; + + /* nick flood: the nick changes allowed in the specified period */ + max_nick_time = 20 seconds; + max_nick_changes = 5; + + /* + * anti_spam_exit_message_time: the minimum time a user must be connected + * before custom quit messages are allowed. + */ + anti_spam_exit_message_time = 5 minutes; + + /* + * ts delta: the time delta allowed between server clocks before + * a warning is given, or before the link is dropped. all servers + * should run ntpdate/rdate to keep clocks in sync + */ + ts_warn_delta = 30 seconds; + ts_max_delta = 5 minutes; + + /* + * warn_no_nline: warn opers about servers that try to connect but + * we don't have a connect {} block for. Twits with misconfigured + * servers can get really annoying with this enabled. + */ + warn_no_nline = yes; + + /* + * stats_e_disabled: set this to 'yes' to disable "STATS e" for both + * operators and administrators. Doing so is a good idea in case + * there are any exempted (exempt{}) server IPs you don't want to + * see leaked. + */ + stats_e_disabled = no; + + /* stats_o_oper only: make stats o (opers) oper only */ + stats_o_oper_only = yes; + + /* stats_P_oper_only: make stats P (ports) oper only */ + stats_P_oper_only = yes; + + /* + * stats i oper only: make stats i (auth {}) oper only. set to: + * yes: show users no auth blocks, made oper only. + * masked: show users first matching auth block + * no: show users all auth blocks. + */ + stats_i_oper_only = yes; + + /* + * stats_k_oper_only: make stats k/K (klines) oper only. set to: + * yes: show users no auth blocks, made oper only + * masked: show users first matching auth block + * no: show users all auth blocks. + */ + stats_k_oper_only = yes; + + /* + * caller_id_wait: time between notifying a +g user that somebody + * is messaging them. + */ + caller_id_wait = 1 minute; + + /* + * opers_bypass_callerid: allows operators to bypass +g and message + * anyone who has it set (useful if you use services). + */ + opers_bypass_callerid = no; + + /* + * pace_wait_simple: time between use of less intensive commands + * (ADMIN, HELP, (L)USERS, VERSION, remote WHOIS) + */ + pace_wait_simple = 1 second; + + /* + * pace_wait: time between more intensive commands + * (AWAY, INFO, LINKS, MAP, MOTD, STATS, WHO, wildcard WHOIS, WHOWAS) + */ + pace_wait = 10 seconds; + + /* + * short_motd: send clients a notice telling them to read the motd + * instead of forcing a motd to clients who may simply ignore it. + */ + short_motd = no; + + /* + * ping_cookie: require clients to respond exactly to a ping command, + * can help block certain types of drones and FTP PASV mode spoofing. + */ + ping_cookie = no; + + /* no_oper_flood: increase flood limits for opers. */ + no_oper_flood = yes; + + /* + * true_no_oper_flood: completely eliminate flood limits for opers + * and for clients with can_flood = yes in their auth {} blocks + */ + true_no_oper_flood = yes; + + /* oper_pass_resv: allow opers to over-ride RESVs on nicks/channels */ + oper_pass_resv = yes; + + /* REMOVE ME. The following line checks you've been reading. */ + havent_read_conf = 1; + + /* + * max_targets: the maximum amount of targets in a single + * PRIVMSG/NOTICE. Set to 999 NOT 0 for unlimited. + */ + max_targets = 4; + + /* + * message_locale: the default message locale + * Use "standard" for the compiled in defaults. + * To install the translated messages, go into messages/ in the + * source directory and run `make install'. + */ + message_locale = "standard"; + + /* + * usermodes configurable: a list of usermodes for the options below + * + * +b - bots - See bot and drone flooding notices + * +c - cconn - Client connection/quit notices + * +C - cconn_full - Client connection/quit notices full + * +D - deaf - Don't receive channel messages + * +d - debug - See debugging notices + * +f - full - See auth{} block full notices + * +G - softcallerid - Server Side Ignore for users not on your channels + * +g - callerid - Server Side Ignore (for privmsgs etc) + * +H - hidden - Hides operator status to other users + * +i - invisible - Not shown in NAMES or WHO unless you share a + * a channel + * +j - rej - See rejected client notices + * +k - skill - See server generated KILL messages + * +l - locops - See LOCOPS messages + * +n - nchange - See client nick changes + * +s - servnotice - See general server notices + * +u - unauth - See unauthorized client notices + * +w - wallop - See server generated WALLOPS + * +x - external - See remote server connection and split notices + * +y - spy - See LINKS, STATS, TRACE notices etc. + * +z - operwall - See oper generated WALLOPS + */ + + /* oper_only_umodes: usermodes only opers may set */ + oper_only_umodes = bots, cconn, cconn_full, debug, full, hidden, skill, + nchange, rej, spy, external, operwall, + locops, unauth; + + /* oper_umodes: default usermodes opers get when they /oper */ + oper_umodes = bots, locops, servnotice, operwall, wallop; + + /* + * use_egd: if your system does not have *random devices yet you + * want to use OpenSSL and encrypted links, enable this. Beware - + * EGD is *very* CPU intensive when gathering data for its pool + */ +# use_egd = yes; + + /* + * egdpool_path: path to EGD pool. Not necessary for OpenSSL >= 0.9.7 + * which automatically finds the path. + */ +# egdpool_path = "/var/run/egd-pool"; + + /* + * throttle_time: the minimum amount of time between connections from + * the same ip. exempt {} blocks are excluded from this throttling. + * Offers protection against flooders who reconnect quickly. + * Set to 0 to disable. + */ + throttle_time = 0; +}; + +modules { + /* + * path: other paths to search for modules specified below + * and in "/module load". + */ + path = "/usr/local/ircd/lib/ircd-hybrid/modules"; + path = "/usr/local/ircd/lib/ircd-hybrid/modules/autoload"; + + /* module: the name of a module to load on startup/rehash */ + #module = "some_module.la"; +}; + +/* + * log {}: contains information about logfiles. + */ +log { + /* Do you want to enable logging to ircd.log? */ + use_logging = yes; + + file { + type = oper; + name = "/home/ircd/var/log/oper.log"; + size = unlimited; + }; + + file { + type = user; + name = "/home/ircd/var/log/user.log"; + size = 50 megabytes; + }; + + file { + type = kill; + name = "/home/ircd/var/log/kill.log"; + size = 50 megabytes; + }; + + file { + type = kline; + name = "/home/ircd/var/log/kline.log"; + size = 50 megabytes; + }; + + file { + type = dline; + name = "/home/ircd/var/log/dline.log"; + size = 50 megabytes; + }; + + file { + type = gline; + name = "/home/ircd/var/log/gline.log"; + size = 50 megabytes; + }; + + file { + type = debug; + name = "/home/ircd/var/log/debug.log"; + size = 50 megabytes; + }; +}; diff --git a/doc/example.quick.conf b/doc/example.quick.conf new file mode 100644 index 0000000..65f0859 --- /dev/null +++ b/doc/example.quick.conf @@ -0,0 +1,369 @@ +/* doc/example.conf.quick - ircd-hybrid-8 Example configuration file + * Copyright (C) 2000-2012 Hybrid Development Team + * + * Written by ejb, wcampbel, db, leeh and others + * + * $Id$ + */ + +/* IMPORTANT NOTES: + * + * auth {} blocks MUST be specified in order of precedence. The first one + * that matches a user will be used. So place spoofs first, then specials, + * then general access, then restricted. + * + * Both shell style (#) and C style comments are supported. + * + * Files may be included by either: + * .include "filename" + * .include <filename> + * + * Times/durations are written as: + * 12 hours 30 minutes 1 second + * + * Valid units of time: + * month, week, day, hour, minute, second + * + * Valid units of size: + * megabyte/mbyte/mb, kilobyte/kbyte/kb, byte + * + * Sizes and times may be singular or plural. + */ + +/* EFNET NOTE: + * + * This config file is NOT suitable for EFNet. EFNet admins should use + * example.efnet.conf + */ + +serverinfo { + name = "hades.arpa"; + sid = "_CHANGE_ME_"; + description = "ircd-hybrid test server"; + network_name = "MyNet"; + network_desc = "This is My Network"; + hub = no; + #vhost = "192.169.0.1"; + #vhost6 = "3ffe:80e8:546::2"; + max_clients = 512; + #rsa_private_key_file = "/usr/local/ircd/etc/rsa.key"; + #ssl_certificate_file = "/usr/local/ircd/etc/cert.pem"; + #ssl_server_method = tlsv1, sslv3; + #ssl_client_method = tlsv1; +}; + +/* admin {}: contains admin information about the server. (OLD A:) */ +admin { + name = "Smurf target"; + description = "Main Server Administrator"; + email = "<syn@packets.r.us>"; +}; + +/* class {}: contain information about classes for users (OLD Y:) */ +class { + name = "users"; + ping_time = 2 minutes; + number_per_ip = 2; + max_number = 100; + sendq = 100 kbytes; + recvq = 2560 bytes; +}; + +class { + name = "restricted"; + ping_time = 1 minute 30 seconds; + number_per_ip = 1; + max_number = 100; + sendq = 60kb; + recvq = 2560 bytes; +}; + +class { + name = "opers"; + ping_time = 5 minutes; + number_per_ip = 10; + max_number = 100; + sendq = 100kbytes; +}; + +class { + name = "server"; + ping_time = 5 minutes; + ping_warning = 15 seconds; + connectfreq = 5 minutes; + max_number = 1; + sendq=2 megabytes; +}; + +/* listen {}: contain information about the ports ircd listens on (OLD P:) */ +listen { + port = 6665 .. 6669; + + flags = ssl; + port = 6697; + + host = "1.2.3.4"; + port = 7000, 7001; + + host = "3ffe:1234:a:b:c::d"; + port = 7002; +}; + +/* auth {}: allow users to connect to the ircd (OLD I:) */ +auth { + user = "*@172.16.0.0/12"; + user = "*test@123D:B567:*"; + password = "letmein"; + flags = need_password, spoof_notice, exceed_limit, kline_exempt, + gline_exempt, no_tilde; + spoof = "I.still.hate.packets"; + class = "opers"; +}; + +auth { + redirserv = "irc.fi"; + redirport = 6667; + user = "*.fi"; + class = "users"; +}; + +auth { + user = "*@*"; + class = "users"; + flags = need_ident; +}; + +/* operator {}: defines ircd operators. (OLD O:) + * ircd-hybrid no longer supports local operators, privileges are + * controlled via flags. + */ +operator { + name = "sheep"; + user = "*sheep@*"; + user = "*@127.0.0.1"; + password = "etcnjl8juSU1E"; + encrypted = yes; + #rsa_public_key_file = "/usr/local/ircd/etc/oper.pub"; + class = "opers"; + flags = global_kill, remote, kline, unkline, gline, module, + xline, die, rehash, nick_changes, admin, set; +}; + +/* connect {}: controls servers we connect to (OLD C:, N:, H:, L:) */ +connect { + name = "irc.uplink.com"; + host = "192.168.0.1"; + send_password = "password"; + accept_password = "anotherpassword"; + encrypted = no; + port = 6666; + hub_mask = "*"; + #leaf_mask = "*.uk"; + class = "server"; + flags = autoconn; +}; + +connect { + name = "ipv6.some.server"; + host = "3ffd:dead:beef::1"; + send_password = "password"; + accept_password = "password"; + port = 6666; + + aftype = ipv6; + class = "server"; +}; + +/* cluster{}: servers that share klines/unkline/xline/unxline/resv/unresv/locops + * automatically (OLD hyb6 SLAVE_SERVERS) + */ +cluster { + name = "*.arpa"; + type = kline, unkline, locops, xline, resv; +}; + +/* shared {}: users that are allowed to remote kline (OLD U:) */ +shared { + name = "irc2.some.server"; + user = "oper@my.host.is.spoofed"; + type = all; +}; + +/* kill {}: users that are not allowed to connect (OLD K:) + * Oper issued klines will be added to the specified kline config + */ +kill { + user = "bad@*.hacked.edu"; + reason = "Obviously hacked account"; +}; + +/* deny {}: IPs that are not allowed to connect (before DNS/ident lookup) + * Oper issued dlines will be added to the specified dline config + */ +deny { + ip = "10.0.1.0/24"; + reason = "Reconnecting vhosted bots"; +}; + +/* exempt {}: IPs that are exempt from deny {} and Dlines. (OLD d:) */ +exempt { + ip = "192.168.0.0/16"; +}; + +/* resv {}: nicks and channels users may not use/join (OLD Q:) */ +resv { + nick = "nickserv"; + nick = "chanserv"; + channel = "#services"; + reason = "Clone bots"; + nick = "clone*"; +}; + +gecos { + name = "*sex*"; + reason = "Possible spambot"; +}; + +gecos { + name = "sub7server"; + reason = "Trojan drone"; +}; + +gecos { + name = "*http*"; + reason = "Spambot"; +}; + +channel { + restrict_channels = no; + knock_delay = 5 minutes; + knock_delay_channel = 1 minute; + max_chans_per_user = 25; + max_chans_per_oper = 50; + quiet_on_ban = yes; + max_bans = 25; + join_flood_count = 16; + join_flood_time = 8 seconds; + default_split_user_count = 0; + default_split_server_count = 0; + no_create_on_split = yes; + no_join_on_split = no; +}; + +serverhide { + flatten_links = no; + links_delay = 5 minutes; + hidden = no; + hide_servers = no; + hidden_name = "*.hidden.com"; + hide_server_ips = no; +}; + +general { + kill_chase_time_limit = 90 seconds; + hide_spoof_ips = yes; + ignore_bogus_ts = no; + + disable_auth = no; + disable_remote_commands = no; + default_floodcount = 10; + failed_oper_notice = yes; + dots_in_ident=2; + min_nonwildcard = 4; + min_nonwildcard_simple = 3; + max_accept = 20; + anti_nick_flood = yes; + + max_nick_time = 20 seconds; + max_nick_changes = 5; + + anti_spam_exit_message_time = 5 minutes; + ts_warn_delta = 30 seconds; + ts_max_delta = 5 minutes; + + invisible_on_connect = yes; + warn_no_nline = yes; + stats_o_oper_only=yes; + stats_P_oper_only=no; + stats_i_oper_only=masked; + stats_k_oper_only=masked; + caller_id_wait = 1 minute; + pace_wait_simple = 1 second; + pace_wait = 10 seconds; + short_motd = no; + ping_cookie = no; + no_oper_flood = yes; + true_no_oper_flood = yes; + oper_pass_resv = yes; + + /* REMOVE ME. The following line checks you've been reading. */ + havent_read_conf = 1; + + max_targets = 4; + message_locale = "standard"; + oper_only_umodes = bots, cconn, debug, full, skill, nchange, + rej, spy, external, operwall, locops, unauth; + + oper_umodes = bots, locops, servnotice, operwall, wallop; + + + #use_egd = yes; + #egdpool_path = "/var/run/egd-pool"; + throttle_time = 10; +}; + +modules { + path = "/usr/local/ircd/lib/ircd-hybrid/modules"; + path = "/usr/local/ircd/lib/ircd-hybrid/modules/autoload"; + #module = "some_module.so"; +}; + +/* + * log {}: contains information about logfiles. + */ +log { + /* Do you want to enable logging to ircd.log? */ + use_logging = yes; + + file { + type = oper; + name = "/home/ircd/var/log/oper.log"; + size = unlimited; + }; + + file { + type = user; + name = "/home/ircd/var/log/user.log"; + size = 50 megabytes; + }; + + file { + type = kill; + name = "/home/ircd/var/log/kill.log"; + size = 50 megabytes; + }; + + file { + type = kline; + name = "/home/ircd/var/log/kline.log"; + size = 50 megabytes; + }; + + file { + type = dline; + name = "/home/ircd/var/log/dline.log"; + size = 50 megabytes; + }; + + file { + type = gline; + name = "/home/ircd/var/log/gline.log"; + size = 50 megabytes; + }; + + file { + type = debug; + name = "/home/ircd/var/log/debug.log"; + size = 50 megabytes; + }; +}; diff --git a/doc/guidelines.txt b/doc/guidelines.txt new file mode 100644 index 0000000..a3d13f8 --- /dev/null +++ b/doc/guidelines.txt @@ -0,0 +1,36 @@ +ircd-hybrid documentation guidelines + +1. When a major change in the code affects users, it MUST be documented +in whats-new and all other appropriate locations. + +2. When something affects the configuration file, and it's compatibility +with previous versions, it MUST be documented in example.conf and in a +proposed new document README.NOW. This is VERY important during the beta +phase to help anyone who mans the "help desk". + +3. All documentation must properly fit in an 80 character wide terminal. +SGML and other "professional" documentation systems are good for some +projects, but hybrid is intended to be used on minimal UNIX installations +where any extra binary is a security risk. Text only docs, sized to fit +properly in an 80 character wide console, are what admins expect, and that's +what they should get. + +4. All documentation must be spell checked before a release or a beta. +'ispell' (using either the US or British dictionary) is probably the +easiest way to spell check the documentation. 'ispell -a' at the command +line will allow you to check individual words as you are editing. + +5. When a document is over approximately 5 pages long, it should be split +into sections to facilitate users reading them. + +6. All docs (except docs specifically describing code) should be written +in a way that all users of the software (not just programmers) will be able +to easily understand. + +7. Don't make documentation a chore. If it's done while coding, or shortly +after, it usually is more accurate and the documentation tasks don't get +pushed back and pile up. + +8. Don't forget to include a CVS Id. + +# $Id$ diff --git a/doc/index.txt b/doc/index.txt new file mode 100644 index 0000000..d43a112 --- /dev/null +++ b/doc/index.txt @@ -0,0 +1,23 @@ +$Id$ +----------------------------------------------- + +Documentation for ircd-hybrid + +CIDR.txt - Description of CIDR in IPv4 +challenge.txt - Overview of the challenge/response system for + obtaining operator status +guidelines.txt - Documentation guidelines +index.txt - This file +ircd.8 - The new revised manpage, read with the following + commands in the prefix directory: + man -M . ircd +kline.txt - Outline of the remote K-line protocol for both + opers and servers +messages.txt - A general help file for users and admins to + customize ircd's messages. +modeg.txt - An in depth description of the server side silence + user mode (+g) +modes.txt - A list of all user and channel modes +resv.txt - Outline of the RESV command. +server-version-info - Overview of the flags shown in /version +serverhide.txt - Information about the server hide options diff --git a/doc/ircd.8 b/doc/ircd.8 new file mode 100644 index 0000000..25f03f4 --- /dev/null +++ b/doc/ircd.8 @@ -0,0 +1,110 @@ +.\" @(#)ircd.8 7b10 25 Oct 2001 +.\" $Id$ +.TH IRCD 8 "1 April 2012" "ircd-hybrid-8" +.SH NAME +ircd \- The IRCD-Hybrid Internet Relay Chat server +.SH SYNOPSIS +.hy 0 +.IP \fBircd\fP +[-configfile filename] [-dlinefile filename] [-klinefile filename] +[-xlinefile filename] [-logfile filename] [-pidfile filename] [-foreground] +[-version] +.SH DESCRIPTION +.LP +\fIircd\fP is the server (daemon) program for the Internet Relay Chat +Program. The \fIircd\fP is a server in that its function is to "serve" +the client program \fIirc(1)\fP and other compatible programs with +messages and commands. All commands and user messages are passed +directly to the \fIircd\fP for processing and relaying to other IRC +servers. + +This is \fIircd-hybrid\fP, the highly modified (and hopefully improved) +variant of the original ircd program by Jarkko Oikarinen. +.SH OPTIONS +.TP +.B \-configfile filename +Specifies the ircd.conf file to be used for this \fIircd\fP. The option +is used to override the default ircd.conf given at compile time. By default, +this is "etc/ircd.conf" within the prefix you installed the \fIircd\fP in. +.TP +.B \-dlinefile filename +.TP +.B \-klinefile filename +.TP +.B \-xlinefile filename +Specifies the files to be used for D-lines (host bans), K-lines (hostmask bans), +and X-lines (gecos bans), which by default are within the etc/ directory of your +installation prefix as dline.conf, kline.conf, and xline.conf. +.TP +.B \-logfile filename +Specifies an alternative logfile to be used than that specified in defaults.h +.TP +.B \-pidfile filename +Specifies the file used by the \fIircd\fP to store its process ID. The option is +used to override the default ircd.pid given at compile time. +.TP +.B \-foreground +Makes \fIircd\fP run in the foreground +.TP +.B \-version +Makes \fIircd\fP print its version, and exit. +.SH USAGE +If you plan to connect your \fIircd\fP server to an existing IRC network, +you will need to alter your local IRC configuration file (typically named +"ircd.conf") so that it will accept and make connections to other \fIIRC\fP +servers. This file contains the hostnames, IP addresses, and sometimes +passwords for connections to other ircds around the world. + +The example ircd.conf in the etc/ directory documents itself. Read it +carefully or you may expose a risk on your network simply by having your +ircd running! +.LP +.SH BOOTING THE SERVER +It is sufficient to type \fBircd\fP at the command line to start +ircd-hybrid into the background. If you wish to run ircd in the +foreground (perhaps for debugging purposes), use the \fB-foreground\fP +parameter. + +The ircd-hybrid package in your distribution may ship with an rc-script +which handles this for you. In Debian, it is \fB/etc/init.d/ircd-hybrid.\fP + +.SH EXAMPLE +# ircd -configfile /usr/share/ircd/ircd.conf -logfile /var/log/ircd.log + +Starts \fBircd\fP with the config file /usr/share/ircd/ircd.conf and +with a log file /var/log/ircd.log. It implicitly forks back to the +console -- to prevent this use -foreground. + +Many of the above paths are hardcoded at compile time in the +\fBinclude/defaults.h\fP file, so it may be convenient to edit these to +suit your needs before you compile the ircd. +.SH COPYRIGHT +(c) 1988,1989 University of Oulu, Computing Center, Finland, +.LP +(c) 1988,1989 Department of Information Processing Science, +University of Oulu, Finland +.LP +(c) 1988-1991 Jarkko Oikarinen +.LP +(c) 1997-2012 The IRCD-Hybrid project. +.LP +For full COPYRIGHT see the LICENSE file within the IRC source package. +.LP +.RE +.SH BUGS +If you find a bug and you have a core file from ircd as a result, use a +debugger like \fBgdb(1)\fP to process the core file and send a backtrace +to \fBbugs@ircd-hybrid.org\fP. + +.SH AUTHORS +irc2.8 and earlier: Jarkko Oikarinen, currently jto@tolsun.oulu.fi. See +doc/old/Authors for more credits. +.LP +ircd-hybrid-7: the IRCD-Hybrid Project, bugs@ircd-hybrid.org. +.LP +Manual page written by Jeff Trim, jtrim@orion.cair.du.edu, +later modified by jto@tolsun.oulu.fi. +.LP +Updated by W. Campbell, wcampbel@botbay.net, Edward Brocklesby, +ejb@klamath.uucp.leguin.org.uk, and highly revised by Joshua Kwan +(joshk@triplehelix.org) for the Debian distribution. diff --git a/doc/kline.txt b/doc/kline.txt new file mode 100644 index 0000000..6c72310 --- /dev/null +++ b/doc/kline.txt @@ -0,0 +1,101 @@ +/* doc/kline.txt - Overview of the remote kline system + * + * Copyright (C) 2005-2012 Hybrid Development Team + * + * $Id$ + */ + + +Introduction +------------ + +Since ircd-hybrid-7, opers are allowed to add and remove K-Lines on multiple +servers, an extension and replacement of the old ircd-hybrid-6 method of sharing +all K-Lines between servers. + +In this implementation, it is extended to be routable among servers which +understand the "KLN" capability. This allows us to continue to "talk" +to non remote kline capable servers without breaking anything. + + +Usage +----- + +The old K-Line method has not been changed. To place a K-Line it is still: + +/quote kline <nick|user@host> :reason +/quote kline [tkline_duration] <nick|user@host> :reason + +Scenario 1 +---------- + +Oper wishes to K-Line user@host on server irc.xyz.net + +/quote kline <nick|user@host> on irc.xyz.net :reason +/quote kline [duration] <nick|user@host> on irc.xyz.net :reason + +Scenario 2 +---------- + +Oper wishes to K-Line user@host on all servers named *.uk + +/quote kline <nick|user@host> on *.uk :reason +/quote kline [duration] <nick|user@host> on *.uk :reason + +Scenario 3 +---------- + +Oper wishes to place a network wide K-Line on user@host + +/quote kline <nick|user@host> on * :reason +/quote kline [duration] <nick|user@host> on * :reason + + +Authorization +------------- + +For the K-Line to be accepted by the remote server, the server must have +explicitly allowed K-Lines from that user. This is done via a shared {}; +block in ircd.conf. + +The shared block contains two settings, a user@host mask of the oper +who is allowed to K-Line, and a servername. + +- If both of these options are present, K-Lines will only be allowed + from that specific user@host on that specific server. +- If only the servername is present, all K-Lines from opers on that + server will be accepted. +- If only the user@host is present, all K-Lines from that user@host on + any server will be accepted. +- If neither are present, the shared block is invalid. + +shared { + /* The name of the server we allow K-Lines from */ + name = "this.server.net"; + + /* the user@host allowed to K-Line */ + user = "user@host.com"; +}; + +Server to Server Protocol +------------------------- + +As mentioned above, each server capable of remote K-Lines passes +the capability KLN along. No server will send a KLINE to a server +without a KLN capability. + +Server to server messages are formatted like this: + + ":oper KLINE target.server duration user host :reason" + +Note the difference between hybrid-6 GLINE which explicitly passed +the oper user@host and server along. This was originally done to handle +possible desync conditions, but is now shelved in favor of saving +some bandwidth. + +oper: the nick of the oper performing the K-Line +target.server: the server(s) this K-Line is destined for +duration: the duration if a TK-Line, 0 if permanent. +user: the 'user' portion of the K-Line +host: the 'host' portion of the K-Line +reason: the reason for the K-Line. diff --git a/doc/messages.txt b/doc/messages.txt new file mode 100644 index 0000000..a8c6227 --- /dev/null +++ b/doc/messages.txt @@ -0,0 +1,54 @@ + Message Customization Overview + + $Id$ + + Copyright (c) 2005-2012 by ircd-hybrid team + + ---------------------------------------------------------------------- + + Hybrid now supports its own .lang format for i18n'd IRC status messages. + + This document is split into two parts, using message files, and creating + your own. + + ---------------------------------------------------------------------- + + Using Provided or Pre-made Message Files + + There are a number of message files provided with ircd-hybrid. These can + be found in the source tree in messages/. + + These files are automatically installed by `make install'. + + These message files can be used in ircd once they are installed. Try the + installed message file with /quote SET MSGLOCALE <locale> first. The + locale will be 'standard' for the plain messages that are Hybrid's + default. + + If the desired message file works without any issues, it can be set to be + the default message file in the ircd.conf file. Refer to example.conf's + documentation on the message_locale setting. + + ---------------------------------------------------------------------- + + Creating Your Own Messages + + This process is a little more complicated. The easiest way to start + editing messages is to take ircd-standard.example.lang, make a copy, + and change whichever status lines you wish. + + Once you have your customized message file ready, just copy it into the + same place as the rest of the messages, typically $PREFIX/messages. + + If you think your .lang file deserves to be in the official distribution, + submit it to us at bugs@ircd-hybrid.org. It must be complete and as error- + free as you can make it since it is subject to public consumption. Providing + a translation will be a way that nearly anyone who knows multiple languages + to contribute to ircd, and get their name in the translation credits. + + When making such a translation, you should base it off + ircd-standard.example.lang, which is a conversion of our base (English) + messages.tab into the .lang format. You should edit it from there into your + own language, and of course give credit to yourself and whoever else you + may have done the translation with. Then, send it off to us, and we'll see + what we can do. diff --git a/doc/modeg.txt b/doc/modeg.txt new file mode 100644 index 0000000..f3b91dc --- /dev/null +++ b/doc/modeg.txt @@ -0,0 +1,144 @@ + User Mode +g Documentation + +Hybrid 7 includes a new and power feature that all users can take advantage +of to help prevent flooding and unwanted messages. This new feature is +invoked by setting user mode +g. When a client is set +g, that user will +be in "Caller ID" mode. Any user that messages a +g client will receive +a numeric saying that they are in +g (server side ignore) mode. The target +client (who is set +g) will also receive a numeric saying that so and so +messaged them, and that they are in +g mode. + +The target of the message will only receive one notification per minute, from +any client, in order to help prevent flooding. The sender will NOT have the +rate limit, and will receive a numeric saying the target is in +g mode every +time they send a message. Note that this behavior is similar to the way AWAY +messages are done. + +There are numerous benefits for both opers and regular users, including the +ability to stop spambot messages from ever reaching your client, stopping +private message and CTCP floods, and being able to sit on IRC in privacy. + +There is also a softer variation of +g named +G, which allows people you see +on your channels talk to you. In other words, messages from users/spambots +sitting on no common channels with you are automagically blocked. + +One question that arises is how to message specific users, while blocking +out everyone else. The command ACCEPT is your answer. To add a user to +your accept list, issue the raw command ACCEPT <nick>,<nick>,<nick>,... + +You will not receive a reply from the ACCEPT command if it is successful, +only if an error has occured. There are three possible errors, shown by +numerics: + + ERR_ACCEPTFULL (456): :irc.server 456 client :Accept list is full + - This is sent when an accept list is full. + ERR_ACCEPTEXIST (457): :irc.server 457 client target :already exists + - This is sent when a client tries to add a user to the accept list + that already exists there + ERR_ACCEPTNOT (458): :irc.server 458 client target :doesn't exist + - This is sent when a client tries to remove a user from their accept + list who is not on the accept list. + +That user will now be able to send messages to your client until the +association is broken. + +Associations break in one of the following situations: when an accepted user +QUIT's (or is on the other side of a split), you QUIT, or the accepted user +changes their nick. The reason why a remote user's nick change will remove +them from your accept list is so that you cannot track a user after they +changed their nick. + +Viewing the accept list is also very easy. Issue the raw command ACCEPT *. +Removing a user from your accept list is also simple. Issue the command +ACCEPT -<nick>. + + Sample Session + +The easiest way to see how this works is by experiencing it. Seeing a sample +session can help understand what goes on though. + +Client Hwy-LL is set +g initially. +Client Hwy101 wants to message Hwy-LL + +Note that some clients may have to use /quote ACCEPT instead of /accept. + +-- + +Client Hwy101: /msg Hwy-LL hi +Hwy101 will see: -Hwy-LL- *** I'm in +g mode (server side ignore). + -Hwy-LL- *** I've been informed you messaged me. + +Hwy-LL will see: Client Hwy101 [wcampbel@admin.irc.monkie.org] is messaging + you and you are +g + +The sender will receive the numeric from the target of the message, while +the recipient will receive the numeric from the server. + +-- + +If Hwy101 sends another message to Hwy-LL (before the minute expires), he will +see: -Hwy-LL- *** I'm in +g mode (server side ignore). +and will not receive the second numeric + +Hwy-LL will NOT see any numeric. + +-- + +Hwy-LL now wishes to see messages from Hwy101 and SpamBot + +Client Hwy-LL: /accept Hwy101,SpamBot + +Neither side will be told of the change in the accept list, Hwy-LL should +presume that the accept was successful if no error occurs. + +Now Hwy-LL can see messages from Hwy101 and SpamBot without any blockage. +If Hwy101 was also set +g, then he would have to issue /accept Hwy-LL +before he would be able to see messages from Hwy-LL. + +-- + +Hwy-LL now wants to see who is on his accept list. + +Client Hwy-LL: /accept * + +Hwy-LL will see: + irc.server 281 Hwy-LL Hwy101 SpamBot + irc.server 282 Hwy-LL :End of /ACCEPT list + +The replies are in numeric form to help parsing by scripts. +-- + +Hwy-LL realises he added a spambot to his list, and wants to remove it, and +allow messages from services + +Client Hwy-LL: /accept -SpamBot,services + +Hwy-LL will now only accept messages from Hwy101 and services. + +-- + +The nicks to be added can be in ANY order, however you cannot add or remove +AND list. + /ACCEPT x,y,-z,f,-a would be acceptable. + /ACCEPT x,y,-z,* would ignore the * and generate an invalid nick + response. + +Like Dalnet and Undernet's SILENCE system, the accept list only exists while +you are connected to IRC. In order for you to have the same accept list +every time you come onto IRC, you must put the accept commands into your +client's auto-perform, or manually issue the commands each time. + +This system may seem similar to the SILENCE system, but it is actually a +reverse SILENCE. SILENCE ignores certain users and allows the rest. Mode ++g ignores all users except certain ones (on your accept list.) Both systems +have their place, but the mode +g in Hybrid 7 is what the developers thought +would be most useful for clients. + +The goals of this user mode is to provide protection from flooding and +spamming, and to provide users with a means to keep their privacy. + +We hope that these goals are obtained. + +-- +W. Campbell +$Id$ diff --git a/doc/modes.txt b/doc/modes.txt new file mode 100644 index 0000000..0a5e4fb --- /dev/null +++ b/doc/modes.txt @@ -0,0 +1,72 @@ + User and Channel Modes Guide + ---------------------------- + +In /VERSION one might see something like this: + +irc.corefailure.com hybrid-7beta5 oiwszcerkfydnxbaugl biklmnopstveIh bkloveIh + +These describe the user modes, channel modes, and channel modes that require +arguments that are available to the user. It is hardcoded into src/messages.tab. + +Here is a guide to the preceding modes: + +User Modes: + ++a - admin - Admin status. Can for example see IPs in "STATS c" ++b - bots - See bot and drone flooding notices ++c - cconn - Client connection/quit notices ++D - deaf - Don't receive channel messages ++d - debug - See debugging notices ++f - full - See I: line full notices ++G - softcallerid - Server Side Ignore for users not on your channels ++g - callerid - Server Side Ignore (see modeg.txt) ++h - hidden - Hides operator status to other users ++i - invisible - Not shown in NAMES or WHO unless you share a channel ++j - rej - See rejected client notices ++k - skill - See server generated KILL messages ++l - locops - See LOCOPS messages ++n - nchange - See client nick changes ++o - oper - Operator status ++r - registered - User has been registered and identified for its nick. + This mode can be set by servers and services only. ++R - regonly - Only registered clients may message you ++s - servnotice - See general server notices ++u - unauth - See unauthorized client notices ++w - wallop - See server generated WALLOPS ++x - external - See remote server connection and split notices ++y - spy - See LINKS, STATS (if configured), TRACE notices ++z - operwall - See oper generated WALLOPS + +Channel Modes: + ++b - ban - Channel ban on nick!user@host ++e - exempt - Exemption from bans ++I - invex - Invite exceptions, nick!user@host does not need to be + explicitly INVITE'd into the channel before being able + JOIN ++i - invite - Invite only ++k - key - Key/password for the channel ++l - limit - Limit the number of users in a channel ++m - moderated - Users without +v/h/o cannot send text to the channel ++n - noexternal - Users must be in the channel to send text to it ++o - chanop - Full operator status ++O - operonly - This mode will prevent anyone who hasn't obtained + IRCOp status from joining the channel. Can be set by an IRCOp + only ++p - private - Private is obsolete, this now restricts KNOCK, and can be + set at the same time as +s. ++r - registered - Channel has been registered ++R - regonly - Only registered clients may join a channel with that mode set ++s - secret - The channel does not show up on NAMES or LIST or in the + WHOIS channel list unless you are a member of the channel ++S - sslonly - This mode will prevent anyone who isn't securely connected + via SSL/TLS from joining the channel. ++t - topic - Only chanops can change the topic ++v - voice - Can speak in a moderated channel, and is exempt from flood + restrictions + +The third part of the 004 numeric lists channel modes that require arguments. +Currently these are bkloveIh. + + +# $Id$ diff --git a/doc/resv.txt b/doc/resv.txt new file mode 100644 index 0000000..d1e0fdc --- /dev/null +++ b/doc/resv.txt @@ -0,0 +1,115 @@ +/* + * doc/resv.txt - Overview of the resv system + * Lee Hardy <lee@leeh.co.uk> + * + * Copyright (C) 2001 Hybrid Development Team + * + * $Id$ + */ + + RESV + -======- + +- What is resv, and why was it coded? + + Resv is a method of 'juping' or 'reserving' nicks and channels, to prevent + local clients using them. It is commonly used to block channels which + are home to abusers, and which attract DoS. It can also be used to stop + people pretending to be services, on a network that doesn't support them. + + It was coded to replace the method in hybrid-6 of blocking channels and + nicks, and was implemented in a much cleaner way to make it faster. + + The hybrid-6 method used to have to physically create channels, and + suffered flaws, resv does not. + +- How can I create a resv? + + There are two types of resv. 'permanent' and 'temporary'. Temporary + resv's will be erased when a server restarts (they will stay through a + rehash). Permanent resv's will stay through a restart. + + You may add permanent resv's into ircd.conf, but they are deprecated. + They should have the reason for the resv, followed by the nicks and + channels being resv'd. The following would block the channel + #services, the nick 'services' and any nick ending in 'serv' (ie: chanserv) + + resv { + reason = "There are no services on this network"; + channel = "#services"; + nick = "services"; + nick = "*serv"; + }; + + All resv's created by RESV are stored in cresv.conf or nresv.conf depending + on the nature of the RESV. + + Syntax: /quote resv <#channel|nick> :<reason> + + So to resv #warez: + /quote resv #warez :No warez on this network. + + To resv kiddie01: + /quote resv kiddie01 :Abuse + + To resv clone*: + /quote resv clone* :clones + + If a non admin does this, he will see: + -irc.leeh.co.uk- You must be an admin to perform a wildcard RESV + +- How do I remove a resv? + + If the resv is stored in ircd.conf, then the resv must be removed from there, + then a /rehash, should do the trick. + + If the resv was made using /RESV, then use the unresv command: + + Syntax: /quote unresv <#channel|nick> + +- Can I make a resv on all servers? + + No. In Hybrid resv's are local only. If a channel is full of abusers, + the solution is not to just block the channel, the abusers themselves + should be removed through /kline and /dline. + +- How do I list resv's? + + To list all current resv's: + /stats q + + Which will give a reply like: + q #warez No warez *@* + Q hax No hackers allowed here + + If the first letter is a 'q', then the resv is in [cn]resv.conf, if the + first letter is a 'Q' then the resv is hardcoded (in ircd.conf). + +- What does a client see if they try using a channel/nick that is resv'd? + + They see the numeric 437 (ERR_UNAVAILRESOURCE) + + Other networks (namely IRCNet) use this numeric on a split, to indicate + the channel cannot be joined, as such it is recognised by a lot of + clients. + +- Can an oper see when someone tries to use a resv'd nick/channel? + + No. When there is a valid reason for this, then possibly, but I honestly + don't see why anyone needs it. + +- Can I resv a local channel? + + Yes. It takes the same format as creating a resv on a normal channel: + /resv &clones :no clonebots! + +- Do you support wildcard channel resv's? + + No. This is mainly for speed reasons. When we are searching nicks, we + cannot just check if the nick, and the item in the list of resv'd nicks + are string equal, we have to check if they match, so we have to search a + full list. With channels however, we can search a hash table to see if an + entry exists, if it doesn't, then the channel isn't resv'd. We don't have + to search through all the channels. + + Besides.. it's legal for a channel to be called #*warez* anyway ;) diff --git a/doc/server-version-info b/doc/server-version-info new file mode 100644 index 0000000..619f823 --- /dev/null +++ b/doc/server-version-info @@ -0,0 +1,48 @@ + Server VERSION Info + + $Id$ + + Copyright (c) 2005 by ircd-hybrid team + + ---------------------------------------------------------------------- + + Updated for Hybrid 7.2 (2005/08/20) + + When you type /VERSION, you will often see something like this: + + hybrid-7.2beta1(20050820_4). test1.chatjunkies.org :eGgHIKMZ6 TS6ow + + Ever wondered what those funny chars mean after the version number? Well + here they are: + + +----------------------------+ + | 'e' | USE_EXCEPT | + |------+---------------------| + | 'G' | GLINES | + |------+---------------------| + | 'g' | NO_FAKE_GLINES | + |------+---------------------| + | 'H' | HUB | + |------+---------------------| + | 'I' | USE_INVEX | + |------+---------------------| + | 'K' | USE_KNOCK | + |------+---------------------| + | 'M' | IDLE_FROM_MSG | + |------+---------------------| + | 'Z' | ZIPLINKS | + |------+---------------------| + | 'T' | IGNORE_BOGUS_TS | + |------+---------------------| + | '6' | IPv6 | + |------+---------------------| + | --- | ------------------- | + |------+---------------------| + | 'TS' | Supports TS | + |------+---------------------| + | '6' | TS Version 6 | + |------+---------------------| + | 'o' | TS Only | + |------+---------------------| + | 'w' | TS Warnings | + +----------------------------+ diff --git a/doc/serverhide.txt b/doc/serverhide.txt new file mode 100644 index 0000000..83fd850 --- /dev/null +++ b/doc/serverhide.txt @@ -0,0 +1,120 @@ + Server Hide Reference + + $Id$ + + Copyright (c) 2001-2012 by ircd-hybrid team + + ---------------------------------------------------------------------- + + Due to pressures from abusers, the Hybrid developers have created a set of + options to limit what users can and cannot do on the server. Each option + can be enabled or disabled at runtime. + + This document describes the ircd-hybrid implementation of the server hiding + ideas originated by (and credited to) numerous people. + + * LINKS as a file: This option is always enabled. It will generate a + file at a certain interval, defined by the links_delay in ircd.conf, + that contains the current LINKS data. This data is sent to users + whenever a LINKS is requested. Opers will always see the current + server structure. + + The file that the LINKS data is stored in is by default etc/links.txt. + + The benefits of this are that transient splits will not be seen by + users issuing LINKS commands, and if a server is split, users can + still see what other servers are normally available. + + * Flattened LINKS: This option forces every server to look as if it is + connected to the local server. Users will see a flat LINKS tree. + + The benefit to using LINKS flattening is that users cannot get + information on how servers are routed. + + The flatten_links in the serverhide {} block in the ircd.conf controls + this feature. + + As a side effect, all netsplit quit messages will appear to originate + from the local server. + + +--------------------------------------------------------------------+ + | Flattened LINKS is needed for any network that uses the hidden hub | + | option. See below for more details. | + +--------------------------------------------------------------------+ + + + + * Hidden server option: This option will hide the server from a + flattened LINKS list on other servers. Opers will of course see the + true routing of the network. + + This is controlled by the hidden option in ircd.conf. + + +--------------------------------------------------------------------+ + | Technically, this code is a hack. With this option enabled, the | + | server will prepend '(H) ' to the server info field when | + | connecting to other servers. Other servers must understand that | + | the (H) means hidden. | + +--------------------------------------------------------------------+ + + * The allow_hidden option is needed to allow servers to use the hidden + server option described above. + + * The hide_servers option forces the server to not be shown when a user + issues WHOIS and other commands which may show what server a user is + on. + + Local user counts, as normally displayed in LUSERS, USERS, and the 255 + numeric, will be shown with the same values as the global counts. + Displaying it this way will help protect servers and avoid breaking + scripts that depend on the 265 and 266 numerics on connect. + + To be effective, this option must be used network wide. + + * The disable_remote_commands option takes care of most of the remaining + issues. These include, for example, ADMIN some.hub.server, VERSION + someuser, and similar commands. A server with this option enabled will + only prevent local users from issuing remote commands. Remote users + will not be affected. + + Remote WHOIS is not blocked. It is, however, restricted to only + querying WHOIS nick nick. The ircd will disregard the server parameter + and always use queried nick. + + * All server modes appear to originate from the server you are using. + This feature is not tunable; and opers also do not see the real server + setting the mode. + + Each item is briefly described in the serverhide {} block in ircd.conf. + + ---------------------------------------------------------------------- + +Using Non-QS Compliant Hubs + + The flattened LINKS option will, as a side effect, display all user QUITs + due to network splits in the following format: + + :user QUIT :*.net *.split + + This works extremely well as long as all servers on your network are + compliant with the QS capability, which sends a single SQUIT to the + network when a server (or tree of servers) splits. All quit messages are + generated on the local server. Certain older servers do not have this + ability, and as such will generate their own quit messages for users who + left because of the split. This can cause leaks in the hub server names + and the structure of the network. + + A quick example is the following network structure: + + servA(Hyb7) --- hubA(nonQS) --- servB(not-important) + + When servB splits from hubA, hubA will generate a QUIT command for every + user on servB (and anything behind servB). Since the QUIT message was not + created on your server, with server hiding enabled, the QUIT message will + contain the real server names. + + The only way to prevent this leak on a network is to only use hubs + supporting the QS capability. Hybrid 6, Hybrid 7, and csircd all are + currently running daemons that support QS. Hybrid 5 and 2.8.21+CSr servers + do not support QS, and will leak server names (and therefore routing + information) on splits. diff --git a/doc/technical/draft-mitchell-irc-capabilities-01.txt b/doc/technical/draft-mitchell-irc-capabilities-01.txt new file mode 100644 index 0000000..f0c6736 --- /dev/null +++ b/doc/technical/draft-mitchell-irc-capabilities-01.txt @@ -0,0 +1,1298 @@ + +Network Working Group K. Mitchell +Internet-Draft P. Lorier +Expires: September 5, 2005 Undernet IRC Network + L. Hardy + ircd-ratbox + P. Kucharski + IRCnet + March 7, 2005 + + IRC Client Capabilities Extension + draft-mitchell-irc-capabilities-01 + +Status of this Memo + + This document is an Internet-Draft and is subject to all provisions + of section 3 of RFC 3667. By submitting this Internet-Draft, each + author represents that any applicable patent or other IPR claims of + which he or she is aware have been or will be disclosed, and any of + which he or she become aware will be disclosed, in accordance with + RFC 3668. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF), its areas, and its working groups. Note that + other groups may also distribute working documents as + Internet-Drafts. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + The list of current Internet-Drafts can be accessed at + http://www.ietf.org/ietf/1id-abstracts.txt. + + The list of Internet-Draft Shadow Directories can be accessed at + http://www.ietf.org/shadow.html. + + This Internet-Draft will expire on September 5, 2005. + +Copyright Notice + + Copyright (C) The Internet Society (2005). + +Abstract + + IRC (Internet Relay Chat) is a long-standing protocol for real-time + chatting. The basic client-server protocol is a very simple + text-based protocol with no explicit mechanism for introducing or + + +Mitchell, et al. Expires September 5, 2005 [Page 1] +Internet-Draft IRC CAP March 2005 + + negotiating backwards-incompatible extensions. This memo presents a + mechanism for negotiation of such extensions. + +Requirements Language + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and + "OPTIONAL" in this document are to be interpreted as described in RFC + 2119 [1]. + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 + + 2. Problems to be Solved . . . . . . . . . . . . . . . . . . . . 4 + + 3. The CAP Command . . . . . . . . . . . . . . . . . . . . . . . 5 + 3.1 CAP LS . . . . . . . . . . . . . . . . . . . . . . . . . . 6 + 3.2 CAP LIST . . . . . . . . . . . . . . . . . . . . . . . . . 6 + 3.3 CAP REQ . . . . . . . . . . . . . . . . . . . . . . . . . 7 + 3.4 CAP ACK . . . . . . . . . . . . . . . . . . . . . . . . . 7 + 3.5 CAP NAK . . . . . . . . . . . . . . . . . . . . . . . . . 8 + 3.6 CAP CLEAR . . . . . . . . . . . . . . . . . . . . . . . . 8 + 3.7 CAP END . . . . . . . . . . . . . . . . . . . . . . . . . 8 + + 4. Capability Negotiation . . . . . . . . . . . . . . . . . . . . 10 + + 5. Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . 11 + 5.1 Capability Modifiers . . . . . . . . . . . . . . . . . . . 11 + + 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 13 + + 7. Security Considerations . . . . . . . . . . . . . . . . . . . 14 + + 8. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 15 + + 9. References . . . . . . . . . . . . . . . . . . . . . . . . . . 15 + + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 15 + + A. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 + + B. ABNF Description of Capabilities . . . . . . . . . . . . . . . 19 + + C. ChangeLog . . . . . . . . . . . . . . . . . . . . . . . . . . 21 + + Intellectual Property and Copyright Statements . . . . . . . . 28 + + +Mitchell, et al. Expires September 5, 2005 [Page 2] +Internet-Draft IRC CAP March 2005 + +1. Introduction + + The IRC protocol, as originally documented by RFC 1459 [2] and + updated by RFC 2812 [3], is a simple, text-based conferencing + protocol, involving a number of users spread across a number of + interconnected servers. These users may chat with other individual + users, or may chat with groups of users on "channels"--what other + chat systems refer to as "rooms" or "chat rooms". + + Over the years, various extensions to the basic IRC protocol have + been made by IRC server programmers. Often, these extensions are + intended to conserve bandwidth, close loopholes left by the original + protocol specification, or add features for users or for the server + administrators. Most of these changes are backwards-compatible with + the original protocol specification: A command may be added, a reply + may be extended to contain more parameters, etc. Recently, however, + there has been a desire to introduce changes that would not be + backwards-compatible with existing IRC clients. Ideally, these + protocol changes would only be used with clients and servers that can + understand the revised protocol. Unfortunately, the IRC protocol + does not provide any form of extension or protocol negotiation, + making it impossible to determine support for such extensions. + + This memo introduces a standardized mechanism for negotiation of + protocol extensions, known as *capabilities*, that will be + backwards-compatible with all existing IRC clients and servers. Any + server not implementing this extension will still interoperate with + clients that do implement it; similarly, clients that do not + implement the capabilities extension may successfully communicate + with a server that does implement the extension. + + + + + + + + + + + +Mitchell, et al. Expires September 5, 2005 [Page 3] +Internet-Draft IRC CAP March 2005 + +2. Problems to be Solved + + The IRC protocol is not a lockstep protocol. This means that a + client may issue additional commands before the server has finished + responding to the first one. Additionally, unlike other protocols, + the server does not necessarily issue a banner response upon initial + connection. This, combined with the fact that some servers do not + complain about unknown commands prior to completion of the client + registration phase, means that a client cannot know for certain + whether a server implements the extension. If a client had to wait + for a banner message, it would fail to interoperate with a server not + implementing the capabilities extension. If the client must issue a + command and then wait for a response, a similar problem results. As + some potential protocol extensions must be set up prior to completion + of the client registration phase, there is no reliable way a server + may indicate implementation of the capabilities extension to a + client. + + The solution to these problems turns out to be to extend the client + registration procedure. The client sends a request to begin + capability negotiation, as well as the other information necessary + for client registration (user name, nick name, optional password, + etc.). If the server understands the capabilities extension, it will + suspend completion of the registration phase until the negotiation is + complete; negotiation may then proceed in a lockstep fashion. If the + server does not understand capabilities, then the registration will + complete immediately, and the client will receive the 001 numeric. + This will signal to the client that the server does not implement the + capabilities extension. + + + + + + + + + + + +Mitchell, et al. Expires September 5, 2005 [Page 4] +Internet-Draft IRC CAP March 2005 + +3. The CAP Command + + The capabilities extension is implemented by addition of one command + with several subcommands. The command added is *CAP*. CAP takes a + single, required subcommand, optionally followed by a single + parameter consisting of a space-separated list of capabilities. Each + capability within the list MAY be preceded by a capability modifier. + (Section 5.1) + + The subcommands defined for CAP are: + + 1. LS (Section 3.1) + 2. LIST (Section 3.2) + 3. REQ (Section 3.3) + 4. ACK (Section 3.4) + 5. NAK (Section 3.5) + 6. CLEAR (Section 3.6) + 7. END (Section 3.7) + + The LS (Section 3.1), LIST (Section 3.2), REQ (Section 3.3), ACK + (Section 3.4), and NAK (Section 3.5) subcommands may be followed by a + single parameter consisting of a space-separated list of capability + names. If more than one capability is named, this argument MUST be + preceded by the IRC protocol colon (':') sentinel to signal that the + remainder of the line is a single argument. + + If a client sends a subcommand not listed above or issues an invalid + command, the server SHOULD reply with the ERR_INVALIDCAPCMD numeric + response, 410. The first parameter after the client nickname SHALL + be the subcommand the client sent; the second parameter SHOULD be a + textual description of the error. + + In ABNF [4] notation: + + capcmd = [ ":" servername SP ] "CAP" SP subcmd + + subcmd = lscmd / listcmd / reqcmd / ackcmd / + nakcmd / clearcmd / endcmd + + capcmderr = ":" servername SP "410" SP nick SP badcmd + SP ":Invalid CAP subcommand" + ; badcmd is the unrecognized subcommand + + caplist = [ ":" ] *( capmod ) capab + caplist =/ ":" *( capmod ) capab 1*( SP *( capmod ) capab ) + + where SP is as designated in Appendix A of RFC 2234 [4], and + servername and nick are as designated in section 2.3.1 of RFC 1459 + + +Mitchell, et al. Expires September 5, 2005 [Page 5] +Internet-Draft IRC CAP March 2005 + + [2]. + + The discussion in the following sections applies only to clients and + servers implementing the capabilities extension. Servers (and + clients) not implementing the capabilities extension are exempted + from the requirements of this section. + +3.1 CAP LS + + The LS subcommand is used to list the capabilities supported by the + server. The client SHALL send an LS subcommand with no arguments to + solicit a list of supported capabilities from the server. Servers + MUST respond to such LS subcommands with one or more LS subcommands + containing the list of recognized capabilities. All but the last + subcommand MUST have a parameter containing only an asterisk ('*') + preceding the capability list. + + If a client issues an LS subcommand during the client registration + phase, client registration MUST be suspended until an END (Section + 3.7) subcommand is received. + + ABNF [4] description of the LS subcommand: + + lscmd = "LS" + lscmd =/ "LS" SP [ "*" SP ] caplist + +3.2 CAP LIST + + The LIST subcommand is provided to permit the client to request a + list of the capabilities currently active for the connection. It is + similar to the LS (Section 3.1) subcommand--if a client issues a LIST + subcommand with no arguments, the server MUST respond with a sequence + of LIST subcommands, all but the last of which MUST have a single + parameter consisting solely of an asterisk ('*') preceding the list + of capabilities. If no capabilities have been enabled, the server + MUST send a LIST command with an empty capability list; the parameter + MUST NOT be omitted. The active capabilities MAY be listed in any + order. + + ABNF [4] description of the LIST subcommand: + + listcmd = "LIST" + listcmd =/ "LIST" SP ":" + listcmd =/ "LIST" SP [ "*" SP ] caplist + + + +Mitchell, et al. Expires September 5, 2005 [Page 6] +Internet-Draft IRC CAP March 2005 + +3.3 CAP REQ + + The REQ subcommand is sent by the client to request that a capability + or set of capabilities be enabled or disabled. Its sole parameter + MUST be a space-separated list of capabilities. Each capability name + MAY be preceded by a dash ('-') to indicate that the capability + should be disabled. Additionally, receipt of this subcommand during + the client registration MUST suspend client registration until an END + (Section 3.7) subcommand is received. + + Servers MUST respond to a REQ command with either the ACK (Section + 3.4) or NAK (Section 3.5) subcommands to indicate acceptance or + rejection of the capability set requested by the client. A server + MUST accept the entire capability set or reject it whole; servers + MUST NOT accept some capabilities in the set while rejecting others. + If a client requests that a "sticky" capability be disabled, the + server MUST reject the capability set. + + ABNF [4] description of the REQ subcommand: + + reqcmd = "REQ" SP caplist + +3.4 CAP ACK + + The ACK subcommand has three uses. It is used by the server to + acknowledge a REQ (Section 3.3) subcommand; by the server to + acknowledge a CLEAR (Section 3.6) subcommand and list the removed + capabilities; and by the client to acknowledge certain capabilities + designated as requiring acknowledgment. If more than one ACK is + required due to the IRC line length limitation of 512 characters, all + but the last SHALL contain a parameter consisting of a single + asterisk ('*') immediately preceding the list of capabilities, as for + LS (Section 3.1) and LIST (Section 3.2). + + If an ACK reply originating from the server is spread across multiple + lines, a client MUST NOT change capabilities until the last ACK of + the set is received. Equally, a server MUST NOT change the + capabilities of the client until the last ACK of the set has been + sent. + + In the first usage, acknowledging a REQ (Section 3.3) subcommand, the + ACK subcommand has a single parameter consisting of a space separated + list of capability names, which may optionally be preceded with one + or more modifiers (Section 5.1). + + The second usage, acknowledging a CLEAR (Section 3.6) subcommand, is + similar to the first usage. When a CLEAR (Section 3.6) subcommand is + + +Mitchell, et al. Expires September 5, 2005 [Page 7] +Internet-Draft IRC CAP March 2005 + + issued, all non-"sticky" capabilities are disabled, and a set of ACK + subcommands will be generated by the server with the disable modifier + preceding each capability. + + The third usage is when, in the preceding two cases, some capability + names have been preceded with the ack modifier. ACK in this case is + used to fully enable or disable the capability. Clients MUST NOT + issue an ACK subcommand for any capability not marked with the ack + modifier in a server-generated ACK subcommand. + + ABNF [4] description of the ACK subcommand: + + ackcmd = "ACK" SP [ "*" SP ] caplist + +3.5 CAP NAK + + The NAK subcommand MUST be sent by the server in response to a REQ + (Section 3.3) subcommand when any capability change requested cannot + be performed for any reason. The server MUST NOT make any change to + the set of capabilities for the client if it responds with a NAK + subcommand. The argument of the NAK subcommand MUST consist of at + least the first one hundred characters of the capability list in the + REQ (Section 3.3) subcommand which triggered the NAK. + + ABNF [4] description of the NAK subcommand: + + nakcmd = "NAK" SP ":" acklist + ; acklist is at least 100 characters of the + ; capability list from the REQ + +3.6 CAP CLEAR + + The CLEAR subcommand requests that the server clear the capability + set for the client. The server MUST respond with a set of ACK + (Section 3.4) subcommands indicating the capabilities being + deactivated. + + ABNF [4] description of the CLEAR subcommand: + + clearcmd = "CLEAR" + +3.7 CAP END + + The END subcommand signals to the server that capability negotiation + is complete and requests that the server continue with client + + +Mitchell, et al. Expires September 5, 2005 [Page 8] +Internet-Draft IRC CAP March 2005 + + registration. If the client is already registered, this command MUST + be ignored by the server. + + Clients that support capabilities but do not wish to enter + negotiation SHOULD send CAP END upon connection to the server. + + ABNF [4] description of the END subcommand: + + endcmd = "END" + + + + + + + + + + + + + + + + + + + + + +Mitchell, et al. Expires September 5, 2005 [Page 9] +Internet-Draft IRC CAP March 2005 + +4. Capability Negotiation + + Clients implementing this extension SHOULD take one of the following + three actions upon initial connection to a server: + + o Issue an LS (Section 3.1) subcommand (with an empty capability + list) to solicit a list of supported capabilities from the server; + + o Issue the REQ (Section 3.3) subcommand to request a particular set + of capabilities without knowing what capabilities the server + supports or if it supports the capabilities extension; or + + o Issue the END (Section 3.7) subcommand to signal implementation of + the capabilities extension without entering into capability + negotiation. + + Although a client is permitted to not issue any CAP commands upon + connection, this is NOT RECOMMENDED. Servers MAY assume a client + does not implement the capabilities extension if it does not issue + any CAP commands upon initial connection. + + Clients SHOULD follow CAP commands issued upon connection with the + standard IRC client registration commands without waiting for any + responses from the server. See RFC 1459 [2] for more details about + the client registration procedure. + + If a client issues the LS (Section 3.1) or REQ (Section 3.3) + subcommands during the client registration procedure, a server + implementing the capabilities extension MUST NOT complete the client + registration until the client issues the END (Section 3.7) + subcommand. A client that sees a RPL_WELCOME (001) numeric response + before it sends CAP END (Section 3.7) SHOULD assume that the server + does not support the capabilities extension. + + Once the client is registered, CAP commands SHALL have no effect on + other connection operations, except that a client MAY change the + capabilities it has set. In particular, CAP commands and their + responses MAY be interspersed with other protocol messages. The END + (Section 3.7) subcommand SHALL have no effect once client + registration has been completed. + + + + + + +Mitchell, et al. Expires September 5, 2005 [Page 10] +Internet-Draft IRC CAP March 2005 + +5. Capabilities + + Capabilities are designated by a name composed of one or more + elements. Name elements are not case-sensitive. They must begin + with a letter and may contain any number of letters, numbers, and the + dash character ('-'). Names containing more than one name element + MUST also contain a period character ('.') in the first name element. + Name elements are separated from each other via the slash character + ('/'). + + There are two capability name spaces: + + Network Specific: Names whose first element contains a period + character ('.') designate a delegated capability name space. The + first element MUST be a valid, existing DNS domain name. These + names MUST contain at least two elements. + + Standardized: All other names MUST correspond to capabilities + documented by an RFC. Further, these names MUST contain only one + element. + + These rules are summarized by the following ABNF [4] representation: + + elem = ALPHA *( ALPHA / DIGIT / "-" ) + + netname = elem 1*( "." elem ) + + netDeleg = netname 1*( "/" elem ) + + standardized = elem + + capab = netDeleg / standardized + + where ALPHA and DIGIT are as designated in Appendix A of RFC 2234 + [4]. + +5.1 Capability Modifiers + + There are various capability modifiers available. If a capability + modifier is to be used, it MUST directly precede the capability name. + The following are the modifiers defined for capabilities. Certain + modifiers MAY be combined. + + The disable modifier is used by both the server and the client to + indicate that a capability should be disabled. The disable modifier + is defined as the dash character ('-'). A client MUST only use the + disable modifier in the REQ (Section 3.3) and ACK (Section 3.4) + subcommands. A server MUST use the disable modifier in the ACK + + +Mitchell, et al. Expires September 5, 2005 [Page 11] +Internet-Draft IRC CAP March 2005 + + (Section 3.4) subcommand when disabling a capability, or in + conjunction with a ack modifier in the LIST (Section 3.2) subcommand. + The server MUST NOT use the disable modifier in any other command + response. + + The sticky modifier is used by the server to indicate a capability + that, once enabled, cannot be disabled. The sticky modifier is + defined as the equals character ('='). A client MUST NOT use the + sticky modifier. A server MUST only use the sticky modifier in the + ACK (Section 3.4), LIST (Section 3.2) and LS (Section 3.1) + subcommands and MUST use the modifier for all such capabilities. + + The ack modifier is used by the server to indicate that the client + must issue an ACK (Section 3.4) subcommand to fully enable or disable + the capability. The ack modifier is defined as the tilde character + ('~'). The ack modifier indicates that traffic originating from the + server SHALL make use of the capability, but the server SHALL NOT + expect traffic originating from the client to make use of the + capability. When combined with the disable modifier, it indicates + traffic originating from the server SHALL NOT make use of the + capability, but the server expects traffic originating from the + client SHALL make use of the capability. The ack modifier MAY be + combined with the sticky modifier. + + A server MUST use the ack modifier in the ACK (Section 3.4) and LIST + (Section 3.2) subcommands to indicate capabilities that require an + ACK (Section 3.4) subcommand from the client to be fully enabled or + disabled. Servers MUST also use the ack modifier in the response to + an LS (Section 3.1) subcommand to indicate capabilities which will + require ACK (Section 3.4) subcommands from the client. Clients MUST + NOT use the ack modifier, but SHOULD issue the ACK (Section 3.4) + subcommand as soon as possible after receiving an ACK (Section 3.4) + or REQ (Section 3.3) subcommand from the server that contains a + capability marked with the ack modifier. + + In ABNF [4] notation: + + dismod = "-" + stickymod = "=" + ackmod = "~" + + capmod = dismod / stickymod / ackmod + + + + + +Mitchell, et al. Expires September 5, 2005 [Page 12] +Internet-Draft IRC CAP March 2005 + +6. IANA Considerations + + The standardized capability name space shall be managed by IANA in + accordance with the description of capability names in Section 5. In + particular, any name not containing the period character ('.') must + be specified by an RFC. + + + + + + + + + + + + + + + + + + + + + + + +Mitchell, et al. Expires September 5, 2005 [Page 13] +Internet-Draft IRC CAP March 2005 + +7. Security Considerations + + Capabilities are an extension to a preexisting, insecure chat + protocol. This extension does not add and does not purport to add + any security to the IRC protocol. Capability negotiation occurs + after client registration has already begun. Moreover, no mechanism + is defined that allows parameters to be passed for specific + capabilities. Although such a mechanism could be added, + cryptographic security systems frequently require several exchanges + to establish a secure context, particularly if authentication must + also be negotiated. Thus, the capabilities extension is unsuited to + the implementation of those protocols, and other mechanisms, such as + SSL-encapsulated IRC, should be used. + + + + + + + + + + + + + + + + + + + +Mitchell, et al. Expires September 5, 2005 [Page 14] +Internet-Draft IRC CAP March 2005 + +8. Acknowledgments + + The authors wish to gratefully acknowledge the participation of Aaron + Wiebe and the members of the proto-desc@dal.net email list in the + design of this protocol extension. + +9 References + + [1] Bradner, S., "Key words for use in RFCs to Indicate Requirement + Levels", BCP 14, RFC 2119, March 1997. + + [2] Oikarinen, J. and D. Reed, "Internet Relay Chat Protocol", RFC + 1459, May 1993. + + [3] Kalt, C., "Internet Relay Chat: Client Protocol", RFC 2812, + April 2000. + + [4] Crocker, D. and P. Overell, "Augmented BNF for Syntax + Specifications: ABNF", RFC 2234, November 1997. + + [5] Bradner, S., "IETF Rights in Contributions", BCP 78, RFC 3667, + February 2004. + +Authors' Addresses + + Kevin L. Mitchell + Undernet IRC Network + 38 Eighth St., Apt. 7 + Cambridge, Massachusetts 02141 + US + + Phone: +1-617-230-1021 + EMail: klmitch@mit.edu + URI: http://www.mit.edu/~klmitch/ + + Perry Lorier + Undernet IRC Network + 3 Liston Cres + Hamilton, Waikato 2001 + NZ + + Phone: +64-7-859-1109 + EMail: isomer@undernet.org + + + +Mitchell, et al. Expires September 5, 2005 [Page 15] +Internet-Draft IRC CAP March 2005 + + Lee Hardy + ircd-ratbox Development Team + + EMail: lee@leeh.co.uk + URI: http://www.leeh.co.uk + + Piotr Kucharski + IRCnet + + EMail: Beeth@irc.pl + URI: http://42.pl/ + + + + + + + + + + + + + + + + + + + + +Mitchell, et al. Expires September 5, 2005 [Page 16] +Internet-Draft IRC CAP March 2005 + +Appendix A. Examples + + In the following examples, lines preceded by "CLIENT:" indicate + protocol messages sent by the client, and lines preceded by "SERVER:" + indicate protocol messages sent by the server. For clarity, the + origin field for server-originated protocol messages has been + omitted. This field would consist of a colon (':') followed by the + full server name, and would be the first field in the command. + + A client communicating with a server not supporting CAP. + + CLIENT: CAP LS + CLIENT: NICK nickname + CLIENT: USER username ignored ignored :real name + SERVER: 001 [...] + + A client which does not wish to enter capability negotiation. + + CLIENT: CAP END + CLIENT: NICK nickname + CLIENT: USER username ignored ignored :real name + SERVER: 001 [...] + + A client entering into capability negotiation during registration, + and requesting a set of capabilities that the server does not + support. + + CLIENT: CAP LS + CLIENT: NICK nickname + CLIENT: USER username ignored ignored :real name + SERVER: CAP LS * :A B C D E F G H + SERVER: CAP LS :I J + CLIENT: CAP REQ :A B C D E F + SERVER: CAP NAK :A B C D E F + CLIENT: CAP REQ :A C E F + SERVER: CAP ACK :A C E F + CLIENT: CAP REQ :B + SERVER: CAP ACK :B + CLIENT: CAP REQ :D + SERVER: CAP NAK :D + CLIENT: CAP END + SERVER: 001 [...] + + + + + +Mitchell, et al. Expires September 5, 2005 [Page 17] +Internet-Draft IRC CAP March 2005 + + A client requesting a capability that requires an ACK (Section 3.4) + subcommand from the client to be enabled. + + CLIENT: CAP LS + SERVER: CAP LS :~I ~J K + CLIENT: CAP REQ :I J K + SERVER: CAP ACK :~I ~J K + CLIENT: CAP ACK :I J + + A client requesting a capability that requires an ACK (Section 3.4) + subcommand from the client to be enabled and disabled, using the LIST + (Section 3.2) subcommand in between. + + CLIENT: CAP LS + SERVER: CAP LS :~A ~B + CLIENT: CAP REQ :A B + SERVER: CAP ACK :~A ~B + CLIENT: CAP LIST + SERVER: CAP LIST :~A ~B + CLIENT: CAP ACK :A B + CLIENT: CAP LIST + SERVER: CAP LIST :A B + CLIENT: CAP REQ :-B + SERVER: CAP ACK :-~B + CLIENT: CAP LIST + SERVER: CAP LIST :A -~B + CLIENT: CAP ACK :-B + CLIENT: CAP LIST + SERVER: CAP LIST :A + + A client requesting a capability that is sticky. + + CLIENT: CAP LS + SERVER: CAP LS :=I J + CLIENT: CAP REQ :I J + SERVER: CAP ACK :=I J + + A client requesting a capability be disabled. + + CLIENT: CAP LIST + SERVER: CAP LIST :=A B C D + CLIENT: CAP REQ :-B -C + SERVER: CAP ACK :-B -C + + + + +Mitchell, et al. Expires September 5, 2005 [Page 18] +Internet-Draft IRC CAP March 2005 + +Appendix B. ABNF Description of Capabilities + + This section summarizes the ABNF [4] description of the capabilities + extension. + + capcmd = [ ":" servername SP ] "CAP" SP subcmd + + subcmd = lscmd / listcmd / reqcmd / ackcmd / + nakcmd / clearcmd / endcmd + + capcmderr = ":" servername SP "410" SP nick SP badcmd + SP ":Invalid CAP subcommand" + ; badcmd is the unrecognized subcommand + + caplist = [ ":" ] *( capmod ) capab + caplist =/ ":" *( capmod ) capab 1*( SP *( capmod ) capab ) + + lscmd = "LS" + lscmd =/ "LS" SP [ "*" SP ] caplist + + listcmd = "LIST" + listcmd =/ "LIST" SP ":" + listcmd =/ "LIST" SP [ "*" SP ] caplist + + reqcmd = "REQ" SP caplist + + ackcmd = "ACK" SP [ "*" SP ] caplist + + nakcmd = "NAK" SP ":" acklist + ; acklist is at least 100 characters of the + ; capability list from the REQ + + clearcmd = "CLEAR" + + endcmd = "END" + + elem = ALPHA *( ALPHA / DIGIT / "-" ) + + netname = elem 1*( "." elem ) + + netDeleg = netname 1*( "/" elem ) + + standardized = elem + + capab = netDeleg / standardized + + dismod = "-" + stickymod = "=" + + +Mitchell, et al. Expires September 5, 2005 [Page 19] +Internet-Draft IRC CAP March 2005 + + ackmod = "~" + + capmod = dismod / stickymod / ackmod + + + + + + + + + + + + + + + + + + + + + + + + +Mitchell, et al. Expires September 5, 2005 [Page 20] +Internet-Draft IRC CAP March 2005 + +Appendix C. ChangeLog + + Note to RFC Editor: This section may be removed on publication as an + RFC. + + Here is a log of changes to this document: + + 2004-12-15 KLM Initial draft written. + + 2004-12-16 KLM + + * Added description of the argument to some CAP commands in + Section 3. + + * Clarified that requirements of Section 3 only apply to clients + and servers implementing capabilities. + + * Substitution of "performed" for "done" in Section 3.5 + + * Added LIST (Section 3.2) subcommand to provide a mechanism to + query active capabilities. + + * Added reference to RFC 2812 [3]. + + * Moved Examples (Appendix A) section into the back matter. + + * Corrected Perry Lorier's email address. + + * Added this ChangeLog section. + + * Corrected typo in Section 3.7: "sent" for "send". + + * Added <vspace> elements to enhance readability. + + * Changed to non-compact form. + + * Changed anchor for Section 5 to "capabilities" from "caps" to + reduce possible confusion. + + * Revise last sentence of first paragraph of Section 2 to remove + redundancy. + + * Revise last sentence of second paragraph of Section 2 + + * Added email addresses for Lee H and Beeth; updated contact + information for Isomer. + + + +Mitchell, et al. Expires September 5, 2005 [Page 21] +Internet-Draft IRC CAP March 2005 + + 2004-12-17 KLM + + * Augmented description of CAP command and subcommands with ABNF + description. + + * Revised Section 5 to remove "net." name space and replace it + with a delegated name space beginning with a DNS domain name + (suggested by Isomer). + + * Augmented ABNF description of capability names. + + * Revised Section 6 to reflect change in capability name space. + + * Added Appendix B to bring together the entire ABNF description + of capabilities. + + 2004-12-18 KLM + + * Added explanation of what should happen if an unrecognized + subcommand is given. + + * Clarified what to do if a client sends a subcommand that + shouldn't come from a client. + + * Add references to LIST (Section 3.2) to LSL and Section 3.1. + + * Section 3.3 omitted the caplist argument for the REQ command; + corrected. + + * Relax the prohibition against a client acknowledging a + capability that doesn't modify the protocol stream in Section + 3.4 + + * Relax the requirement for a client that understands + capabilities to send CAP END in Section 3.7 + + 2004-12-19 KLM + + * Converted a number of common xrefs into internal entities to + simplify the text. + + * Inserted some white space to make the <front> section a bit + more readable. + + * Added the keyword "Protocol". + + +Mitchell, et al. Expires September 5, 2005 [Page 22] +Internet-Draft IRC CAP March 2005 + + * Added the term "NOT RECOMMENDED" to the note on "Requirements + Language". + + * Moved LIST (Section 3.2) up in the list of CAP subcommands. + + * Minor formatting change to the ABNF representation of subcmd. + + * Capitalized "MAY" in "empty" subcommand. + + * Added text about capability list order and what to do if no + capabilities are implemented to "empty" subcommand. + + * Mention LIST (Section 3.2) also in LSL when talking about + sending more than one LSL subcommand. + + * Clarify language in Section 3.1 a little bit. + + * Substitute "set of capabilities" for "list of capabilities" in + Section 3.3. + + * Fix minor typo in preamble to ABNF description of NAK (Section + 3.5) subcommand: substitution of "ACK" for "NAK". + + * Add note about servers ignoring END (Section 3.7) after client + registration. + + * Fix minor typo in preamble to ABNF description of LIST (Section + 3.2) subcommand: substitution of "END" for "LIST". + + * Added Section 4 discussing capability negotiation. + + * Add ".xml" extension to include files in references section. + + * Simplification of preamble of first example (Appendix A). + + * Add 'type="ABNF"' to <artwork> sections so that they can be + extracted and used to create the abnf.xml now included in + Appendix B. + + * It's now RFC 3667 [5], not RFC 2026... + + 2004-12-27 KLM + + * Minor wording changes to second paragraph of Section 1 + + * Minor wording change to first paragraph of Section 2 + + +Mitchell, et al. Expires September 5, 2005 [Page 23] +Internet-Draft IRC CAP March 2005 + + * Minor wording changes to first paragraph of Section 3; remove + redundant note about the IRC colon sentinel. + + * Change a "must" to a "MUST" in Section 3.4; note that + capability list may be truncated if it would otherwise exceed + the 512 character limit. + + * In Section 3.5, note that capability list may be truncated if + it would otherwise exceed the 512 character limit. + + * Remove redundant line about ignoring END (Section 3.7) commands + after registration. + + * Correct spelling of "acknowledgments". + + * Empty <organization> elements for Lee H and Beeth; put Beeth's + real name, Piotr Kucharski, in the right place. + + * Switch to using a new preprocessor that consolidates all the + ABNF artwork and inserts it with the processing instruction + <?art type="foo"?>. + + * Remove deliberate page break after <abstract> section. + + * Reorder authors section to consolidate <organization> elements + for everyone. + + * Drop abbreviation for Undernet. + + * Expand Section 7 a bit to try to explain why capabilities are + not suited to securing IRC. + + 2005-01-04 KLM + + * Add Lee Hardy's information to the list of authors. + + 2005-01-05 KLM + + * Replace UNKNOWNCAPCMD with INVALIDCAPCMD. + + * Begin rewriting LS (Section 3.1) documentation + + + + +Mitchell, et al. Expires September 5, 2005 [Page 24] +Internet-Draft IRC CAP March 2005 + + 2005-01-19 KLM + + * Redesign the protocol substantially to simplify it. + + 2005-01-20 KLM + + * Update Piotr's contact information. + + * Drop the "x-" namespace... + + 2005-01-20 LH + + * Some servers do issue banner responses, now. + + * The CAP subcommand is now a requirement. + + * Minor grammatical fix-up in documentation of REQ (Section 3.3) + ("acceptance of or rejection of"--strike first "of"). + + * Clarify that sticky capabilities cause a REQ (Section 3.3) to + be NAK (Section 3.5)ed. + + * Mark the third case of an ACK (Section 3.4) with an explicit + indicator that it's the third case... + + * Strike redundant mention of not suspending client registration + in documentation for END (Section 3.7). + + 2005-01-21 LH + + * Move all references on capability modifiers to its own section + + * Clarify instructions on the ack ('~') modifier, indicating it + can be used with sticky capabilities. + + * Add a note into CAP section about capability modifiers + + 2005-01-21 KLM + + * Subcommands are not optional anymore; updated the description + of CAP and the ABNF to reflect this. + + * More than one modifier may precede a capability name. + + +Mitchell, et al. Expires September 5, 2005 [Page 25] +Internet-Draft IRC CAP March 2005 + + * Move ABNF for capmod into the "Capability Modifiers" section. + + * Fix a few minor grammatical errors (I think). + + * Note that capability names may be preceded by modifiers in the + first form of ACK. + + * Remove an unnecessary "MAY" in documentation for the third + usage of ACK. + + * Explicitly note in the ABNF for NAK that the parameter is an + opaque repeat of at least the first 100 characters of the + argument to REQ. + + * CLEAR may result in more than one ACK. + + * Clarify the language of what composes a capability name. + + * Add missing </figure>. + + * ACK subcommand should be sent in response to ACK with ack + modifier as soon as possible... + + * Allow disable modifier in LIST, but only in conjunction with an + ack modifier. + + * The ack modifier may also show up in an LS response; rewrote + the final paragraph to indicate that and clarify the language. + + * Add "Client" to the title in the appropriate place... + + * The "capability" rule in the ABNF got changed to "capab" for + brevity. + + * Update "date" to be current. + + 2005-01-22 LH + + * Clarify a client must not act upon an ACK spread across + multiple lines until it receives the final ACK of the set. + + 2005-01-23 KLM + + * Bump version number in preparation for any suggested edits... + + + +Mitchell, et al. Expires September 5, 2005 [Page 26] +Internet-Draft IRC CAP March 2005 + + 2005-01-26 LH + + * Clarify a server also must not change capabilities until its + finished sending its ACKs. + + 2005-01-27 KLM + + * Acknowledge Aaron Wiebe as participating. + + 2005-03-01 LH + + * Add examples on sticky modifiers, the removal modifier and the + sticky modifier. + + 2005-03-07 KLM + + * Submit second draft... + + + + + + + + + + + + + + + + +Mitchell, et al. Expires September 5, 2005 [Page 27] +Internet-Draft IRC CAP March 2005 + +Intellectual Property Statement + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at + ietf-ipr@ietf.org. + +Disclaimer of Validity + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE + INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +Copyright Statement + + Copyright (C) The Internet Society (2005). This document is subject + to the rights, licenses and restrictions contained in BCP 78, and + except as set forth therein, the authors retain all their rights. + +Acknowledgment + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + +Mitchell, et al. Expires September 5, 2005 [Page 28] diff --git a/doc/technical/event.txt b/doc/technical/event.txt new file mode 100644 index 0000000..b09b0b7 --- /dev/null +++ b/doc/technical/event.txt @@ -0,0 +1,82 @@ +Overview of the event subsystem +Adrian Chadd <adrian@creative.net.au> + +$Id$ + +One of the things that immediately struck me whilst first looking at the +code was that the ircd periodically scheduled things in io_loop() but +it did them manually. This is very wasteful and very tedious. + +Therefore, an event system was added to hybrid. src/event.c contains an +event system ported from the squid web cache. It is pretty self contained, +and only a few things (debugging, time resolution) needed changing. + +An event is scheduled through eventAdd() or eventAddIsh() : + +eventAdd(const char *name, EVH * func, void *arg, time_t when, int weight) +eventAddIsh(const char *name, EVH * func, void *arg, time_t delta_ish, + int weight) + +after 'when' (or delta_ish) seconds has elapsed from the time the above +functions are called, the 'func' is called with the given data 'arg'. The +event is then deleted. + +To delete an event, use eventDelete() : + +eventDelete(EVH * func, void *arg) + +An event is identified by its callback function and data pair. + +Events are run through eventRun(). This is designed to be called *BEFORE* +your IO handlers, to let events scheduled immediately (ie a time of 0) +to initiate IO before the IO handlers are called. + +(Believe me, its useful.) + + + +Example: + +Say you have something which must be called every 15 seconds. + +* You would first define the callback in your module: + +static EVH foo_periodic_event; +static int initialised = 0; + +* You would then add the event in your initialization function: + +void foo_init(void) +{ + if (!initialised) { + eventAdd("foo_periodic_event", foo_periodic_event, NULL, 0, 0); + initialised = 1; + } +} + + This will force the event to be called the next time eventRun() is called, + rather than waiting 15 seconds. + +* You then define your event callback: + +static void +foo_periodic_event(void *data) +{ + /* We'd do our work here */ + + /* Then we'd finish */ + eventAdd("foo_periodic_event", foo_periodic_event, NULL, 15, 0); +} + + +Notes: + +* I really should change the timeout value to be in milliseconds. Squid used + a double, but Dianora had something against floating point code in the main + loop (which is understandable). If someone wants a fun task .. :-) + +* Note that the 'name' parameter to eventAdd() / eventAddIsh() is a const + char *, and is *not copied* but *referenced*. Therefore, it is in your + best interest to use string constants. + +* /stats E for an oper shows pending events. Thanks Diane! diff --git a/doc/technical/fd-management.txt b/doc/technical/fd-management.txt new file mode 100644 index 0000000..cb98e3f --- /dev/null +++ b/doc/technical/fd-management.txt @@ -0,0 +1,47 @@ +Overview of the filedescriptor subsystem +Adrian Chadd <adrian@creative.net.au> + +$Id$ + + +Filedescriptor lists +-------------------- + +The filedescriptor list is managed through the routines in fdlist.c . +These include: + +fd_open() - tag an FD as "open" and active +fd_close() - tag an FD as "closed" and close() the filedescriptor +fd_note() - update the filedescriptor tag + +You can get the current list of open filedescriptors through /stats F as +an oper. + + + +FD lists +-------- + +The FD list support is very alpha. There are a few lists defined: + +typedef enum fdlist_t { + FDLIST_NONE, + FDLIST_SERVICE, + FDLIST_SERVER, + FDLIST_IDLECLIENT, + FDLIST_BUSYCLIENT, + FDLIST_MAX +} fdlist_t; + +FDLIST_NONE Not on any list (ie close()d) +FDLIST_SERVICE A service - listen() sockets, resolver, etc +FDLIST_SERVER Server connections +FDLIST_IDLECLIENT An idle client +FDLIST_BUSYCLIENT A busy client +FDLIST_MAX Used for bounds checking + +The idea is that the SERVICE sockets need polling frequently, the SERVER +sockets also need polling frequently, BUSYCLIENT is for busy clients +which need frequent polling (eg we're trying to write to them), and +IDLECLIENT is for clients which we don't need to poll frequently. +THIS hasn't been decided upon yet. diff --git a/doc/technical/hostmask.txt b/doc/technical/hostmask.txt new file mode 100644 index 0000000..892bc93 --- /dev/null +++ b/doc/technical/hostmask.txt @@ -0,0 +1,136 @@ +The Hostmask and Netmask System +Copyright(c) 2001 by Andrew Miller(A1kmm)<a1kmm@mware.virtualave.net> + +$Id$ +------------------------------------------------------------------------ + +Contents :: +============ +* Section 1: Motivation +* Section 2: Underlying Mechanism + - 2.1: General Overview + - 2.2: IPv4 Netmasks + - 2.3: IPv6 Netmasks + - 2.4: Hostmasks +* Section 3: Exposed Abstraction Layer + - 3.1: Parsing Masks + - 3.2: Adding Configuration Items + - 3.3: Initialising or Rehashing + - 3.4: Finding IP/Hostname Confs + - 3.5: Deleting Entries + - 3.6: Reporting Entries + +Section 1: Motivation +===================== + +Looking up configuration hostnames and IP addresses (such as for I-Lines +and K-Lines) needs to be implemented efficiently. It turns out a hash +based algorithm like that employed here performs very will on the average +case, which is what we should be the most concerned about. A profiling +comparison with the mtre code using data from a real network confirmed +that this algorithm performs much better. + + +Section 2: Underlying Mechanism +=============================== + +2.1: General Overview +--------------------- + +In short, a hash-table with linked lists for buckets is used to locate +the correct hostname/netmask entries. In order to support CIDR IPs and +wildcard masks, the entire key cannot be hashed, and there is a need to +rehash. The means for deciding how much to hash differs between the +hostmasks and IPv4/6 netmasks. + +2.2: IPv4 Netmasks +------------------ + +In order to hash IPv4 netmasks for addition to the hash, the mask is first +processed into a 32-bit address and a number of bits is used. All unused +bits are set to 0. The mask could be in these forms: + +1.2.3.4 => 1.2.3.4 : 32 +1.2.3.* => 1.2.3.0 : 24 +1.2.*.* => 1.2.0.0 : 16 +1.2.3.64/26 => 1.2.3.64 : 26 + +The number of whole bytes is then calculated, and only those bytes are +hashed (e.g. 1.2.3.64/26 and 1.2.3.0/24 hash the same). When a complete +IPv4 address is given so that an IPv4 match can be found the entire IP +address is first hashed, and then looked up in the table. Then the most +significant three bytes are hashed, followed by the most significant two, +the most significant one, and finally the "identity hash" bucket is +searched (to match masks like 192/7). + +2.3: IPv6 Netmasks +------------------ + +As per the IPv4 netmasks, except that instead of rehashing with one byte +granularity, a 16-bit (two byte) granularity is used, as 16 rehashes is +considered too great a fixed offset to be justified for a (possible) +slight reduction in hash collisions. + +2.4: Hostmasks +-------------- + +On adding a hostmask to the hash, all of the hostmask right of the next +dot after the last wildcard character in the string is hashed, or in the +case that there are no wildcards in the hostmask, the entire string is +hashed. + +On searching for a hostmask match, the entire hostname is hashed, followed +by the entire hostmask after the first dot, followed by the entire hostmask +after the second dot, and so on. Finally the "identity hash" bucket is checked +to catch hostnames like *test*. + +Section 3: Exposed Abstraction Layer +==================================== + +Section 3.1: Parsing Masks +-------------------------- + +Call "parse_netmask()" with the netmask and a pointer to an irc_inaddr +structure to be filled in, as well as a pointer to an integer where the +number of bits will be placed. + +Always check the return value, if it returns HM_MOST, it means that the +mask is probably a hostmask. If it returns HM_IPV4, it means it was an +IPv4 address. If it returns HM_IPV6, it means it was an IPv6 address. +If parse_netmask() returns HM_MOST however, no change is made to the +irc_inaddr structure or the number of bits. + +Section 3.2: Adding Configuration Items +--------------------------------------- + +Call "add_conf_by_address()" with the hostname or IP mask, the username, +and the ConfItem* to associate with this mask. + +Section 3.3: Initialising and Rehashing +--------------------------------------- + +To initialise, call "init_host_hash()". This only needs to be done once +on start-up. On rehash, to wipe out the old unwanted configuration, and +free them if there are no references to them, call +"clear_out_address_conf()". + +Section 3.4: Finding IP/Hostname Confs +--------------------------------------- + +Call "find_address_conf()" with the hostname, the username, the address, +the address family and the client-supplied password. To find a D-Line, +call "find_dline()" with the address and address family. + +Section 3.5: Deleted Entries +---------------------------- + +Call "delete_one_address_conf()" with the hostname and the ConfItem*. + +Section 3.6: Reporting Entries +------------------------------ + +Call "report_dlines()", "report_exemptlines()", "report_Klines()", or +"report_Ilines()" with the client pointer to report to. Note these walk +the hash, which is inefficient, but these are not called often enough +to justify the memory and maintenance clockcycles to for more efficient +data structuring. diff --git a/doc/technical/index.txt b/doc/technical/index.txt new file mode 100644 index 0000000..32577e9 --- /dev/null +++ b/doc/technical/index.txt @@ -0,0 +1,16 @@ +$Id$ +----------------------------------------------- + +Technical Documentation for ircd-hybrid-8 + +event.txt - Outline of the event system +fd-management.txt - Outline of the file descriptor management system +hostmask.txt - Outline of hostmask handling +network.txt - Outline of the network traffic subsystem +rfc1459.txt - The IRC RFC +rfc2812.txt - The IRC Client RFC +rfc2813.txt - The IRC Server RFC +send.txt - Document on all of the send_to functions +ts3.txt - TSora Version 3 Protocol +ts5.txt - TSora Version 5 Protocol +ts6.txt - TSora Version 6 Protocol diff --git a/doc/technical/network.txt b/doc/technical/network.txt new file mode 100644 index 0000000..520adc0 --- /dev/null +++ b/doc/technical/network.txt @@ -0,0 +1,99 @@ +Overview of the network subsystem +Adrian Chadd <adrian@creative.net.au> + +$Id$ + +This document is an overview of the new and hopefully improved network +subsystem. + +The code is based loosely upon the network core found in the Squid web cache +server, with some optimizations for ircd-specific IO patterns. + +Filedescriptor IO +----------------- + +Filedescriptor IO is initiated using comm_setselect(). comm_setselect() +registers interest in reading from or writing to a file descriptor. +When a filedescriptor is ready for the required IO a callback is called +from the IO loop. + +The comm_setselect() usage is: + +void +comm_setselect(int fd, fdlist_t list, int type, PF *callback, void *cbdata, + int timeout) + +where: + fd filedescriptor + list Which list the FD should be put on + type IO type. Can currently include: + COMM_SELECT_READ - register for read + COMM_SELECT_WRITE - register for write + callback Function to call when the FD is ready + cbdata Data to be passed to above function + timeout Update the timeout value. 0 is "don't update". + + +A typical use is: + +.. + +/* Register interest in the FD for a read event */ +comm_setselect(fd, FDLIST_SERVICE, COMM_SELECT_READ, read_callback, read_data, + 0); + +.. + +(FD becomes ready for read in the IO loop) + +void +read_callback(int fd, void *data) +{ + /* called when the FD becomes ready for read */ + retval = read(fd, buf, len); + + .. + /* Ok, we need to read some more when its ready */ + comm_setselect(fd, FDLIST_SERVICE, COMM_SELECT_READ, read_callback, data, + 0); +} + +Socket timeouts +--------------- + +A "socket timeout" is a callback registered to be called when a certain +amount of time has elapsed. Think of it as an event, but against a FD. + +A good example of socket timeouts is in the comm_connect_tcp() code. +When the connect() begins, comm_settimeout() is called to call +comm_connect_timeout() if the timeout occurs. Once the connect() completes, +comm_settimeout() is called with a timeout of 0 and callback of NULL +to deregister the timeout. If the timeout occurs, comm_connect_timeout() +is called and the connection attempt is aborted. + + + + +Functions +--------- + +comm_open() - a socket() wrapper, enforcing fd limitations and tagging the + file descriptor with a note + +comm_accept() - an accept() wrapper, enforcing fd limitations and tagging + the file descriptor with a note + +comm_connect_tcp() - attempt an async connect(). Handles DNS lookups if + required, and will call the given callback at completion or error + +comm_settimeout() - set a callback to be called after a given time period. + This is good to implement things like PING checks and connect() timeouts. + +Notes: + +* All socket creation should go through comm_open() / comm_accept(). +* All socket closing should go through fd_close(). comm_close() isn't + implemented yet. +* comm_connect_tcp() is your best friend. :-) +* *ALL* network sockets should be non-blocking. If your OS doesn't support + non-blocking sockets, you shouldn't be here. diff --git a/doc/technical/rfc1459.txt b/doc/technical/rfc1459.txt new file mode 100644 index 0000000..768e176 --- /dev/null +++ b/doc/technical/rfc1459.txt @@ -0,0 +1,3110 @@ +$Id$ + +Network Working Group J. Oikarinen +Request for Comments: 1459 D. Reed + May 1993 + + Internet Relay Chat Protocol + +Status of This Memo + + This memo defines an Experimental Protocol for the Internet + community. Discussion and suggestions for improvement are requested. + Please refer to the current edition of the "IAB Official Protocol + Standards" for the standardization state and status of this protocol. + Distribution of this memo is unlimited. + +Abstract + + The IRC protocol was developed over the last 4 years since it was + first implemented as a means for users on a BBS to chat amongst + themselves. Now it supports a world-wide network of servers and + clients, and is stringing to cope with growth. Over the past 2 years, + the average number of users connected to the main IRC network has + grown by a factor of 10. + + The IRC protocol is a text-based protocol, with the simplest client + being any socket program capable of connecting to the server. + +Table of Contents + + 1. INTRODUCTION ............................................... 4 + 1.1 Servers ................................................ 4 + 1.2 Clients ................................................ 5 + 1.2.1 Operators .......................................... 5 + 1.3 Channels ................................................ 5 + 1.3.1 Channel Operators .................................... 6 + 2. THE IRC SPECIFICATION ....................................... 7 + 2.1 Overview ................................................ 7 + 2.2 Character codes ......................................... 7 + 2.3 Messages ................................................ 7 + 2.3.1 Message format in 'pseudo' BNF .................... 8 + 2.4 Numeric replies ......................................... 10 + 3. IRC Concepts ................................................ 10 + 3.1 One-to-one communication ................................ 10 + 3.2 One-to-many ............................................. 11 + 3.2.1 To a list .......................................... 11 + 3.2.2 To a group (channel) ............................... 11 + 3.2.3 To a host/server mask .............................. 12 + 3.3 One to all .............................................. 12 + + 3.3.1 Client to Client ................................... 12 + 3.3.2 Clients to Server .................................. 12 + 3.3.3 Server to Server ................................... 12 + 4. MESSAGE DETAILS ............................................. 13 + 4.1 Connection Registration ................................. 13 + 4.1.1 Password message ................................... 14 + 4.1.2 Nickname message ................................... 14 + 4.1.3 User message ....................................... 15 + 4.1.4 Server message ..................................... 16 + 4.1.5 Operator message ................................... 17 + 4.1.6 Quit message ....................................... 17 + 4.1.7 Server Quit message ................................ 18 + 4.2 Channel operations ...................................... 19 + 4.2.1 Join message ....................................... 19 + 4.2.2 Part message ....................................... 20 + 4.2.3 Mode message ....................................... 21 + 4.2.3.1 Channel modes ................................. 21 + 4.2.3.2 User modes .................................... 22 + 4.2.4 Topic message ...................................... 23 + 4.2.5 Names message ...................................... 24 + 4.2.6 List message ....................................... 24 + 4.2.7 Invite message ..................................... 25 + 4.2.8 Kick message ....................................... 25 + 4.3 Server queries and commands ............................. 26 + 4.3.1 Version message .................................... 26 + 4.3.2 Stats message ...................................... 27 + 4.3.3 Links message ...................................... 28 + 4.3.4 Time message ....................................... 29 + 4.3.5 Connect message .................................... 29 + 4.3.6 Trace message ...................................... 30 + 4.3.7 Admin message ...................................... 31 + 4.3.8 Info message ....................................... 31 + 4.4 Sending messages ........................................ 32 + 4.4.1 Private messages ................................... 32 + 4.4.2 Notice messages .................................... 33 + 4.5 User-based queries ...................................... 33 + 4.5.1 Who query .......................................... 33 + 4.5.2 Whois query ........................................ 34 + 4.5.3 Whowas message ..................................... 35 + 4.6 Miscellaneous messages .................................. 35 + 4.6.1 Kill message ....................................... 36 + 4.6.2 Ping message ....................................... 37 + 4.6.3 Pong message ....................................... 37 + 4.6.4 Error message ...................................... 38 + 5. OPTIONAL MESSAGES ........................................... 38 + 5.1 Away message ............................................ 38 + 5.2 Rehash command .......................................... 39 + 5.3 Restart command ......................................... 39 + + 5.4 Summon message .......................................... 40 + 5.5 Users message ........................................... 40 + 5.6 Operwall command ........................................ 41 + 5.7 Userhost message ........................................ 42 + 5.8 Ison message ............................................ 42 + 6. REPLIES ..................................................... 43 + 6.1 Error Replies ........................................... 43 + 6.2 Command responses ....................................... 48 + 6.3 Reserved numerics ....................................... 56 + 7. Client and server authentication ............................ 56 + 8. Current Implementations Details ............................. 56 + 8.1 Network protocol: TCP ................................... 57 + 8.1.1 Support of Unix sockets ............................ 57 + 8.2 Command Parsing ......................................... 57 + 8.3 Message delivery ........................................ 57 + 8.4 Connection 'Liveness' ................................... 58 + 8.5 Establishing a server-client connection ................. 58 + 8.6 Establishing a server-server connection ................. 58 + 8.6.1 State information exchange when connecting ......... 59 + 8.7 Terminating server-client connections ................... 59 + 8.8 Terminating server-server connections ................... 59 + 8.9 Tracking nickname changes ............................... 60 + 8.10 Flood control of clients ............................... 60 + 8.11 Non-blocking lookups ................................... 61 + 8.11.1 Hostname (DNS) lookups ............................ 61 + 8.11.2 Username (Ident) lookups .......................... 61 + 8.12 Configuration file ..................................... 61 + 8.12.1 Allowing clients to connect ....................... 62 + 8.12.2 Operators ......................................... 62 + 8.12.3 Allowing servers to connect ....................... 62 + 8.12.4 Administrivia ..................................... 63 + 8.13 Channel membership ..................................... 63 + 9. Current problems ............................................ 63 + 9.1 Scalability ............................................. 63 + 9.2 Labels .................................................. 63 + 9.2.1 Nicknames .......................................... 63 + 9.2.2 Channels ........................................... 64 + 9.2.3 Servers ............................................ 64 + 9.3 Algorithms .............................................. 64 + 10. Support and availability ................................... 64 + 11. Security Considerations .................................... 65 + 12. Authors' Addresses ......................................... 65 + +1. INTRODUCTION + + The IRC (Internet Relay Chat) protocol has been designed over a + number of years for use with text based conferencing. This document + describes the current IRC protocol. + + The IRC protocol has been developed on systems using the TCP/IP + network protocol, although there is no requirement that this remain + the only sphere in which it operates. + + IRC itself is a teleconferencing system, which (through the use of + the client-server model) is well-suited to running on many machines + in a distributed fashion. A typical setup involves a single process + (the server) forming a central point for clients (or other servers) + to connect to, performing the required message delivery/multiplexing + and other functions. + +1.1 Servers + + The server forms the backbone of IRC, providing a point to which + clients may connect to to talk to each other, and a point for other + servers to connect to, forming an IRC network. The only network + configuration allowed for IRC servers is that of a spanning tree [see + Fig. 1] where each server acts as a central node for the rest of the + net it sees. + + [ Server 15 ] [ Server 13 ] [ Server 14] + / \ / + / \ / + [ Server 11 ] ------ [ Server 1 ] [ Server 12] + / \ / + / \ / + [ Server 2 ] [ Server 3 ] + / \ \ + / \ \ + [ Server 4 ] [ Server 5 ] [ Server 6 ] + / | \ / + / | \ / + / | \____ / + / | \ / + [ Server 7 ] [ Server 8 ] [ Server 9 ] [ Server 10 ] + + : + [ etc. ] + : + + [ Fig. 1. Format of IRC server network ] + +1.2 Clients + + A client is anything connecting to a server that is not another + server. Each client is distinguished from other clients by a unique + nickname having a maximum length of nine (9) characters. See the + protocol grammar rules for what may and may not be used in a + nickname. In addition to the nickname, all servers must have the + following information about all clients: the real name of the host + that the client is running on, the username of the client on that + host, and the server to which the client is connected. + +1.2.1 Operators + + To allow a reasonable amount of order to be kept within the IRC + network, a special class of clients (operators) is allowed to perform + general maintenance functions on the network. Although the powers + granted to an operator can be considered as 'dangerous', they are + nonetheless required. Operators should be able to perform basic + network tasks such as disconnecting and reconnecting servers as + needed to prevent long-term use of bad network routing. In + recognition of this need, the protocol discussed herein provides for + operators only to be able to perform such functions. See sections + 4.1.7 (SQUIT) and 4.3.5 (CONNECT). + + A more controversial power of operators is the ability to remove a + user from the connected network by 'force', i.e. operators are able + to close the connection between any client and server. The + justification for this is delicate since its abuse is both + destructive and annoying. For further details on this type of + action, see section 4.6.1 (KILL). + +1.3 Channels + + A channel is a named group of one or more clients which will all + receive messages addressed to that channel. The channel is created + implicitly when the first client joins it, and the channel ceases to + exist when the last client leaves it. While channel exists, any + client can reference the channel using the name of the channel. + + Channels names are strings (beginning with a '&' or '#' character) of + length up to 200 characters. Apart from the the requirement that the + first character being either '&' or '#'; the only restriction on a + channel name is that it may not contain any spaces (' '), a control G + (^G or ASCII 7), or a comma (',' which is used as a list item + separator by the protocol). + + There are two types of channels allowed by this protocol. One is a + distributed channel which is known to all the servers that are + + connected to the network. These channels are marked by the first + character being a only clients on the server where it exists may join + it. These are distinguished by a leading '&' character. On top of + these two types, there are the various channel modes available to + alter the characteristics of individual channels. See section 4.2.3 + (MODE command) for more details on this. + + To create a new channel or become part of an existing channel, a user + is required to JOIN the channel. If the channel doesn't exist prior + to joining, the channel is created and the creating user becomes a + channel operator. If the channel already exists, whether or not your + request to JOIN that channel is honoured depends on the current modes + of the channel. For example, if the channel is invite-only, (+i), + then you may only join if invited. As part of the protocol, a user + may be a part of several channels at once, but a limit of ten (10) + channels is recommended as being ample for both experienced and + novice users. See section 8.13 for more information on this. + + If the IRC network becomes disjoint because of a split between two + servers, the channel on each side is only composed of those clients + which are connected to servers on the respective sides of the split, + possibly ceasing to exist on one side of the split. When the split + is healed, the connecting servers announce to each other who they + think is in each channel and the mode of that channel. If the + channel exists on both sides, the JOINs and MODEs are interpreted in + an inclusive manner so that both sides of the new connection will + agree about which clients are in the channel and what modes the + channel has. + +1.3.1 Channel Operators + + The channel operator (also referred to as a "chop" or "chanop") on a + given channel is considered to 'own' that channel. In recognition of + this status, channel operators are endowed with certain powers which + enable them to keep control and some sort of sanity in their channel. + As an owner of a channel, a channel operator is not required to have + reasons for their actions, although if their actions are generally + antisocial or otherwise abusive, it might be reasonable to ask an IRC + operator to intervene, or for the usersjust leave and go elsewhere + and form their own channel. + + The commands which may only be used by channel operators are: + + KICK - Eject a client from the channel + MODE - Change the channel's mode + INVITE - Invite a client to an invite-only channel (mode +i) + TOPIC - Change the channel topic in a mode +t channel + + A channel operator is identified by the '@' symbol next to their + nickname whenever it is associated with a channel (ie replies to the + NAMES, WHO and WHOIS commands). + +2. The IRC Specification + +2.1 Overview + + The protocol as described herein is for use both with server to + server and client to server connections. There are, however, more + restrictions on client connections (which are considered to be + untrustworthy) than on server connections. + +2.2 Character codes + + No specific character set is specified. The protocol is based on a a + set of codes which are composed of eight (8) bits, making up an + octet. Each message may be composed of any number of these octets; + however, some octet values are used for control codes which act as + message delimiters. + + Regardless of being an 8-bit protocol, the delimiters and keywords + are such that protocol is mostly usable from USASCII terminal and a + telnet connection. + + Because of IRC's scandanavian origin, the characters {}| are + considered to be the lower case equivalents of the characters []\, + respectively. This is a critical issue when determining the + equivalence of two nicknames. + +2.3 Messages + + Servers and clients send eachother messages which may or may not + generate a reply. If the message contains a valid command, as + described in later sections, the client should expect a reply as + specified but it is not advised to wait forever for the reply; client + to server and server to server communication is essentially + asynchronous in nature. + + Each IRC message may consist of up to three main parts: the prefix + (optional), the command, and the command parameters (of which there + may be up to 15). The prefix, command, and all parameters are + separated by one (or more) ASCII space character(s) (0x20). + + The presence of a prefix is indicated with a single leading ASCII + colon character (':', 0x3b), which must be the first character of the + message itself. There must be no gap (whitespace) between the colon + and the prefix. The prefix is used by servers to indicate the true + + origin of the message. If the prefix is missing from the message, it + is assumed to have originated from the connection from which it was + received. Clients should not use prefix when sending a message from + themselves; if they use a prefix, the only valid prefix is the + registered nickname associated with the client. If the source + identified by the prefix cannot be found from the server's internal + database, or if the source is registered from a different link than + from which the message arrived, the server must ignore the message + silently. + + The command must either be a valid IRC command or a three (3) digit + number represented in ASCII text. + + IRC messages are always lines of characters terminated with a CR-LF + (Carriage Return - Line Feed) pair, and these messages shall not + exceed 512 characters in length, counting all characters including + the trailing CR-LF. Thus, there are 510 characters maximum allowed + for the command and its parameters. There is no provision for + continuation message lines. See section 7 for more details about + current implementations. + +2.3.1 Message format in 'pseudo' BNF + + The protocol messages must be extracted from the contiguous stream of + octets. The current solution is to designate two characters, CR and + LF, as message separators. Empty messages are silently ignored, + which permits use of the sequence CR-LF between messages + without extra problems. + + The extracted message is parsed into the components <prefix>, + <command> and list of parameters matched either by <middle> or + <trailing> components. + + The BNF representation for this is: + +<message> ::= [':' <prefix> <SPACE> ] <command> <params> <crlf> +<prefix> ::= <servername> | <nick> [ '!' <user> ] [ '@' <host> ] +<command> ::= <letter> { <letter> } | <number> <number> <number> +<SPACE> ::= ' ' { ' ' } +<params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ] + +<middle> ::= <Any *non-empty* sequence of octets not including SPACE + or NUL or CR or LF, the first of which may not be ':'> +<trailing> ::= <Any, possibly *empty*, sequence of octets not including + NUL or CR or LF> + +<crlf> ::= CR LF + +NOTES: + + 1) <SPACE> is consists only of SPACE character(s) (0x20). + Specially notice that TABULATION, and all other control + characters are considered NON-WHITE-SPACE. + + 2) After extracting the parameter list, all parameters are equal, + whether matched by <middle> or <trailing>. <Trailing> is just + a syntactic trick to allow SPACE within parameter. + + 3) The fact that CR and LF cannot appear in parameter strings is + just artifact of the message framing. This might change later. + + 4) The NUL character is not special in message framing, and + basically could end up inside a parameter, but as it would + cause extra complexities in normal C string handling. Therefore + NUL is not allowed within messages. + + 5) The last parameter may be an empty string. + + 6) Use of the extended prefix (['!' <user> ] ['@' <host> ]) must + not be used in server to server communications and is only + intended for server to client messages in order to provide + clients with more useful information about who a message is + from without the need for additional queries. + + Most protocol messages specify additional semantics and syntax for + the extracted parameter strings dictated by their position in the + list. For example, many server commands will assume that the first + parameter after the command is the list of targets, which can be + described with: + + <target> ::= <to> [ "," <target> ] + <to> ::= <channel> | <user> '@' <servername> | <nick> | <mask> + <channel> ::= ('#' | '&') <chstring> + <servername> ::= <host> + <host> ::= see RFC 952 [DNS:4] for details on allowed hostnames + <nick> ::= <letter> { <letter> | <number> | <special> } + <mask> ::= ('#' | '$') <chstring> + <chstring> ::= <any 8bit code except SPACE, BELL, NUL, CR, LF and + comma (',')> + + Other parameter syntaxes are: + + <user> ::= <nonwhite> { <nonwhite> } + <letter> ::= 'a' ... 'z' | 'A' ... 'Z' + <number> ::= '0' ... '9' + <special> ::= '-' | '[' | ']' | '\' | '`' | '^' | '{' | '}' + + <nonwhite> ::= <any 8bit code except SPACE (0x20), NUL (0x0), CR + (0xd), and LF (0xa)> + +2.4 Numeric replies + + Most of the messages sent to the server generate a reply of some + sort. The most common reply is the numeric reply, used for both + errors and normal replies. The numeric reply must be sent as one + message consisting of the sender prefix, the three digit numeric, and + the target of the reply. A numeric reply is not allowed to originate + from a client; any such messages received by a server are silently + dropped. In all other respects, a numeric reply is just like a normal + message, except that the keyword is made up of 3 numeric digits + rather than a string of letters. A list of different replies is + supplied in section 6. + +3. IRC Concepts. + + This section is devoted to describing the actual concepts behind the + organization of the IRC protocol and how the current + implementations deliver different classes of messages. + + 1--\ + A D---4 + 2--/ \ / + B----C + / \ + 3 E + + Servers: A, B, C, D, E Clients: 1, 2, 3, 4 + + [ Fig. 2. Sample small IRC network ] + +3.1 One-to-one communication + + Communication on a one-to-one basis is usually only performed by + clients, since most server-server traffic is not a result of servers + talking only to each other. To provide a secure means for clients to + talk to each other, it is required that all servers be able to send a + message in exactly one direction along the spanning tree in order to + reach any client. The path of a message being delivered is the + shortest path between any two points on the spanning tree. + + The following examples all refer to Figure 2 above. + +Example 1: + A message between clients 1 and 2 is only seen by server A, which + sends it straight to client 2. + +Example 2: + A message between clients 1 and 3 is seen by servers A & B, and + client 3. No other clients or servers are allowed see the message. + +Example 3: + A message between clients 2 and 4 is seen by servers A, B, C & D + and client 4 only. + +3.2 One-to-many + + The main goal of IRC is to provide a forum which allows easy and + efficient conferencing (one to many conversations). IRC offers + several means to achieve this, each serving its own purpose. + +3.2.1 To a list + + The least efficient style of one-to-many conversation is through + clients talking to a 'list' of users. How this is done is almost + self explanatory: the client gives a list of destinations to which + the message is to be delivered and the server breaks it up and + dispatches a separate copy of the message to each given destination. + This isn't as efficient as using a group since the destination list + is broken up and the dispatch sent without checking to make sure + duplicates aren't sent down each path. + +3.2.2 To a group (channel) + + In IRC the channel has a role equivalent to that of the multicast + group; their existence is dynamic (coming and going as people join + and leave channels) and the actual conversation carried out on a + channel is only sent to servers which are supporting users on a given + channel. If there are multiple users on a server in the same + channel, the message text is sent only once to that server and then + sent to each client on the channel. This action is then repeated for + each client-server combination until the original message has fanned + out and reached each member of the channel. + + The following examples all refer to Figure 2. + +Example 4: + Any channel with 1 client in it. Messages to the channel go to the + server and then nowhere else. + +Example 5: + 2 clients in a channel. All messages traverse a path as if they + were private messages between the two clients outside a channel. + +Example 6: + Clients 1, 2 and 3 in a channel. All messages to the channel are + sent to all clients and only those servers which must be traversed + by the message if it were a private message to a single client. If + client 1 sends a message, it goes back to client 2 and then via + server B to client 3. + +3.2.3 To a host/server mask + + To provide IRC operators with some mechanism to send messages to a + large body of related users, host and server mask messages are + provided. These messages are sent to users whose host or server + information match that of the mask. The messages are only sent to + locations where users are, in a fashion similar to that of channels. + +3.3 One-to-all + + The one-to-all type of message is better described as a broadcast + message, sent to all clients or servers or both. On a large network + of users and servers, a single message can result in a lot of traffic + being sent over the network in an effort to reach all of the desired + destinations. + + For some messages, there is no option but to broadcast it to all + servers so that the state information held by each server is + reasonably consistent between servers. + +3.3.1 Client-to-Client + + There is no class of message which, from a single message, results in + a message being sent to every other client. + +3.3.2 Client-to-Server + + Most of the commands which result in a change of state information + (such as channel membership, channel mode, user status, etc) must be + sent to all servers by default, and this distribution may not be + changed by the client. + +3.3.3 Server-to-Server. + + While most messages between servers are distributed to all 'other' + servers, this is only required for any message that affects either a + user, channel or server. Since these are the basic items found in + + IRC, nearly all messages originating from a server are broadcast to + all other connected servers. + +4. Message details + + On the following pages are descriptions of each message recognized by + the IRC server and client. All commands described in this section + must be implemented by any server for this protocol. + + Where the reply ERR_NOSUCHSERVER is listed, it means that the + <server> parameter could not be found. The server must not send any + other replies after this for that command. + + The server to which a client is connected is required to parse the + complete message, returning any appropriate errors. If the server + encounters a fatal error while parsing a message, an error must be + sent back to the client and the parsing terminated. A fatal error + may be considered to be incorrect command, a destination which is + otherwise unknown to the server (server, nick or channel names fit + this category), not enough parameters or incorrect privileges. + + If a full set of parameters is presented, then each must be checked + for validity and appropriate responses sent back to the client. In + the case of messages which use parameter lists using the comma as an + item separator, a reply must be sent for each item. + + In the examples below, some messages appear using the full format: + + :Name COMMAND parameter list + + Such examples represent a message from "Name" in transit between + servers, where it is essential to include the name of the original + sender of the message so remote servers may send back a reply along + the correct path. + +4.1 Connection Registration + + The commands described here are used to register a connection with an + IRC server as either a user or a server as well as correctly + disconnect. + + A "PASS" command is not required for either client or server + connection to be registered, but it must precede the server message + or the latter of the NICK/USER combination. It is strongly + recommended that all server connections have a password in order to + give some level of security to the actual connections. The + recommended order for a client to register is as follows: + + 1. Pass message + 2. Nick message + 3. User message + +4.1.1 Password message + + Command: PASS + Parameters: <password> + + The PASS command is used to set a 'connection password'. The + password can and must be set before any attempt to register the + connection is made. Currently this requires that clients send a PASS + command before sending the NICK/USER combination and servers *must* + send a PASS command before any SERVER command. The password supplied + must match the one contained in the C/N lines (for servers) or I + lines (for clients). It is possible to send multiple PASS commands + before registering but only the last one sent is used for + verification and it may not be changed once registered. Numeric + Replies: + + ERR_NEEDMOREPARAMS ERR_ALREADYREGISTRED + + Example: + + PASS secretpasswordhere + +4.1.2 Nick message + + Command: NICK + Parameters: <nickname> [ <hopcount> ] + + NICK message is used to give user a nickname or change the previous + one. The <hopcount> parameter is only used by servers to indicate + how far away a nick is from its home server. A local connection has + a hopcount of 0. If supplied by a client, it must be ignored. + + If a NICK message arrives at a server which already knows about an + identical nickname for another client, a nickname collision occurs. + As a result of a nickname collision, all instances of the nickname + are removed from the server's database, and a KILL command is issued + to remove the nickname from all other server's database. If the NICK + message causing the collision was a nickname change, then the + original (old) nick must be removed as well. + + If the server recieves an identical NICK from a client which is + directly connected, it may issue an ERR_NICKCOLLISION to the local + client, drop the NICK command, and not generate any kills. + + Numeric Replies: + + ERR_NONICKNAMEGIVEN ERR_ERRONEUSNICKNAME + ERR_NICKNAMEINUSE ERR_NICKCOLLISION + + Example: + + NICK Wiz ; Introducing new nick "Wiz". + + :WiZ NICK Kilroy ; WiZ changed his nickname to Kilroy. + +4.1.3 User message + + Command: USER + Parameters: <username> <hostname> <servername> <realname> + + The USER message is used at the beginning of connection to specify + the username, hostname, servername and realname of s new user. It is + also used in communication between servers to indicate new user + arriving on IRC, since only after both USER and NICK have been + received from a client does a user become registered. + + Between servers USER must to be prefixed with client's NICKname. + Note that hostname and servername are normally ignored by the IRC + server when the USER command comes from a directly connected client + (for security reasons), but they are used in server to server + communication. This means that a NICK must always be sent to a + remote server when a new user is being introduced to the rest of the + network before the accompanying USER is sent. + + It must be noted that realname parameter must be the last parameter, + because it may contain space characters and must be prefixed with a + colon (':') to make sure this is recognised as such. + + Since it is easy for a client to lie about its username by relying + solely on the USER message, the use of an "Identity Server" is + recommended. If the host which a user connects from has such a + server enabled the username is set to that as in the reply from the + "Identity Server". + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_ALREADYREGISTRED + + Examples: + + USER guest tolmoon tolsun :Ronnie Reagan + + ; User registering themselves with a + username of "guest" and real name + "Ronnie Reagan". + + :testnick USER guest tolmoon tolsun :Ronnie Reagan + ; message between servers with the + nickname for which the USER command + belongs to + +4.1.4 Server message + + Command: SERVER + Parameters: <servername> <hopcount> <info> + + The server message is used to tell a server that the other end of a + new connection is a server. This message is also used to pass server + data over whole net. When a new server is connected to net, + information about it be broadcast to the whole network. <hopcount> + is used to give all servers some internal information on how far away + all servers are. With a full server list, it would be possible to + construct a map of the entire server tree, but hostmasks prevent this + from being done. + + The SERVER message must only be accepted from either (a) a connection + which is yet to be registered and is attempting to register as a + server, or (b) an existing connection to another server, in which + case the SERVER message is introducing a new server behind that + server. + + Most errors that occur with the receipt of a SERVER command result in + the connection being terminated by the destination host (target + SERVER). Error replies are usually sent using the "ERROR" command + rather than the numeric since the ERROR command has several useful + properties which make it useful here. + + If a SERVER message is parsed and attempts to introduce a server + which is already known to the receiving server, the connection from + which that message must be closed (following the correct procedures), + since a duplicate route to a server has formed and the acyclic nature + of the IRC tree broken. + + Numeric Replies: + + ERR_ALREADYREGISTRED + + Example: + +SERVER test.oulu.fi 1 :[tolsun.oulu.fi] Experimental server + ; New server test.oulu.fi introducing + itself and attempting to register. The + name in []'s is the hostname for the + host running test.oulu.fi. + +:tolsun.oulu.fi SERVER csd.bu.edu 5 :BU Central Server + ; Server tolsun.oulu.fi is our uplink + for csd.bu.edu which is 5 hops away. + +4.1.5 Oper + + Command: OPER + Parameters: <user> <password> + + OPER message is used by a normal user to obtain operator privileges. + The combination of <user> and <password> are required to gain + Operator privileges. + + If the client sending the OPER command supplies the correct password + for the given user, the server then informs the rest of the network + of the new operator by issuing a "MODE +o" for the clients nickname. + + The OPER message is client-server only. + + Numeric Replies: + + ERR_NEEDMOREPARAMS RPL_YOUREOPER + ERR_NOOPERHOST ERR_PASSWDMISMATCH + + Example: + + OPER foo bar ; Attempt to register as an operator + using a username of "foo" and "bar" as + the password. + +4.1.6 Quit + + Command: QUIT + Parameters: [<Quit message>] + + A client session is ended with a quit message. The server must close + the connection to a client which sends a QUIT message. If a "Quit + Message" is given, this will be sent instead of the default message, + the nickname. + + When netsplits (disconnecting of two servers) occur, the quit message + + is composed of the names of two servers involved, separated by a + space. The first name is that of the server which is still connected + and the second name is that of the server that has become + disconnected. + + If, for some other reason, a client connection is closed without the + client issuing a QUIT command (e.g. client dies and EOF occurs + on socket), the server is required to fill in the quit message with + some sort of message reflecting the nature of the event which + caused it to happen. + + Numeric Replies: + + None. + + Examples: + + QUIT :Gone to have lunch ; Preferred message format. + +4.1.7 Server quit message + + Command: SQUIT + Parameters: <server> <comment> + + The SQUIT message is needed to tell about quitting or dead servers. + If a server wishes to break the connection to another server it must + send a SQUIT message to the other server, using the the name of the + other server as the server parameter, which then closes its + connection to the quitting server. + + This command is also available operators to help keep a network of + IRC servers connected in an orderly fashion. Operators may also + issue an SQUIT message for a remote server connection. In this case, + the SQUIT must be parsed by each server inbetween the operator and + the remote server, updating the view of the network held by each + server as explained below. + + The <comment> should be supplied by all operators who execute a SQUIT + for a remote server (that is not connected to the server they are + currently on) so that other operators are aware for the reason of + this action. The <comment> is also filled in by servers which may + place an error or similar message here. + + Both of the servers which are on either side of the connection being + closed are required to to send out a SQUIT message (to all its other + server connections) for all other servers which are considered to be + behind that link. + + Similarly, a QUIT message must be sent to the other connected servers + rest of the network on behalf of all clients behind that link. In + addition to this, all channel members of a channel which lost a + member due to the split must be sent a QUIT message. + + If a server connection is terminated prematurely (e.g. the server on + the other end of the link died), the server which detects + this disconnection is required to inform the rest of the network + that the connection has closed and fill in the comment field + with something appropriate. + + Numeric replies: + + ERR_NOPRIVILEGES ERR_NOSUCHSERVER + + Example: + + SQUIT tolsun.oulu.fi :Bad Link ? ; the server link tolson.oulu.fi has + been terminated because of "Bad Link". + + :Trillian SQUIT cm22.eng.umd.edu :Server out of control + ; message from Trillian to disconnect + "cm22.eng.umd.edu" from the net + because "Server out of control". + +4.2 Channel operations + + This group of messages is concerned with manipulating channels, their + properties (channel modes), and their contents (typically clients). + In implementing these, a number of race conditions are inevitable + when clients at opposing ends of a network send commands which will + ultimately clash. It is also required that servers keep a nickname + history to ensure that wherever a <nick> parameter is given, the + server check its history in case it has recently been changed. + +4.2.1 Join message + + Command: JOIN + Parameters: <channel>{,<channel>} [<key>{,<key>}] + + The JOIN command is used by client to start listening a specific + channel. Whether or not a client is allowed to join a channel is + checked only by the server the client is connected to; all other + servers automatically add the user to the channel when it is received + from other servers. The conditions which affect this are as follows: + + 1. the user must be invited if the channel is invite-only; + + 2. the user's nick/username/hostname must not match any + active bans; + + 3. the correct key (password) must be given if it is set. + + These are discussed in more detail under the MODE command (see + section 4.2.3 for more details). + + Once a user has joined a channel, they receive notice about all + commands their server receives which affect the channel. This + includes MODE, KICK, PART, QUIT and of course PRIVMSG/NOTICE. The + JOIN command needs to be broadcast to all servers so that each server + knows where to find the users who are on the channel. This allows + optimal delivery of PRIVMSG/NOTICE messages to the channel. + + If a JOIN is successful, the user is then sent the channel's topic + (using RPL_TOPIC) and the list of users who are on the channel (using + RPL_NAMREPLY), which must include the user joining. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_BANNEDFROMCHAN + ERR_INVITEONLYCHAN ERR_BADCHANNELKEY + ERR_CHANNELISFULL ERR_BADCHANMASK + ERR_NOSUCHCHANNEL ERR_TOOMANYCHANNELS + RPL_TOPIC + + Examples: + + JOIN #foobar ; join channel #foobar. + + JOIN &foo fubar ; join channel &foo using key "fubar". + + JOIN #foo,&bar fubar ; join channel #foo using key "fubar" + and &bar using no key. + + JOIN #foo,#bar fubar,foobar ; join channel #foo using key "fubar". + and channel #bar using key "foobar". + + JOIN #foo,#bar ; join channels #foo and #bar. + + :WiZ JOIN #Twilight_zone ; JOIN message from WiZ + +4.2.2 Part message + + Command: PART + Parameters: <channel>{,<channel>} + + The PART message causes the client sending the message to be removed + from the list of active users for all given channels listed in the + parameter string. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_NOSUCHCHANNEL + ERR_NOTONCHANNEL + + Examples: + + PART #twilight_zone ; leave channel "#twilight_zone" + + PART #oz-ops,&group5 ; leave both channels "&group5" and + "#oz-ops". + +4.2.3 Mode message + + Command: MODE + + The MODE command is a dual-purpose command in IRC. It allows both + usernames and channels to have their mode changed. The rationale for + this choice is that one day nicknames will be obsolete and the + equivalent property will be the channel. + + When parsing MODE messages, it is recommended that the entire message + be parsed first and then the changes which resulted then passed on. + +4.2.3.1 Channel modes + + Parameters: <channel> {[+|-]|o|p|s|i|t|n|b|v} [<limit>] [<user>] + [<ban mask>] + + The MODE command is provided so that channel operators may change the + characteristics of `their' channel. It is also required that servers + be able to change channel modes so that channel operators may be + created. + + The various modes available for channels are as follows: + + o - give/take channel operator privileges; + p - private channel flag; + s - secret channel flag; + i - invite-only channel flag; + t - topic settable by channel operator only flag; + n - no messages to channel from clients on the outside; + m - moderated channel; + l - set the user limit to channel; + + b - set a ban mask to keep users out; + v - give/take the ability to speak on a moderated channel; + k - set a channel key (password). + + When using the 'o' and 'b' options, a restriction on a total of three + per mode command has been imposed. That is, any combination of 'o' + and + +4.2.3.2 User modes + + Parameters: <nickname> {[+|-]|i|w|s|o} + + The user MODEs are typically changes which affect either how the + client is seen by others or what 'extra' messages the client is sent. + A user MODE command may only be accepted if both the sender of the + message and the nickname given as a parameter are both the same. + + The available modes are as follows: + + i - marks a users as invisible; + s - marks a user for receipt of server notices; + w - user receives wallops; + o - operator flag. + + Additional modes may be available later on. + + If a user attempts to make themselves an operator using the "+o" + flag, the attempt should be ignored. There is no restriction, + however, on anyone `deopping' themselves (using "-o"). Numeric + Replies: + + ERR_NEEDMOREPARAMS RPL_CHANNELMODEIS + ERR_CHANOPRIVSNEEDED ERR_NOSUCHNICK + ERR_NOTONCHANNEL ERR_KEYSET + RPL_BANLIST RPL_ENDOFBANLIST + ERR_UNKNOWNMODE ERR_NOSUCHCHANNEL + + ERR_USERSDONTMATCH RPL_UMODEIS + ERR_UMODEUNKNOWNFLAG + + Examples: + + Use of Channel Modes: + +MODE #Finnish +im ; Makes #Finnish channel moderated and + 'invite-only'. + +MODE #Finnish +o Kilroy ; Gives 'chanop' privileges to Kilroy on + + channel #Finnish. + +MODE #Finnish +v Wiz ; Allow WiZ to speak on #Finnish. + +MODE #Fins -s ; Removes 'secret' flag from channel + #Fins. + +MODE #42 +k oulu ; Set the channel key to "oulu". + +MODE #eu-opers +l 10 ; Set the limit for the number of users + on channel to 10. + +MODE &oulu +b ; list ban masks set for channel. + +MODE &oulu +b *!*@* ; prevent all users from joining. + +MODE &oulu +b *!*@*.edu ; prevent any user from a hostname + matching *.edu from joining. + + Use of user Modes: + +:MODE WiZ -w ; turns reception of WALLOPS messages + off for WiZ. + +:Angel MODE Angel +i ; Message from Angel to make themselves + invisible. + +MODE WiZ -o ; WiZ 'deopping' (removing operator + status). The plain reverse of this + command ("MODE WiZ +o") must not be + allowed from users since would bypass + the OPER command. + +4.2.4 Topic message + + Command: TOPIC + Parameters: <channel> [<topic>] + + The TOPIC message is used to change or view the topic of a channel. + The topic for channel <channel> is returned if there is no <topic> + given. If the <topic> parameter is present, the topic for that + channel will be changed, if the channel modes permit this action. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_NOTONCHANNEL + RPL_NOTOPIC RPL_TOPIC + ERR_CHANOPRIVSNEEDED + + Examples: + + :Wiz TOPIC #test :New topic ;User Wiz setting the topic. + + TOPIC #test :another topic ;set the topic on #test to "another + topic". + + TOPIC #test ; check the topic for #test. + +4.2.5 Names message + + Command: NAMES + Parameters: [<channel>{,<channel>}] + + By using the NAMES command, a user can list all nicknames that are + visible to them on any channel that they can see. Channel names + which they can see are those which aren't private (+p) or secret (+s) + or those which they are actually on. The <channel> parameter + specifies which channel(s) to return information about if valid. + There is no error reply for bad channel names. + + If no <channel> parameter is given, a list of all channels and their + occupants is returned. At the end of this list, a list of users who + are visible but either not on any channel or not on a visible channel + are listed as being on `channel' "*". + + Numerics: + + RPL_NAMREPLY RPL_ENDOFNAMES + + Examples: + + NAMES #twilight_zone,#42 ; list visible users on #twilight_zone + and #42 if the channels are visible to + you. + + NAMES ; list all visible channels and users + +4.2.6 List message + + Command: LIST + Parameters: [<channel>{,<channel>} [<server>]] + + The list message is used to list channels and their topics. If the + <channel> parameter is used, only the status of that channel + is displayed. Private channels are listed (without their + topics) as channel "Prv" unless the client generating the query is + actually on that channel. Likewise, secret channels are not listed + + at all unless the client is a member of the channel in question. + + Numeric Replies: + + ERR_NOSUCHSERVER RPL_LISTSTART + RPL_LIST RPL_LISTEND + + Examples: + + LIST ; List all channels. + + LIST #twilight_zone,#42 ; List channels #twilight_zone and #42 + +4.2.7 Invite message + + Command: INVITE + Parameters: <nickname> <channel> + + The INVITE message is used to invite users to a channel. The + parameter <nickname> is the nickname of the person to be invited to + the target channel <channel>. There is no requirement that the + channel the target user is being invited to must exist or be a valid + channel. To invite a user to a channel which is invite only (MODE + +i), the client sending the invite must be recognised as being a + channel operator on the given channel. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_NOSUCHNICK + ERR_NOTONCHANNEL ERR_USERONCHANNEL + ERR_CHANOPRIVSNEEDED + RPL_INVITING RPL_AWAY + + Examples: + + :Angel INVITE Wiz #Dust ; User Angel inviting WiZ to channel + #Dust + + INVITE Wiz #Twilight_Zone ; Command to invite WiZ to + #Twilight_zone + +4.2.8 Kick command + + Command: KICK + Parameters: <channel> <user> [<comment>] + + The KICK command can be used to forcibly remove a user from a + channel. It 'kicks them out' of the channel (forced PART). + + Only a channel operator may kick another user out of a channel. + Each server that receives a KICK message checks that it is valid + (ie the sender is actually a channel operator) before removing + the victim from the channel. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_NOSUCHCHANNEL + ERR_BADCHANMASK ERR_CHANOPRIVSNEEDED + ERR_NOTONCHANNEL + + Examples: + +KICK &Melbourne Matthew ; Kick Matthew from &Melbourne + +KICK #Finnish John :Speaking English + ; Kick John from #Finnish using + "Speaking English" as the reason + (comment). + +:WiZ KICK #Finnish John ; KICK message from WiZ to remove John + from channel #Finnish + +NOTE: + It is possible to extend the KICK command parameters to the +following: + +<channel>{,<channel>} <user>{,<user>} [<comment>] + +4.3 Server queries and commands + + The server query group of commands has been designed to return + information about any server which is connected to the network. All + servers connected must respond to these queries and respond + correctly. Any invalid response (or lack thereof) must be considered + a sign of a broken server and it must be disconnected/disabled as + soon as possible until the situation is remedied. + + In these queries, where a parameter appears as "<server>", it will + usually mean it can be a nickname or a server or a wildcard name of + some sort. For each parameter, however, only one query and set of + replies is to be generated. + +4.3.1 Version message + + Command: VERSION + Parameters: [<server>] + + The VERSION message is used to query the version of the server + program. An optional parameter <server> is used to query the version + of the server program which a client is not directly connected to. + + Numeric Replies: + + ERR_NOSUCHSERVER RPL_VERSION + + Examples: + + :Wiz VERSION *.se ; message from Wiz to check the version + of a server matching "*.se" + + VERSION tolsun.oulu.fi ; check the version of server + "tolsun.oulu.fi". + +4.3.2 Stats message + + Command: STATS + Parameters: [<query> [<server>]] + + The stats message is used to query statistics of certain server. If + <server> parameter is omitted, only the end of stats reply is sent + back. The implementation of this command is highly dependent on the + server which replies, although the server must be able to supply + information as described by the queries below (or similar). + + A query may be given by any single letter which is only checked by + the destination server (if given as the <server> parameter) and is + otherwise passed on by intermediate servers, ignored and unaltered. + The following queries are those found in the current IRC + implementation and provide a large portion of the setup information + for that server. Although these may not be supported in the same way + by other versions, all servers should be able to supply a valid reply + to a STATS query which is consistent with the reply formats currently + used and the purpose of the query. + + The currently supported queries are: + + c - returns a list of servers which the server may connect + to or allow connections from; + h - returns a list of servers which are either forced to be + treated as leaves or allowed to act as hubs; + i - returns a list of hosts which the server allows a client + to connect from; + k - returns a list of banned username/hostname combinations + for that server; + l - returns a list of the server's connections, showing how + + long each connection has been established and the traffic + over that connection in bytes and messages for each + direction; + m - returns a list of commands supported by the server and + the usage count for each if the usage count is non zero; + o - returns a list of hosts from which normal clients may + become operators; + y - show Y (Class) lines from server's configuration file; + u - returns a string showing how long the server has been up. + + Numeric Replies: + + ERR_NOSUCHSERVER + RPL_STATSCLINE RPL_STATSNLINE + RPL_STATSILINE RPL_STATSKLINE + RPL_STATSQLINE RPL_STATSLLINE + RPL_STATSLINKINFO RPL_STATSUPTIME + RPL_STATSCOMMANDS RPL_STATSOLINE + RPL_STATSHLINE RPL_ENDOFSTATS + + Examples: + +STATS m ; check the command usage for the server + you are connected to + +:Wiz STATS c eff.org ; request by WiZ for C/N line + information from server eff.org + +4.3.3 Links message + + Command: LINKS + Parameters: [[<remote server>] <server mask>] + + With LINKS, a user can list all servers which are known by the server + answering the query. The returned list of servers must match the + mask, or if no mask is given, the full list is returned. + + If <remote server> is given in addition to <server mask>, the LINKS + command is forwarded to the first server found that matches that name + (if any), and that server is then required to answer the query. + + Numeric Replies: + + ERR_NOSUCHSERVER + RPL_LINKS RPL_ENDOFLINKS + + Examples: + +LINKS *.au ; list all servers which have a name + that matches *.au; + +:WiZ LINKS *.bu.edu *.edu ; LINKS message from WiZ to the first + server matching *.edu for a list of + servers matching *.bu.edu. + +4.3.4 Time message + + Command: TIME + Parameters: [<server>] + + The time message is used to query local time from the specified + server. If the server parameter is not given, the server handling the + command must reply to the query. + + Numeric Replies: + + ERR_NOSUCHSERVER RPL_TIME + + Examples: + + TIME tolsun.oulu.fi ; check the time on the server + "tolson.oulu.fi" + + Angel TIME *.au ; user angel checking the time on a + server matching "*.au" + +4.3.5 Connect message + + Command: CONNECT + Parameters: <target server> [<port> [<remote server>]] + + The CONNECT command can be used to force a server to try to establish + a new connection to another server immediately. CONNECT is a + privileged command and is to be available only to IRC Operators. If + a remote server is given then the CONNECT attempt is made by that + server to <target server> and <port>. + + Numeric Replies: + + ERR_NOSUCHSERVER ERR_NOPRIVILEGES + ERR_NEEDMOREPARAMS + + Examples: + +CONNECT tolsun.oulu.fi ; Attempt to connect a server to + tolsun.oulu.fi + +:WiZ CONNECT eff.org 6667 csd.bu.edu + ; CONNECT attempt by WiZ to get servers + eff.org and csd.bu.edu connected on port + 6667. + +4.3.6 Trace message + + Command: TRACE + Parameters: [<server>] + + TRACE command is used to find the route to specific server. Each + server that processes this message must tell the sender about it by + sending a reply indicating it is a pass-through link, forming a chain + of replies similar to that gained from using "traceroute". After + sending this reply back, it must then send the TRACE message to the + next server until given server is reached. If the <server> parameter + is omitted, it is recommended that TRACE command send a message to + the sender telling which servers the current server has direct + connection to. + + If the destination given by "<server>" is an actual server, then the + destination server is required to report all servers and users which + are connected to it, although only operators are permitted to see + users present. If the destination given by <server> is a nickname, + they only a reply for that nickname is given. + + Numeric Replies: + + ERR_NOSUCHSERVER + + If the TRACE message is destined for another server, all intermediate + servers must return a RPL_TRACELINK reply to indicate that the TRACE + passed through it and where its going next. + + RPL_TRACELINK + A TRACE reply may be composed of any number of the following numeric + replies. + + RPL_TRACECONNECTING RPL_TRACEHANDSHAKE + RPL_TRACEUNKNOWN RPL_TRACEOPERATOR + RPL_TRACEUSER RPL_TRACESERVER + RPL_TRACESERVICE RPL_TRACENEWTYPE + RPL_TRACECLASS + + Examples: + +TRACE *.oulu.fi ; TRACE to a server matching *.oulu.fi + +:WiZ TRACE AngelDust ; TRACE issued by WiZ to nick AngelDust + +4.3.7 Admin command + + Command: ADMIN + Parameters: [<server>] + + The admin message is used to find the name of the administrator of + the given server, or current server if <server> parameter is omitted. + Each server must have the ability to forward ADMIN messages to other + servers. + + Numeric Replies: + + ERR_NOSUCHSERVER + RPL_ADMINME RPL_ADMINLOC1 + RPL_ADMINLOC2 RPL_ADMINEMAIL + + Examples: + + ADMIN tolsun.oulu.fi ; request an ADMIN reply from + tolsun.oulu.fi + + :WiZ ADMIN *.edu ; ADMIN request from WiZ for first + server found to match *.edu. + +4.3.8 Info command + + Command: INFO + Parameters: [<server>] + + The INFO command is required to return information which describes + the server: its version, when it was compiled, the patchlevel, when + it was started, and any other miscellaneous information which may be + considered to be relevant. + + Numeric Replies: + + ERR_NOSUCHSERVER + RPL_INFO RPL_ENDOFINFO + + Examples: + + INFO csd.bu.edu ; request an INFO reply from + csd.bu.edu + + :Avalon INFO *.fi ; INFO request from Avalon for first + server found to match *.fi. + + INFO Angel ; request info from the server that + Angel is connected to. + +4.4 Sending messages + + The main purpose of the IRC protocol is to provide a base for clients + to communicate with each other. PRIVMSG and NOTICE are the only + messages available which actually perform delivery of a text message + from one client to another - the rest just make it possible and try + to ensure it happens in a reliable and structured manner. + +4.4.1 Private messages + + Command: PRIVMSG + Parameters: <receiver>{,<receiver>} <text to be sent> + + PRIVMSG is used to send private messages between users. <receiver> + is the nickname of the receiver of the message. <receiver> can also + be a list of names or channels separated with commas. + + The <receiver> parameter may also me a host mask (#mask) or server + mask ($mask). In both cases the server will only send the PRIVMSG + to those who have a server or host matching the mask. The mask must + have at least 1 (one) "." in it and no wildcards following the + last ".". This requirement exists to prevent people sending messages + to "#*" or "$*", which would broadcast to all users; from + experience, this is abused more than used responsibly and properly. + Wildcards are the '*' and '?' characters. This extension to + the PRIVMSG command is only available to Operators. + + Numeric Replies: + + ERR_NORECIPIENT ERR_NOTEXTTOSEND + ERR_CANNOTSENDTOCHAN ERR_NOTOPLEVEL + ERR_WILDTOPLEVEL ERR_TOOMANYTARGETS + ERR_NOSUCHNICK + RPL_AWAY + + Examples: + +:Angel PRIVMSG Wiz :Hello are you receiving this message ? + ; Message from Angel to Wiz. + +PRIVMSG Angel :yes I'm receiving it !receiving it !'u>(768u+1n) .br ; + Message to Angel. + +PRIVMSG jto@tolsun.oulu.fi :Hello ! + ; Message to a client on server + + tolsun.oulu.fi with username of "jto". + +PRIVMSG $*.fi :Server tolsun.oulu.fi rebooting. + ; Message to everyone on a server which + has a name matching *.fi. + +PRIVMSG #*.edu :NSFNet is undergoing work, expect interruptions + ; Message to all users who come from a + host which has a name matching *.edu. + +4.4.2 Notice + + Command: NOTICE + Parameters: <nickname> <text> + + The NOTICE message is used similarly to PRIVMSG. The difference + between NOTICE and PRIVMSG is that automatic replies must never be + sent in response to a NOTICE message. This rule applies to servers + too - they must not send any error reply back to the client on + receipt of a notice. The object of this rule is to avoid loops + between a client automatically sending something in response to + something it received. This is typically used by automatons (clients + with either an AI or other interactive program controlling their + actions) which are always seen to be replying lest they end up in a + loop with another automaton. + + See PRIVMSG for more details on replies and examples. + +4.5 User based queries + + User queries are a group of commands which are primarily concerned + with finding details on a particular user or group users. When using + wildcards with any of these commands, if they match, they will only + return information on users who are 'visible' to you. The visibility + of a user is determined as a combination of the user's mode and the + common set of channels you are both on. + +4.5.1 Who query + + Command: WHO + Parameters: [<name> [<o>]] + + The WHO message is used by a client to generate a query which returns + a list of information which 'matches' the <name> parameter given by + the client. In the absence of the <name> parameter, all visible + (users who aren't invisible (user mode +i) and who don't have a + common channel with the requesting client) are listed. The same + result can be achieved by using a <name> of "0" or any wildcard which + + will end up matching every entry possible. + + The <name> passed to WHO is matched against users' host, server, real + name and nickname if the channel <name> cannot be found. + + If the "o" parameter is passed only operators are returned according + to the name mask supplied. + + Numeric Replies: + + ERR_NOSUCHSERVER + RPL_WHOREPLY RPL_ENDOFWHO + + Examples: + + WHO *.fi ; List all users who match against + "*.fi". + + WHO jto* o ; List all users with a match against + "jto*" if they are an operator. + +4.5.2 Whois query + + Command: WHOIS + Parameters: [<server>] <nickmask>[,<nickmask>[,...]] + + This message is used to query information about particular user. The + server will answer this message with several numeric messages + indicating different statuses of each user which matches the nickmask + (if you are entitled to see them). If no wildcard is present in the + <nickmask>, any information about that nick which you are allowed to + see is presented. A comma (',') separated list of nicknames may be + given. + + The latter version sends the query to a specific server. It is + useful if you want to know how long the user in question has been + idle as only local server (ie. the server the user is directly + connected to) knows that information, while everything else is + globally known. + + Numeric Replies: + + ERR_NOSUCHSERVER ERR_NONICKNAMEGIVEN + RPL_WHOISUSER RPL_WHOISCHANNELS + RPL_WHOISCHANNELS RPL_WHOISSERVER + RPL_AWAY RPL_WHOISOPERATOR + RPL_WHOISIDLE ERR_NOSUCHNICK + RPL_ENDOFWHOIS + + Examples: + + WHOIS wiz ; return available user information + about nick WiZ + + WHOIS eff.org trillian ; ask server eff.org for user + information about trillian + +4.5.3 Whowas + + Command: WHOWAS + Parameters: <nickname> [<count> [<server>]] + + Whowas asks for information about a nickname which no longer exists. + This may either be due to a nickname change or the user leaving IRC. + In response to this query, the server searches through its nickname + history, looking for any nicks which are lexically the same (no wild + card matching here). The history is searched backward, returning the + most recent entry first. If there are multiple entries, up to + <count> replies will be returned (or all of them if no <count> + parameter is given). If a non-positive number is passed as being + <count>, then a full search is done. + + Numeric Replies: + + ERR_NONICKNAMEGIVEN ERR_WASNOSUCHNICK + RPL_WHOWASUSER RPL_WHOISSERVER + RPL_ENDOFWHOWAS + + Examples: + + WHOWAS Wiz ; return all information in the nick + history about nick "WiZ"; + + WHOWAS Mermaid 9 ; return at most, the 9 most recent + entries in the nick history for + "Mermaid"; + + WHOWAS Trillian 1 *.edu ; return the most recent history for + "Trillian" from the first server found + to match "*.edu". + +4.6 Miscellaneous messages + + Messages in this category do not fit into any of the above categories + but are nonetheless still a part of and required by the protocol. + +4.6.1 Kill message + + Command: KILL + Parameters: <nickname> <comment> + + The KILL message is used to cause a client-server connection to be + closed by the server which has the actual connection. KILL is used + by servers when they encounter a duplicate entry in the list of valid + nicknames and is used to remove both entries. It is also available + to operators. + + Clients which have automatic reconnect algorithms effectively make + this command useless since the disconnection is only brief. It does + however break the flow of data and can be used to stop large amounts + of being abused, any user may elect to receive KILL messages + generated for others to keep an 'eye' on would be trouble spots. + + In an arena where nicknames are required to be globally unique at all + times, KILL messages are sent whenever 'duplicates' are detected + (that is an attempt to register two users with the same nickname) in + the hope that both of them will disappear and only 1 reappear. + + The comment given must reflect the actual reason for the KILL. For + server-generated KILLs it usually is made up of details concerning + the origins of the two conflicting nicknames. For users it is left + up to them to provide an adequate reason to satisfy others who see + it. To prevent/discourage fake KILLs from being generated to hide + the identify of the KILLer, the comment also shows a 'kill-path' + which is updated by each server it passes through, each prepending + its name to the path. + + Numeric Replies: + + ERR_NOPRIVILEGES ERR_NEEDMOREPARAMS + ERR_NOSUCHNICK ERR_CANTKILLSERVER + + KILL David (csd.bu.edu <- tolsun.oulu.fi) + ; Nickname collision between csd.bu.edu + and tolson.oulu.fi + + NOTE: + It is recommended that only Operators be allowed to kill other users + with KILL message. In an ideal world not even operators would need + to do this and it would be left to servers to deal with. + +4.6.2 Ping message + + Command: PING + Parameters: <server1> [<server2>] + + The PING message is used to test the presence of an active client at + the other end of the connection. A PING message is sent at regular + intervals if no other activity detected coming from a connection. If + a connection fails to respond to a PING command within a set amount + of time, that connection is closed. + + Any client which receives a PING message must respond to <server1> + (server which sent the PING message out) as quickly as possible with + an appropriate PONG message to indicate it is still there and alive. + Servers should not respond to PING commands but rely on PINGs from + the other end of the connection to indicate the connection is alive. + If the <server2> parameter is specified, the PING message gets + forwarded there. + + Numeric Replies: + + ERR_NOORIGIN ERR_NOSUCHSERVER + + Examples: + + PING tolsun.oulu.fi ; server sending a PING message to + another server to indicate it is still + alive. + + PING WiZ ; PING message being sent to nick WiZ + +4.6.3 Pong message + + Command: PONG + Parameters: <daemon> [<daemon2>] + + PONG message is a reply to ping message. If parameter <daemon2> is + given this message must be forwarded to given daemon. The <daemon> + parameter is the name of the daemon who has responded to PING message + and generated this message. + + Numeric Replies: + + ERR_NOORIGIN ERR_NOSUCHSERVER + + Examples: + + PONG csd.bu.edu tolsun.oulu.fi ; PONG message from csd.bu.edu to + + tolsun.oulu.fi + +4.6.4 Error + + Command: ERROR + Parameters: <error message> + + The ERROR command is for use by servers when reporting a serious or + fatal error to its operators. It may also be sent from one server to + another but must not be accepted from any normal unknown clients. + + An ERROR message is for use for reporting errors which occur with a + server-to-server link only. An ERROR message is sent to the server + at the other end (which sends it to all of its connected operators) + and to all operators currently connected. It is not to be passed + onto any other servers by a server if it is received from a server. + + When a server sends a received ERROR message to its operators, the + message should be encapsulated inside a NOTICE message, indicating + that the client was not responsible for the error. + + Numerics: + + None. + + Examples: + + ERROR :Server *.fi already exists; ERROR message to the other server + which caused this error. + + NOTICE WiZ :ERROR from csd.bu.edu -- Server *.fi already exists + ; Same ERROR message as above but sent + to user WiZ on the other server. + +5. OPTIONALS + + This section describes OPTIONAL messages. They are not required in a + working server implementation of the protocol described herein. In + the absence of the option, an error reply message must be generated + or an unknown command error. If the message is destined for another + server to answer then it must be passed on (elementary parsing + required) The allocated numerics for this are listed with the + messages below. + +5.1 Away + + Command: AWAY + Parameters: [message] + + With the AWAY message, clients can set an automatic reply string for + any PRIVMSG commands directed at them (not to a channel they are on). + The automatic reply is sent by the server to client sending the + PRIVMSG command. The only replying server is the one to which the + sending client is connected to. + + The AWAY message is used either with one parameter (to set an AWAY + message) or with no parameters (to remove the AWAY message). + + Numeric Replies: + + RPL_UNAWAY RPL_NOWAWAY + + Examples: + + AWAY :Gone to lunch. Back in 5 ; set away message to "Gone to lunch. + Back in 5". + + :WiZ AWAY ; unmark WiZ as being away. + +5.2 Rehash message + + Command: REHASH + Parameters: None + + The rehash message can be used by the operator to force the server to + re-read and process its configuration file. + + Numeric Replies: + + RPL_REHASHING ERR_NOPRIVILEGES + +Examples: + +REHASH ; message from client with operator + status to server asking it to reread its + configuration file. + +5.3 Restart message + + Command: RESTART + Parameters: None + + The restart message can only be used by an operator to force a server + restart itself. This message is optional since it may be viewed as a + risk to allow arbitrary people to connect to a server as an operator + and execute this command, causing (at least) a disruption to service. + + The RESTART command must always be fully processed by the server to + which the sending client is connected and not be passed onto other + connected servers. + + Numeric Replies: + + ERR_NOPRIVILEGES + + Examples: + + RESTART ; no parameters required. + +5.4 Summon message + + Command: SUMMON + Parameters: <user> [<server>] + + The SUMMON command can be used to give users who are on a host + running an IRC server a message asking them to please join IRC. This + message is only sent if the target server (a) has SUMMON enabled, (b) + the user is logged in and (c) the server process can write to the + user's tty (or similar). + + If no <server> parameter is given it tries to summon <user> from the + server the client is connected to is assumed as the target. + + If summon is not enabled in a server, it must return the + ERR_SUMMONDISABLED numeric and pass the summon message onwards. + + Numeric Replies: + + ERR_NORECIPIENT ERR_FILEERROR + ERR_NOLOGIN ERR_NOSUCHSERVER + RPL_SUMMONING + + Examples: + + SUMMON jto ; summon user jto on the server's host + + SUMMON jto tolsun.oulu.fi ; summon user jto on the host which a + server named "tolsun.oulu.fi" is + running. + +5.5 Users + + Command: USERS + Parameters: [<server>] + + The USERS command returns a list of users logged into the server in a + similar format to who(1), rusers(1) and finger(1). Some people + may disable this command on their server for security related + reasons. If disabled, the correct numeric must be returned to + indicate this. + + Numeric Replies: + + ERR_NOSUCHSERVER ERR_FILEERROR + RPL_USERSSTART RPL_USERS + RPL_NOUSERS RPL_ENDOFUSERS + ERR_USERSDISABLED + + Disabled Reply: + + ERR_USERSDISABLED + + Examples: + +USERS eff.org ; request a list of users logged in on + server eff.org + +:John USERS tolsun.oulu.fi ; request from John for a list of users + logged in on server tolsun.oulu.fi + +5.6 Operwall message + + Command: WALLOPS + Parameters: Text to be sent to all operators currently online + + Sends a message to all operators currently online. After + implementing WALLOPS as a user command it was found that it was + often and commonly abused as a means of sending a message to a lot + of people (much similar to WALL). Due to this it is recommended + that the current implementation of WALLOPS be used as an + example by allowing and recognising only servers as the senders of + WALLOPS. + + Numeric Replies: + + ERR_NEEDMOREPARAMS + + Examples: + + :csd.bu.edu WALLOPS :Connect '*.uiuc.edu 6667' from Joshua; WALLOPS + message from csd.bu.edu announcing a + CONNECT message it received and acted + upon from Joshua. + +5.7 Userhost message + + Command: USERHOST + Parameters: <nickname>{<space><nickname>} + + The USERHOST command takes a list of up to 5 nicknames, each + separated by a space character and returns a list of information + about each nickname that it found. The returned list has each reply + separated by a space. + + Numeric Replies: + + RPL_USERHOST ERR_NEEDMOREPARAMS + + Examples: + + USERHOST Wiz Michael Marty p ;USERHOST request for information on + nicks "Wiz", "Michael", "Marty" and "p" + +5.8 Ison message + + Command: ISON + Parameters: <nickname>{<space><nickname>} + + The ISON command was implemented to provide a quick and efficient + means to get a response about whether a given nickname was currently + on IRC. ISON only takes one (1) parameter: a space-separated list of + nicks. For each nickname in the list that is present, the server + adds that to its reply string. Thus the reply string may return + empty (none of the given nicks are present), an exact copy of the + parameter string (all of them present) or as any other subset of the + set of nicks given in the parameter. The only limit on the number + of nicks that may be checked is that the combined length must not be + too large as to cause the server to chop it off so it fits in 512 + characters. + + ISON is only be processed by the server local to the client sending + the command and thus not passed onto other servers for further + processing. + + Numeric Replies: + + RPL_ISON ERR_NEEDMOREPARAMS + + Examples: + + ISON phone trillian WiZ jarlek Avalon Angel Monstah + ; Sample ISON request for 7 nicks. + +6. REPLIES + + The following is a list of numeric replies which are generated in + response to the commands given above. Each numeric is given with its + number, name and reply string. + +6.1 Error Replies. + + 401 ERR_NOSUCHNICK + "<nickname> :No such nick/channel" + + - Used to indicate the nickname parameter supplied to a + command is currently unused. + + 402 ERR_NOSUCHSERVER + "<server name> :No such server" + + - Used to indicate the server name given currently + doesn't exist. + + 403 ERR_NOSUCHCHANNEL + "<channel name> :No such channel" + + - Used to indicate the given channel name is invalid. + + 404 ERR_CANNOTSENDTOCHAN + "<channel name> :Cannot send to channel" + + - Sent to a user who is either (a) not on a channel + which is mode +n or (b) not a chanop (or mode +v) on + a channel which has mode +m set and is trying to send + a PRIVMSG message to that channel. + + 405 ERR_TOOMANYCHANNELS + "<channel name> :You have joined too many \ + channels" + - Sent to a user when they have joined the maximum + number of allowed channels and they try to join + another channel. + + 406 ERR_WASNOSUCHNICK + "<nickname> :There was no such nickname" + + - Returned by WHOWAS to indicate there is no history + information for that nickname. + + 407 ERR_TOOMANYTARGETS + "<target> :Duplicate recipients. No message \ + + delivered" + + - Returned to a client which is attempting to send a + PRIVMSG/NOTICE using the user@host destination format + and for a user@host which has several occurrences. + + 409 ERR_NOORIGIN + ":No origin specified" + + - PING or PONG message missing the originator parameter + which is required since these commands must work + without valid prefixes. + + 411 ERR_NORECIPIENT + ":No recipient given (<command>)" + 412 ERR_NOTEXTTOSEND + ":No text to send" + 413 ERR_NOTOPLEVEL + "<mask> :No toplevel domain specified" + 414 ERR_WILDTOPLEVEL + "<mask> :Wildcard in toplevel domain" + + - 412 - 414 are returned by PRIVMSG to indicate that + the message wasn't delivered for some reason. + ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that + are returned when an invalid use of + "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted. + + 421 ERR_UNKNOWNCOMMAND + "<command> :Unknown command" + + - Returned to a registered client to indicate that the + command sent is unknown by the server. + + 422 ERR_NOMOTD + ":MOTD File is missing" + + - Server's MOTD file could not be opened by the server. + + 423 ERR_NOADMININFO + "<server> :No administrative info available" + + - Returned by a server in response to an ADMIN message + when there is an error in finding the appropriate + information. + + 424 ERR_FILEERROR + ":File error doing <file op> on <file>" + + - Generic error message used to report a failed file + operation during the processing of a message. + + 431 ERR_NONICKNAMEGIVEN + ":No nickname given" + + - Returned when a nickname parameter expected for a + command and isn't found. + + 432 ERR_ERRONEUSNICKNAME + "<nick> :Erroneus nickname" + + - Returned after receiving a NICK message which contains + characters which do not fall in the defined set. See + section x.x.x for details on valid nicknames. + + 433 ERR_NICKNAMEINUSE + "<nick> :Nickname is already in use" + + - Returned when a NICK message is processed that results + in an attempt to change to a currently existing + nickname. + + 436 ERR_NICKCOLLISION + "<nick> :Nickname collision KILL" + + - Returned by a server to a client when it detects a + nickname collision (registered of a NICK that + already exists by another server). + + 441 ERR_USERNOTINCHANNEL + "<nick> <channel> :They aren't on that channel" + + - Returned by the server to indicate that the target + user of the command is not on the given channel. + + 442 ERR_NOTONCHANNEL + "<channel> :You're not on that channel" + + - Returned by the server whenever a client tries to + perform a channel effecting command for which the + client isn't a member. + + 443 ERR_USERONCHANNEL + "<user> <channel> :is already on channel" + + - Returned when a client tries to invite a user to a + channel they are already on. + + 444 ERR_NOLOGIN + "<user> :User not logged in" + + - Returned by the summon after a SUMMON command for a + user was unable to be performed since they were not + logged in. + + 445 ERR_SUMMONDISABLED + ":SUMMON has been disabled" + + - Returned as a response to the SUMMON command. Must be + returned by any server which does not implement it. + + 446 ERR_USERSDISABLED + ":USERS has been disabled" + + - Returned as a response to the USERS command. Must be + returned by any server which does not implement it. + + 451 ERR_NOTREGISTERED + ":You have not registered" + + - Returned by the server to indicate that the client + must be registered before the server will allow it + to be parsed in detail. + + 461 ERR_NEEDMOREPARAMS + "<command> :Not enough parameters" + + - Returned by the server by numerous commands to + indicate to the client that it didn't supply enough + parameters. + + 462 ERR_ALREADYREGISTRED + ":You may not reregister" + + - Returned by the server to any link which tries to + change part of the registered details (such as + password or user details from second USER message). + + 463 ERR_NOPERMFORHOST + ":Your host isn't among the privileged" + + - Returned to a client which attempts to register with + a server which does not been setup to allow + connections from the host the attempted connection + is tried. + + 464 ERR_PASSWDMISMATCH + ":Password incorrect" + + - Returned to indicate a failed attempt at registering + a connection for which a password was required and + was either not given or incorrect. + + 465 ERR_YOUREBANNEDCREEP + ":You are banned from this server" + + - Returned after an attempt to connect and register + yourself with a server which has been setup to + explicitly deny connections to you. + + 467 ERR_KEYSET + "<channel> :Channel key already set" + 471 ERR_CHANNELISFULL + "<channel> :Cannot join channel (+l)" + 472 ERR_UNKNOWNMODE + "<char> :is unknown mode char to me" + 473 ERR_INVITEONLYCHAN + "<channel> :Cannot join channel (+i)" + 474 ERR_BANNEDFROMCHAN + "<channel> :Cannot join channel (+b)" + 475 ERR_BADCHANNELKEY + "<channel> :Cannot join channel (+k)" + 481 ERR_NOPRIVILEGES + ":Permission Denied- You're not an IRC operator" + + - Any command requiring operator privileges to operate + must return this error to indicate the attempt was + unsuccessful. + + 482 ERR_CHANOPRIVSNEEDED + "<channel> :You're not channel operator" + + - Any command requiring 'chanop' privileges (such as + MODE messages) must return this error if the client + making the attempt is not a chanop on the specified + channel. + + 483 ERR_CANTKILLSERVER + ":You cant kill a server!" + + - Any attempts to use the KILL command on a server + are to be refused and this error returned directly + to the client. + + 491 ERR_NOOPERHOST + ":No O-lines for your host" + + - If a client sends an OPER message and the server has + not been configured to allow connections from the + client's host as an operator, this error must be + returned. + + 501 ERR_UMODEUNKNOWNFLAG + ":Unknown MODE flag" + + - Returned by the server to indicate that a MODE + message was sent with a nickname parameter and that + the a mode flag sent was not recognized. + + 502 ERR_USERSDONTMATCH + ":Cant change mode for other users" + + - Error sent to any user trying to view or change the + user mode for a user other than themselves. + +6.2 Command responses. + + 300 RPL_NONE + Dummy reply number. Not used. + + 302 RPL_USERHOST + ":[<reply>{<space><reply>}]" + + - Reply format used by USERHOST to list replies to + the query list. The reply string is composed as + follows: + + <reply> ::= <nick>['*'] '=' <'+'|'-'><hostname> + + The '*' indicates whether the client has registered + as an Operator. The '-' or '+' characters represent + whether the client has set an AWAY message or not + respectively. + + 303 RPL_ISON + ":[<nick> {<space><nick>}]" + + - Reply format used by ISON to list replies to the + query list. + + 301 RPL_AWAY + "<nick> :<away message>" + + 305 RPL_UNAWAY + ":You are no longer marked as being away" + 306 RPL_NOWAWAY + ":You have been marked as being away" + + - These replies are used with the AWAY command (if + allowed). RPL_AWAY is sent to any client sending a + PRIVMSG to a client which is away. RPL_AWAY is only + sent by the server to which the client is connected. + Replies RPL_UNAWAY and RPL_NOWAWAY are sent when the + client removes and sets an AWAY message. + + 311 RPL_WHOISUSER + "<nick> <user> <host> * :<real name>" + 312 RPL_WHOISSERVER + "<nick> <server> :<server info>" + 313 RPL_WHOISOPERATOR + "<nick> :is an IRC operator" + 317 RPL_WHOISIDLE + "<nick> <integer> :seconds idle" + 318 RPL_ENDOFWHOIS + "<nick> :End of /WHOIS list" + 319 RPL_WHOISCHANNELS + "<nick> :{[@|+]<channel><space>}" + + - Replies 311 - 313, 317 - 319 are all replies + generated in response to a WHOIS message. Given that + there are enough parameters present, the answering + server must either formulate a reply out of the above + numerics (if the query nick is found) or return an + error reply. The '*' in RPL_WHOISUSER is there as + the literal character and not as a wild card. For + each reply set, only RPL_WHOISCHANNELS may appear + more than once (for long lists of channel names). + The '@' and '+' characters next to the channel name + indicate whether a client is a channel operator or + has been granted permission to speak on a moderated + channel. The RPL_ENDOFWHOIS reply is used to mark + the end of processing a WHOIS message. + + 314 RPL_WHOWASUSER + "<nick> <user> <host> * :<real name>" + 369 RPL_ENDOFWHOWAS + "<nick> :End of WHOWAS" + + - When replying to a WHOWAS message, a server must use + the replies RPL_WHOWASUSER, RPL_WHOISSERVER or + ERR_WASNOSUCHNICK for each nickname in the presented + + list. At the end of all reply batches, there must + be RPL_ENDOFWHOWAS (even if there was only one reply + and it was an error). + + 321 RPL_LISTSTART + "Channel :Users Name" + 322 RPL_LIST + "<channel> <# visible> :<topic>" + 323 RPL_LISTEND + ":End of /LIST" + + - Replies RPL_LISTSTART, RPL_LIST, RPL_LISTEND mark + the start, actual replies with data and end of the + server's response to a LIST command. If there are + no channels available to return, only the start + and end reply must be sent. + + 324 RPL_CHANNELMODEIS + "<channel> <mode> <mode params>" + + 331 RPL_NOTOPIC + "<channel> :No topic is set" + 332 RPL_TOPIC + "<channel> :<topic>" + + - When sending a TOPIC message to determine the + channel topic, one of two replies is sent. If + the topic is set, RPL_TOPIC is sent back else + RPL_NOTOPIC. + + 341 RPL_INVITING + "<channel> <nick>" + + - Returned by the server to indicate that the + attempted INVITE message was successful and is + being passed onto the end client. + + 342 RPL_SUMMONING + "<user> :Summoning user to IRC" + + - Returned by a server answering a SUMMON message to + indicate that it is summoning that user. + + 351 RPL_VERSION + "<version>.<debuglevel> <server> :<comments>" + + - Reply by the server showing its version details. + The <version> is the version of the software being + + used (including any patchlevel revisions) and the + <debuglevel> is used to indicate if the server is + running in "debug mode". + + The "comments" field may contain any comments about + the version or further version details. + + 352 RPL_WHOREPLY + "<channel> <user> <host> <server> <nick> \ + <H|G>[*][@|+] :<hopcount> <real name>" + 315 RPL_ENDOFWHO + "<name> :End of /WHO list" + + - The RPL_WHOREPLY and RPL_ENDOFWHO pair are used + to answer a WHO message. The RPL_WHOREPLY is only + sent if there is an appropriate match to the WHO + query. If there is a list of parameters supplied + with a WHO message, a RPL_ENDOFWHO must be sent + after processing each list item with <name> being + the item. + + 353 RPL_NAMREPLY + "<channel> :[[@|+]<nick> [[@|+]<nick> [...]]]" + 366 RPL_ENDOFNAMES + "<channel> :End of /NAMES list" + + - To reply to a NAMES message, a reply pair consisting + of RPL_NAMREPLY and RPL_ENDOFNAMES is sent by the + server back to the client. If there is no channel + found as in the query, then only RPL_ENDOFNAMES is + returned. The exception to this is when a NAMES + message is sent with no parameters and all visible + channels and contents are sent back in a series of + RPL_NAMEREPLY messages with a RPL_ENDOFNAMES to mark + the end. + + 364 RPL_LINKS + "<mask> <server> :<hopcount> <server info>" + 365 RPL_ENDOFLINKS + "<mask> :End of /LINKS list" + + - In replying to the LINKS message, a server must send + replies back using the RPL_LINKS numeric and mark the + end of the list using an RPL_ENDOFLINKS reply. + + 367 RPL_BANLIST + "<channel> <banid>" + 368 RPL_ENDOFBANLIST + + "<channel> :End of channel ban list" + + - When listing the active 'bans' for a given channel, + a server is required to send the list back using the + RPL_BANLIST and RPL_ENDOFBANLIST messages. A separate + RPL_BANLIST is sent for each active banid. After the + banids have been listed (or if none present) a + RPL_ENDOFBANLIST must be sent. + + 371 RPL_INFO + ":<string>" + 374 RPL_ENDOFINFO + ":End of /INFO list" + + - A server responding to an INFO message is required to + send all its 'info' in a series of RPL_INFO messages + with a RPL_ENDOFINFO reply to indicate the end of the + replies. + + 375 RPL_MOTDSTART + ":- <server> Message of the day - " + 372 RPL_MOTD + ":- <text>" + 376 RPL_ENDOFMOTD + ":End of /MOTD command" + + - When responding to the MOTD message and the MOTD file + is found, the file is displayed line by line, with + each line no longer than 80 characters, using + RPL_MOTD format replies. These should be surrounded + by a RPL_MOTDSTART (before the RPL_MOTDs) and an + RPL_ENDOFMOTD (after). + + 381 RPL_YOUREOPER + ":You are now an IRC operator" + + - RPL_YOUREOPER is sent back to a client which has + just successfully issued an OPER message and gained + operator status. + + 382 RPL_REHASHING + "<config file> :Rehashing" + + - If the REHASH option is used and an operator sends + a REHASH message, an RPL_REHASHING is sent back to + the operator. + + 391 RPL_TIME + + "<server> :<string showing server's local time>" + + - When replying to the TIME message, a server must send + the reply using the RPL_TIME format above. The string + showing the time need only contain the correct day and + time there. There is no further requirement for the + time string. + + 392 RPL_USERSSTART + ":UserID Terminal Host" + 393 RPL_USERS + ":%-8s %-9s %-8s" + 394 RPL_ENDOFUSERS + ":End of users" + 395 RPL_NOUSERS + ":Nobody logged in" + + - If the USERS message is handled by a server, the + replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and + RPL_NOUSERS are used. RPL_USERSSTART must be sent + first, following by either a sequence of RPL_USERS + or a single RPL_NOUSER. Following this is + RPL_ENDOFUSERS. + + 200 RPL_TRACELINK + "Link <version & debug level> <destination> \ + <next server>" + 201 RPL_TRACECONNECTING + "Try. <class> <server>" + 202 RPL_TRACEHANDSHAKE + "H.S. <class> <server>" + 203 RPL_TRACEUNKNOWN + "???? <class> [<client IP address in dot form>]" + 204 RPL_TRACEOPERATOR + "Oper <class> <nick>" + 205 RPL_TRACEUSER + "User <class> <nick>" + 206 RPL_TRACESERVER + "Serv <class> <int>S <int>C <server> \ + <nick!user|*!*>@<host|server>" + 208 RPL_TRACENEWTYPE + "<newtype> 0 <client name>" + 261 RPL_TRACELOG + "File <logfile> <debug level>" + + - The RPL_TRACE* are all returned by the server in + response to the TRACE message. How many are + returned is dependent on the the TRACE message and + + whether it was sent by an operator or not. There + is no predefined order for which occurs first. + Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and + RPL_TRACEHANDSHAKE are all used for connections + which have not been fully established and are either + unknown, still attempting to connect or in the + process of completing the 'server handshake'. + RPL_TRACELINK is sent by any server which handles + a TRACE message and has to pass it on to another + server. The list of RPL_TRACELINKs sent in + response to a TRACE command traversing the IRC + network should reflect the actual connectivity of + the servers themselves along that path. + RPL_TRACENEWTYPE is to be used for any connection + which does not fit in the other categories but is + being displayed anyway. + + 211 RPL_STATSLINKINFO + "<linkname> <sendq> <sent messages> \ + <sent bytes> <received messages> \ + <received bytes> <time open>" + 212 RPL_STATSCOMMANDS + "<command> <count>" + 213 RPL_STATSCLINE + "C <host> * <name> <port> <class>" + 214 RPL_STATSNLINE + "N <host> * <name> <port> <class>" + 215 RPL_STATSILINE + "I <host> * <host> <port> <class>" + 216 RPL_STATSKLINE + "K <host> * <username> <port> <class>" + 218 RPL_STATSYLINE + "Y <class> <ping frequency> <connect \ + frequency> <max sendq>" + 219 RPL_ENDOFSTATS + "<stats letter> :End of /STATS report" + 241 RPL_STATSLLINE + "L <hostmask> * <servername> <maxdepth>" + 242 RPL_STATSUPTIME + ":Server Up %d days %d:%02d:%02d" + 243 RPL_STATSOLINE + "O <hostmask> * <name>" + 244 RPL_STATSHLINE + "H <hostmask> * <servername>" + + 221 RPL_UMODEIS + "<user mode string>" + + - To answer a query about a client's own mode, + RPL_UMODEIS is sent back. + + 251 RPL_LUSERCLIENT + ":There are <integer> users and <integer> \ + invisible on <integer> servers" + 252 RPL_LUSEROP + "<integer> :operator(s) online" + 253 RPL_LUSERUNKNOWN + "<integer> :unknown connection(s)" + 254 RPL_LUSERCHANNELS + "<integer> :channels formed" + 255 RPL_LUSERME + ":I have <integer> clients and <integer> \ + servers" + + - In processing an LUSERS message, the server + sends a set of replies from RPL_LUSERCLIENT, + RPL_LUSEROP, RPL_USERUNKNOWN, + RPL_LUSERCHANNELS and RPL_LUSERME. When + replying, a server must send back + RPL_LUSERCLIENT and RPL_LUSERME. The other + replies are only sent back if a non-zero count + is found for them. + + 256 RPL_ADMINME + "<server> :Administrative info" + 257 RPL_ADMINLOC1 + ":<admin info>" + 258 RPL_ADMINLOC2 + ":<admin info>" + 259 RPL_ADMINEMAIL + ":<admin info>" + + - When replying to an ADMIN message, a server + is expected to use replies RLP_ADMINME + through to RPL_ADMINEMAIL and provide a text + message with each. For RPL_ADMINLOC1 a + description of what city, state and country + the server is in is expected, followed by + details of the university and department + (RPL_ADMINLOC2) and finally the administrative + contact for the server (an email address here + is required) in RPL_ADMINEMAIL. + +6.3 Reserved numerics. + + These numerics are not described above since they fall into one of + the following categories: + + 1. no longer in use; + + 2. reserved for future planned use; + + 3. in current use but are part of a non-generic 'feature' of + the current IRC server. + + 209 RPL_TRACECLASS 217 RPL_STATSQLINE + 231 RPL_SERVICEINFO 232 RPL_ENDOFSERVICES + 233 RPL_SERVICE 234 RPL_SERVLIST + 235 RPL_SERVLISTEND + 316 RPL_WHOISCHANOP 361 RPL_KILLDONE + 362 RPL_CLOSING 363 RPL_CLOSEEND + 373 RPL_INFOSTART 384 RPL_MYPORTIS + 466 ERR_YOUWILLBEBANNED 476 ERR_BADCHANMASK + 492 ERR_NOSERVICEHOST + +7. Client and server authentication + + Clients and servers are both subject to the same level of + authentication. For both, an IP number to hostname lookup (and + reverse check on this) is performed for all connections made to the + server. Both connections are then subject to a password check (if + there is a password set for that connection). These checks are + possible on all connections although the password check is only + commonly used with servers. + + An additional check that is becoming of more and more common is that + of the username responsible for making the connection. Finding the + username of the other end of the connection typically involves + connecting to an authentication server such as IDENT as described in + RFC 1413. + + Given that without passwords it is not easy to reliably determine who + is on the other end of a network connection, use of passwords is + strongly recommended on inter-server connections in addition to any + other measures such as using an ident server. + +8. Current implementations + + The only current implementation of this protocol is the IRC server, + version 2.8. Earlier versions may implement some or all of the + commands described by this document with NOTICE messages replacing + + many of the numeric replies. Unfortunately, due to backward + compatibility requirements, the implementation of some parts of this + document varies with what is laid out. On notable difference is: + + * recognition that any LF or CR anywhere in a message marks the + end of that message (instead of requiring CR-LF); + + The rest of this section deals with issues that are mostly of + importance to those who wish to implement a server but some parts + also apply directly to clients as well. + +8.1 Network protocol: TCP - why it is best used here. + + IRC has been implemented on top of TCP since TCP supplies a reliable + network protocol which is well suited to this scale of conferencing. + The use of multicast IP is an alternative, but it is not widely + available or supported at the present time. + +8.1.1 Support of Unix sockets + + Given that Unix domain sockets allow listen/connect operations, the + current implementation can be configured to listen and accept both + client and server connections on a Unix domain socket. These are + recognized as sockets where the hostname starts with a '/'. + + When providing any information about the connections on a Unix domain + socket, the server is required to supplant the actual hostname in + place of the pathname unless the actual socket name is being asked + for. + +8.2 Command Parsing + + To provide useful 'non-buffered' network IO for clients and servers, + each connection is given its own private 'input buffer' in which the + results of the most recent read and parsing are kept. A buffer size + of 512 bytes is used so as to hold 1 full message, although, this + will usually hold several commands. The private buffer is parsed + after every read operation for valid messages. When dealing with + multiple messages from one client in the buffer, care should be taken + in case one happens to cause the client to be 'removed'. + +8.3 Message delivery + + It is common to find network links saturated or hosts to which you + are sending data unable to send data. Although Unix typically + handles this through the TCP window and internal buffers, the server + often has large amounts of data to send (especially when a new + server-server link forms) and the small buffers provided in the + + kernel are not enough for the outgoing queue. To alleviate this + problem, a "send queue" is used as a FIFO queue for data to be sent. + A typical "send queue" may grow to 200 Kbytes on a large IRC network + with a slow network connection when a new server connects. + + When polling its connections, a server will first read and parse all + incoming data, queuing any data to be sent out. When all available + input is processed, the queued data is sent. This reduces the number + of write() system calls and helps TCP make bigger packets. + +8.4 Connection 'Liveness' + + To detect when a connection has died or become unresponsive, the + server must ping each of its connections that it doesn't get a + response from in a given amount of time. + + If a connection doesn't respond in time, its connection is closed + using the appropriate procedures. A connection is also dropped if + its sendq grows beyond the maximum allowed, because it is better to + close a slow connection than have a server process block. + +8.5 Establishing a server to client connection + + Upon connecting to an IRC server, a client is sent the MOTD (if + present) as well as the current user/server count (as per the LUSER + command). The server is also required to give an unambiguous message + to the client which states its name and version as well as any other + introductory messages which may be deemed appropriate. + + After dealing with this, the server must then send out the new user's + nickname and other information as supplied by itself (USER command) + and as the server could discover (from DNS/authentication servers). + The server must send this information out with NICK first followed by + USER. + +8.6 Establishing a server-server connection. + + The process of establishing of a server-to-server connection is + fraught with danger since there are many possible areas where + problems can occur - the least of which are race conditions. + + After a server has received a connection following by a PASS/SERVER + pair which were recognised as being valid, the server should then + reply with its own PASS/SERVER information for that connection as + well as all of the other state information it knows about as + described below. + + When the initiating server receives a PASS/SERVER pair, it too then + + checks that the server responding is authenticated properly before + accepting the connection to be that server. + +8.6.1 Server exchange of state information when connecting + + The order of state information being exchanged between servers is + essential. The required order is as follows: + + * all known other servers; + + * all known user information; + + * all known channel information. + + Information regarding servers is sent via extra SERVER messages, user + information with NICK/USER/MODE/JOIN messages and channels with MODE + messages. + + NOTE: channel topics are *NOT* exchanged here because the TOPIC + command overwrites any old topic information, so at best, the two + sides of the connection would exchange topics. + + By passing the state information about servers first, any collisions + with servers that already exist occur before nickname collisions due + to a second server introducing a particular nickname. Due to the IRC + network only being able to exist as an acyclic graph, it may be + possible that the network has already reconnected in another + location, the place where the collision occurs indicating where the + net needs to split. + +8.7 Terminating server-client connections + + When a client connection closes, a QUIT message is generated on + behalf of the client by the server to which the client connected. No + other message is to be generated or used. + +8.8 Terminating server-server connections + + If a server-server connection is closed, either via a remotely + generated SQUIT or 'natural' causes, the rest of the connected IRC + network must have its information updated with by the server which + detected the closure. The server then sends a list of SQUITs (one + for each server behind that connection) and a list of QUITs (again, + one for each client behind that connection). + +8.9 Tracking nickname changes + + All IRC servers are required to keep a history of recent nickname + changes. This is required to allow the server to have a chance of + keeping in touch of things when nick-change race conditions occur + with commands which manipulate them. Commands which must trace nick + changes are: + + * KILL (the nick being killed) + + * MODE (+/- o,v) + + * KICK (the nick being kicked) + + No other commands are to have nick changes checked for. + + In the above cases, the server is required to first check for the + existence of the nickname, then check its history to see who that + nick currently belongs to (if anyone!). This reduces the chances of + race conditions but they can still occur with the server ending up + affecting the wrong client. When performing a change trace for an + above command it is recommended that a time range be given and + entries which are too old ignored. + + For a reasonable history, a server should be able to keep previous + nickname for every client it knows about if they all decided to + change. This size is limited by other factors (such as memory, etc). + +8.10 Flood control of clients + + With a large network of interconnected IRC servers, it is quite easy + for any single client attached to the network to supply a continuous + stream of messages that result in not only flooding the network, but + also degrading the level of service provided to others. Rather than + require every 'victim' to be provide their own protection, flood + protection was written into the server and is applied to all clients + except services. The current algorithm is as follows: + + * check to see if client's `message timer' is less than + current time (set to be equal if it is); + + * read any data present from the client; + + * while the timer is less than ten seconds ahead of the current + time, parse any present messages and penalize the client by + 2 seconds for each message; + + which in essence means that the client may send 1 message every 2 + + seconds without being adversely affected. + +8.11 Non-blocking lookups + + In a real-time environment, it is essential that a server process do + as little waiting as possible so that all the clients are serviced + fairly. Obviously this requires non-blocking IO on all network + read/write operations. For normal server connections, this was not + difficult, but there are other support operations that may cause the + server to block (such as disk reads). Where possible, such activity + should be performed with a short timeout. + +8.11.1 Hostname (DNS) lookups + + Using the standard resolver libraries from Berkeley and others has + meant large delays in some cases where replies have timed out. To + avoid this, a separate set of DNS routines were written which were + setup for non-blocking IO operations and then polled from within the + main server IO loop. + +8.11.2 Username (Ident) lookups + + Although there are numerous ident libraries for use and inclusion + into other programs, these caused problems since they operated in a + synchronous manner and resulted in frequent delays. Again the + solution was to write a set of routines which would cooperate with + the rest of the server and work using non-blocking IO. + +8.12 Configuration File + + To provide a flexible way of setting up and running the server, it is + recommended that a configuration file be used which contains + instructions to the server on the following: + + * which hosts to accept client connections from; + + * which hosts to allow to connect as servers; + + * which hosts to connect to (both actively and + passively); + + * information about where the server is (university, + city/state, company are examples of this); + + * who is responsible for the server and an email address + at which they can be contacted; + + * hostnames and passwords for clients which wish to be given + + access to restricted operator commands. + + In specifying hostnames, both domain names and use of the 'dot' + notation (127.0.0.1) should both be accepted. It must be possible to + specify the password to be used/accepted for all outgoing and + incoming connections (although the only outgoing connections are + those to other servers). + + The above list is the minimum requirement for any server which wishes + to make a connection with another server. Other items which may be + of use are: + + * specifying which servers other server may introduce; + + * how deep a server branch is allowed to become; + + * hours during which clients may connect. + +8.12.1 Allowing clients to connect + + A server should use some sort of 'access control list' (either in the + configuration file or elsewhere) that is read at startup and used to + decide what hosts clients may use to connect to it. + + Both 'deny' and 'allow' should be implemented to provide the required + flexibility for host access control. + +8.12.2 Operators + + The granting of operator privileges to a disruptive person can have + dire consequences for the well-being of the IRC net in general due to + the powers given to them. Thus, the acquisition of such powers + should not be very easy. The current setup requires two 'passwords' + to be used although one of them is usually easy guessed. Storage of + oper passwords in configuration files is preferable to hard coding + them in and should be stored in a crypted format (ie using crypt(3) + from Unix) to prevent easy theft. + +8.12.3 Allowing servers to connect + + The interconnection of server is not a trivial matter: a bad + connection can have a large impact on the usefulness of IRC. Thus, + each server should have a list of servers to which it may connect and + which servers may connect to it. Under no circumstances should a + server allow an arbitrary host to connect as a server. In addition + to which servers may and may not connect, the configuration file + should also store the password and other characteristics of that + link. + +8.12.4 Administrivia + + To provide accurate and valid replies to the ADMIN command (see + section 4.3.7), the server should find the relevant details in the + configuration. + +8.13 Channel membership + + The current server allows any registered local user to join upto 10 + different channels. There is no limit imposed on non-local users so + that the server remains (reasonably) consistant with all others on a + channel membership basis + +9. Current problems + + There are a number of recognized problems with this protocol, all of + which hope to be solved sometime in the near future during its + rewrite. Currently, work is underway to find working solutions to + these problems. + +9.1 Scalability + + It is widely recognized that this protocol does not scale + sufficiently well when used in a large arena. The main problem comes + from the requirement that all servers know about all other servers + and users and that information regarding them be updated as soon as + it changes. It is also desirable to keep the number of servers low + so that the path length between any two points is kept minimal and + the spanning tree as strongly branched as possible. + +9.2 Labels + + The current IRC protocol has 3 types of labels: the nickname, the + channel name and the server name. Each of the three types has its + own domain and no duplicates are allowed inside that domain. + Currently, it is possible for users to pick the label for any of the + three, resulting in collisions. It is widely recognized that this + needs reworking, with a plan for unique names for channels and nicks + that don't collide being desirable as well as a solution allowing a + cyclic tree. + +9.2.1 Nicknames + + The idea of the nickname on IRC is very convenient for users to use + when talking to each other outside of a channel, but there is only a + finite nickname space and being what they are, its not uncommon for + several people to want to use the same nick. If a nickname is chosen + by two people using this protocol, either one will not succeed or + + both will removed by use of KILL (4.6.1). + +9.2.2 Channels + + The current channel layout requires that all servers know about all + channels, their inhabitants and properties. Besides not scaling + well, the issue of privacy is also a concern. A collision of + channels is treated as an inclusive event (both people who create the + new channel are considered to be members of it) rather than an + exclusive one such as used to solve nickname collisions. + +9.2.3 Servers + + Although the number of servers is usually small relative to the + number of users and channels, they two currently required to be known + globally, either each one separately or hidden behind a mask. + +9.3 Algorithms + + In some places within the server code, it has not been possible to + avoid N^2 algorithms such as checking the channel list of a set + of clients. + + In current server versions, there are no database consistency checks, + each server assumes that a neighbouring server is correct. This + opens the door to large problems if a connecting server is buggy or + otherwise tries to introduce contradictions to the existing net. + + Currently, because of the lack of unique internal and global labels, + there are a multitude of race conditions that exist. These race + conditions generally arise from the problem of it taking time for + messages to traverse and effect the IRC network. Even by changing to + unique labels, there are problems with channel-related commands being + disrupted. + +10. Current support and availability + + Mailing lists for IRC related discussion: + Future protocol: ircd-three-request@eff.org + General discussion: operlist-request@eff.org + + Software implemenations + cs.bu.edu:/irc + nic.funet.fi:/pub/irc + coombs.anu.edu.au:/pub/irc + + Newsgroup: alt.irc + +Security Considerations + + Security issues are discussed in sections 4.1, 4.1.1, 4.1.3, 5.5, and + 7. + +12. Authors' Addresses + + Jarkko Oikarinen + Tuirantie 17 as 9 + 90500 OULU + FINLAND + + Email: jto@tolsun.oulu.fi + + Darren Reed + 4 Pateman Street + Watsonia, Victoria 3087 + Australia + + Email: avalon@coombs.anu.edu.au diff --git a/doc/technical/rfc2812.txt b/doc/technical/rfc2812.txt new file mode 100644 index 0000000..3a77c66 --- /dev/null +++ b/doc/technical/rfc2812.txt @@ -0,0 +1,2916 @@ +$Id$ + +Network Working Group C. Kalt +Request for Comments: 2812 April 2000 +Updates: 1459 +Category: Informational + + Internet Relay Chat: Client Protocol + +Status of this Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2000). All Rights Reserved. + +IESG NOTE: + + The IRC protocol itself enables several possibilities of transferring + data between clients, and just like with other transfer mechanisms + like email, the receiver of the data has to be careful about how the + data is handled. For more information on security issues with the IRC + protocol, see for example http://www.irchelp.org/irchelp/security/. + +Abstract + + The IRC (Internet Relay Chat) protocol is for use with text based + conferencing; the simplest client being any socket program capable of + connecting to the server. + + This document defines the Client Protocol, and assumes that the + reader is familiar with the IRC Architecture [IRC-ARCH]. + +Table of Contents + + 1. Labels ..................................................... 3 + 1.1 Servers ................................................ 3 + 1.2 Clients ................................................ 3 + 1.2.1 Users ............................................. 4 + 1.2.1.1 Operators .................................... 4 + 1.2.2 Services .......................................... 4 + 1.3 Channels ............................................... 4 + 2. The IRC Client Specification ............................... 5 + 2.1 Overview ............................................... 5 + 2.2 Character codes ........................................ 5 + 2.3 Messages ............................................... 5 + + 2.3.1 Message format in Augmented BNF ................... 6 + 2.4 Numeric replies ........................................ 8 + 2.5 Wildcard expressions ................................... 9 + 3. Message Details ............................................ 9 + 3.1 Connection Registration ................................ 10 + 3.1.1 Password message .................................. 10 + 3.1.2 Nick message ...................................... 10 + 3.1.3 User message ...................................... 11 + 3.1.4 Oper message ...................................... 12 + 3.1.5 User mode message ................................. 12 + 3.1.6 Service message ................................... 13 + 3.1.7 Quit .............................................. 14 + 3.1.8 Squit ............................................. 15 + 3.2 Channel operations ..................................... 15 + 3.2.1 Join message ...................................... 16 + 3.2.2 Part message ...................................... 17 + 3.2.3 Channel mode message .............................. 18 + 3.2.4 Topic message ..................................... 19 + 3.2.5 Names message ..................................... 20 + 3.2.6 List message ...................................... 21 + 3.2.7 Invite message .................................... 21 + 3.2.8 Kick command ...................................... 22 + 3.3 Sending messages ....................................... 23 + 3.3.1 Private messages .................................. 23 + 3.3.2 Notice ............................................ 24 + 3.4 Server queries and commands ............................ 25 + 3.4.1 Motd message ...................................... 25 + 3.4.2 Lusers message .................................... 25 + 3.4.3 Version message ................................... 26 + 3.4.4 Stats message ..................................... 26 + 3.4.5 Links message ..................................... 27 + 3.4.6 Time message ...................................... 28 + 3.4.7 Connect message ................................... 28 + 3.4.8 Trace message ..................................... 29 + 3.4.9 Admin command ..................................... 30 + 3.4.10 Info command ...................................... 31 + 3.5 Service Query and Commands ............................. 31 + 3.5.1 Servlist message .................................. 31 + 3.5.2 Squery ............................................ 32 + 3.6 User based queries ..................................... 32 + 3.6.1 Who query ......................................... 32 + 3.6.2 Whois query ....................................... 33 + 3.6.3 Whowas ............................................ 34 + 3.7 Miscellaneous messages ................................. 34 + 3.7.1 Kill message ...................................... 35 + 3.7.2 Ping message ...................................... 36 + 3.7.3 Pong message ...................................... 37 + 3.7.4 Error ............................................. 37 + + 4. Optional features .......................................... 38 + 4.1 Away ................................................... 38 + 4.2 Rehash message ......................................... 39 + 4.3 Die message ............................................ 39 + 4.4 Restart message ........................................ 40 + 4.5 Summon message ......................................... 40 + 4.6 Users .................................................. 41 + 4.7 Operwall message ....................................... 41 + 4.8 Userhost message ....................................... 42 + 4.9 Ison message ........................................... 42 + 5. Replies .................................................... 43 + 5.1 Command responses ...................................... 43 + 5.2 Error Replies .......................................... 53 + 5.3 Reserved numerics ...................................... 59 + 6. Current implementations .................................... 60 + 7. Current problems ........................................... 60 + 7.1 Nicknames .............................................. 60 + 7.2 Limitation of wildcards ................................ 61 + 7.3 Security considerations ................................ 61 + 8. Current support and availability ........................... 61 + 9. Acknowledgements ........................................... 61 + 10. References ................................................ 62 + 11. Author's Address .......................................... 62 + 12. Full Copyright Statement .................................. 63 + +1. Labels + + This section defines the identifiers used for the various components + of the IRC protocol. + +1.1 Servers + + Servers are uniquely identified by their name, which has a maximum + length of sixty three (63) characters. See the protocol grammar + rules (section 2.3.1) for what may and may not be used in a server + name. + +1.2 Clients + + For each client all servers MUST have the following information: a + netwide unique identifier (whose format depends on the type of + client) and the server which introduced the client. + +1.2.1 Users + + Each user is distinguished from other users by a unique nickname + having a maximum length of nine (9) characters. See the protocol + grammar rules (section 2.3.1) for what may and may not be used in a + nickname. + + While the maximum length is limited to nine characters, clients + SHOULD accept longer strings as they may become used in future + evolutions of the protocol. + +1.2.1.1 Operators + + To allow a reasonable amount of order to be kept within the IRC + network, a special class of users (operators) is allowed to perform + general maintenance functions on the network. Although the powers + granted to an operator can be considered as 'dangerous', they are + nonetheless often necessary. Operators SHOULD be able to perform + basic network tasks such as disconnecting and reconnecting servers as + needed. In recognition of this need, the protocol discussed herein + provides for operators only to be able to perform such functions. + See sections 3.1.8 (SQUIT) and 3.4.7 (CONNECT). + + A more controversial power of operators is the ability to remove a + user from the connected network by 'force', i.e., operators are able + to close the connection between any client and server. The + justification for this is very delicate since its abuse is both + destructive and annoying, and its benefits close to inexistent. For + further details on this type of action, see section 3.7.1 (KILL). + +1.2.2 Services + + Each service is distinguished from other services by a service name + composed of a nickname and a server name. As for users, the nickname + has a maximum length of nine (9) characters. See the protocol + grammar rules (section 2.3.1) for what may and may not be used in a + nickname. + +1.3 Channels + + Channels names are strings (beginning with a '&', '#', '+' or '!' + character) of length up to fifty (50) characters. Apart from the + requirement that the first character is either '&', '#', '+' or '!', + the only restriction on a channel name is that it SHALL NOT contain + any spaces (' '), a control G (^G or ASCII 7), a comma (','). Space + is used as parameter separator and command is used as a list item + separator by the protocol). A colon (':') can also be used as a + delimiter for the channel mask. Channel names are case insensitive. + + See the protocol grammar rules (section 2.3.1) for the exact syntax + of a channel name. + + Each prefix characterizes a different channel type. The definition + of the channel types is not relevant to the client-server protocol + and thus it is beyond the scope of this document. More details can + be found in "Internet Relay Chat: Channel Management" [IRC-CHAN]. + +2. The IRC Client Specification + +2.1 Overview + + The protocol as described herein is for use only with client to + server connections when the client registers as a user. + +2.2 Character codes + + No specific character set is specified. The protocol is based on a + set of codes which are composed of eight (8) bits, making up an + octet. Each message may be composed of any number of these octets; + however, some octet values are used for control codes, which act as + message delimiters. + + Regardless of being an 8-bit protocol, the delimiters and keywords + are such that protocol is mostly usable from US-ASCII terminal and a + telnet connection. + + Because of IRC's Scandinavian origin, the characters {}|^ are + considered to be the lower case equivalents of the characters []\~, + respectively. This is a critical issue when determining the + equivalence of two nicknames or channel names. + +2.3 Messages + + Servers and clients send each other messages, which may or may not + generate a reply. If the message contains a valid command, as + described in later sections, the client should expect a reply as + specified but it is not advised to wait forever for the reply; client + to server and server to server communication is essentially + asynchronous by nature. + + Each IRC message may consist of up to three main parts: the prefix + (OPTIONAL), the command, and the command parameters (maximum of + fifteen (15)). The prefix, command, and all parameters are separated + by one ASCII space character (0x20) each. + + The presence of a prefix is indicated with a single leading ASCII + colon character (':', 0x3b), which MUST be the first character of the + message itself. There MUST be NO gap (whitespace) between the colon + and the prefix. The prefix is used by servers to indicate the true + origin of the message. If the prefix is missing from the message, it + is assumed to have originated from the connection from which it was + received from. Clients SHOULD NOT use a prefix when sending a + message; if they use one, the only valid prefix is the registered + nickname associated with the client. + + The command MUST either be a valid IRC command or a three (3) digit + number represented in ASCII text. + + IRC messages are always lines of characters terminated with a CR-LF + (Carriage Return - Line Feed) pair, and these messages SHALL NOT + exceed 512 characters in length, counting all characters including + the trailing CR-LF. Thus, there are 510 characters maximum allowed + for the command and its parameters. There is no provision for + continuation of message lines. See section 6 for more details about + current implementations. + +2.3.1 Message format in Augmented BNF + + The protocol messages must be extracted from the contiguous stream of + octets. The current solution is to designate two characters, CR and + LF, as message separators. Empty messages are silently ignored, + which permits use of the sequence CR-LF between messages without + extra problems. + + The extracted message is parsed into the components <prefix>, + <command> and list of parameters (<params>). + + The Augmented BNF representation for this is: + + message = [ ":" prefix SPACE ] command [ params ] crlf + prefix = servername / ( nickname [ [ "!" user ] "@" host ] ) + command = 1*letter / 3digit + params = *14( SPACE middle ) [ SPACE ":" trailing ] + =/ 14( SPACE middle ) [ SPACE [ ":" ] trailing ] + + nospcrlfcl = %x01-09 / %x0B-0C / %x0E-1F / %x21-39 / %x3B-FF + ; any octet except NUL, CR, LF, " " and ":" + middle = nospcrlfcl *( ":" / nospcrlfcl ) + trailing = *( ":" / " " / nospcrlfcl ) + + SPACE = %x20 ; space character + crlf = %x0D %x0A ; "carriage return" "linefeed" + + NOTES: + 1) After extracting the parameter list, all parameters are equal + whether matched by <middle> or <trailing>. <trailing> is just a + syntactic trick to allow SPACE within the parameter. + + 2) The NUL (%x00) character is not special in message framing, and + basically could end up inside a parameter, but it would cause + extra complexities in normal C string handling. Therefore, NUL + is not allowed within messages. + + Most protocol messages specify additional semantics and syntax for + the extracted parameter strings dictated by their position in the + list. For example, many server commands will assume that the first + parameter after the command is the list of targets, which can be + described with: + + target = nickname / server + msgtarget = msgto *( "," msgto ) + msgto = channel / ( user [ "%" host ] "@" servername ) + msgto =/ ( user "%" host ) / targetmask + msgto =/ nickname / ( nickname "!" user "@" host ) + channel = ( "#" / "+" / ( "!" channelid ) / "&" ) chanstring + [ ":" chanstring ] + servername = hostname + host = hostname / hostaddr + hostname = shortname *( "." shortname ) + shortname = ( letter / digit ) *( letter / digit / "-" ) + *( letter / digit ) + ; as specified in RFC 1123 [HNAME] + hostaddr = ip4addr / ip6addr + ip4addr = 1*3digit "." 1*3digit "." 1*3digit "." 1*3digit + ip6addr = 1*hexdigit 7( ":" 1*hexdigit ) + ip6addr =/ "0:0:0:0:0:" ( "0" / "FFFF" ) ":" ip4addr + nickname = ( letter / special ) *8( letter / digit / special / "-" ) + targetmask = ( "$" / "#" ) mask + ; see details on allowed masks in section 3.3.1 + chanstring = %x01-07 / %x08-09 / %x0B-0C / %x0E-1F / %x21-2B + chanstring =/ %x2D-39 / %x3B-FF + ; any octet except NUL, BELL, CR, LF, " ", "," and ":" + channelid = 5( %x41-5A / digit ) ; 5( A-Z / 0-9 ) + + Other parameter syntaxes are: + + user = 1*( %x01-09 / %x0B-0C / %x0E-1F / %x21-3F / %x41-FF ) + ; any octet except NUL, CR, LF, " " and "@" + key = 1*23( %x01-05 / %x07-08 / %x0C / %x0E-1F / %x21-7F ) + ; any 7-bit US_ASCII character, + ; except NUL, CR, LF, FF, h/v TABs, and " " + letter = %x41-5A / %x61-7A ; A-Z / a-z + digit = %x30-39 ; 0-9 + hexdigit = digit / "A" / "B" / "C" / "D" / "E" / "F" + special = %x5B-60 / %x7B-7D + ; "[", "]", "\", "`", "_", "^", "{", "|", "}" + + NOTES: + 1) The <hostaddr> syntax is given here for the sole purpose of + indicating the format to follow for IP addresses. This + reflects the fact that the only available implementations of + this protocol uses TCP/IP as underlying network protocol but is + not meant to prevent other protocols to be used. + + 2) <hostname> has a maximum length of 63 characters. This is a + limitation of the protocol as internet hostnames (in + particular) can be longer. Such restriction is necessary + because IRC messages are limited to 512 characters in length. + Clients connecting from a host which name is longer than 63 + characters are registered using the host (numeric) address + instead of the host name. + + 3) Some parameters used in the following sections of this + documents are not defined here as there is nothing specific + about them besides the name that is used for convenience. + These parameters follow the general syntax defined for + <params>. + +2.4 Numeric replies + + Most of the messages sent to the server generate a reply of some + sort. The most common reply is the numeric reply, used for both + errors and normal replies. The numeric reply MUST be sent as one + message consisting of the sender prefix, the three-digit numeric, and + the target of the reply. A numeric reply is not allowed to originate + from a client. In all other respects, a numeric reply is just like a + normal message, except that the keyword is made up of 3 numeric + digits rather than a string of letters. A list of different replies + is supplied in section 5 (Replies). + +2.5 Wildcard expressions + + When wildcards are allowed in a string, it is referred as a "mask". + + For string matching purposes, the protocol allows the use of two + special characters: '?' (%x3F) to match one and only one character, + and '*' (%x2A) to match any number of any characters. These two + characters can be escaped using the character '\' (%x5C). + + The Augmented BNF syntax for this is: + + mask = *( nowild / noesc wildone / noesc wildmany ) + wildone = %x3F + wildmany = %x2A + nowild = %x01-29 / %x2B-3E / %x40-FF + ; any octet except NUL, "*", "?" + noesc = %x01-5B / %x5D-FF + ; any octet except NUL and "\" + matchone = %x01-FF + ; matches wildone + matchmany = *matchone + ; matches wildmany + + Examples: + + a?c ; Matches any string of 3 characters in length starting + with "a" and ending with "c" + + a*c ; Matches any string of at least 2 characters in length + starting with "a" and ending with "c" + +3. Message Details + + On the following pages there are descriptions of each message + recognized by the IRC server and client. All commands described in + this section MUST be implemented by any server for this protocol. + + Where the reply ERR_NOSUCHSERVER is returned, it means that the + target of the message could not be found. The server MUST NOT send + any other replies after this error for that command. + + The server to which a client is connected is required to parse the + complete message, and return any appropriate errors. + + If multiple parameters is presented, then each MUST be checked for + validity and appropriate responses MUST be sent back to the client. + In the case of incorrect messages which use parameter lists with + comma as an item separator, a reply MUST be sent for each item. + +3.1 Connection Registration + + The commands described here are used to register a connection with an + IRC server as a user as well as to correctly disconnect. + + A "PASS" command is not required for a client connection to be + registered, but it MUST precede the latter of the NICK/USER + combination (for a user connection) or the SERVICE command (for a + service connection). The RECOMMENDED order for a client to register + is as follows: + + 1. Pass message + 2. Nick message 2. Service message + 3. User message + + Upon success, the client will receive an RPL_WELCOME (for users) or + RPL_YOURESERVICE (for services) message indicating that the + connection is now registered and known the to the entire IRC network. + The reply message MUST contain the full client identifier upon which + it was registered. + +3.1.1 Password message + + Command: PASS + Parameters: <password> + + The PASS command is used to set a 'connection password'. The + optional password can and MUST be set before any attempt to register + the connection is made. Currently this requires that user send a + PASS command before sending the NICK/USER combination. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_ALREADYREGISTRED + + Example: + + PASS secretpasswordhere + +3.1.2 Nick message + + Command: NICK + Parameters: <nickname> + + NICK command is used to give user a nickname or change the existing + one. + + Numeric Replies: + + ERR_NONICKNAMEGIVEN ERR_ERRONEUSNICKNAME + ERR_NICKNAMEINUSE ERR_NICKCOLLISION + ERR_UNAVAILRESOURCE ERR_RESTRICTED + + Examples: + + NICK Wiz ; Introducing new nick "Wiz" if session is + still unregistered, or user changing his + nickname to "Wiz" + + :WiZ!jto@tolsun.oulu.fi NICK Kilroy + ; Server telling that WiZ changed his + nickname to Kilroy. + +3.1.3 User message + + Command: USER + Parameters: <user> <mode> <unused> <realname> + + The USER command is used at the beginning of connection to specify + the username, hostname and realname of a new user. + + The <mode> parameter should be a numeric, and can be used to + automatically set user modes when registering with the server. This + parameter is a bitmask, with only 2 bits having any signification: if + the bit 2 is set, the user mode 'w' will be set and if the bit 3 is + set, the user mode 'i' will be set. (See Section 3.1.5 "User + Modes"). + + The <realname> may contain space characters. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_ALREADYREGISTRED + + Example: + + USER guest 0 * :Ronnie Reagan ; User registering themselves with a + username of "guest" and real name + "Ronnie Reagan". + + USER guest 8 * :Ronnie Reagan ; User registering themselves with a + username of "guest" and real name + "Ronnie Reagan", and asking to be set + invisible. + +3.1.4 Oper message + + Command: OPER + Parameters: <name> <password> + + A normal user uses the OPER command to obtain operator privileges. + The combination of <name> and <password> are REQUIRED to gain + Operator privileges. Upon success, the user will receive a MODE + message (see section 3.1.5) indicating the new user modes. + + Numeric Replies: + + ERR_NEEDMOREPARAMS RPL_YOUREOPER + ERR_NOOPERHOST ERR_PASSWDMISMATCH + + Example: + + OPER foo bar ; Attempt to register as an operator + using a username of "foo" and "bar" + as the password. + +3.1.5 User mode message + + Command: MODE + Parameters: <nickname> + *( ( "+" / "-" ) *( "i" / "w" / "o" / "O" / "r" ) ) + + The user MODE's are typically changes which affect either how the + client is seen by others or what 'extra' messages the client is sent. + + A user MODE command MUST only be accepted if both the sender of the + message and the nickname given as a parameter are both the same. If + no other parameter is given, then the server will return the current + settings for the nick. + + The available modes are as follows: + + a - user is flagged as away; + i - marks a users as invisible; + w - user receives wallops; + r - restricted user connection; + o - operator flag; + O - local operator flag; + s - marks a user for receipt of server notices. + + Additional modes may be available later on. + + The flag 'a' SHALL NOT be toggled by the user using the MODE command, + instead use of the AWAY command is REQUIRED. + + If a user attempts to make themselves an operator using the "+o" or + "+O" flag, the attempt SHOULD be ignored as users could bypass the + authentication mechanisms of the OPER command. There is no + restriction, however, on anyone `deopping' themselves (using "-o" or + "-O"). + + On the other hand, if a user attempts to make themselves unrestricted + using the "-r" flag, the attempt SHOULD be ignored. There is no + restriction, however, on anyone `deopping' themselves (using "+r"). + This flag is typically set by the server upon connection for + administrative reasons. While the restrictions imposed are left up + to the implementation, it is typical that a restricted user not be + allowed to change nicknames, nor make use of the channel operator + status on channels. + + The flag 's' is obsolete but MAY still be used. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_USERSDONTMATCH + ERR_UMODEUNKNOWNFLAG RPL_UMODEIS + + Examples: + + MODE WiZ -w ; Command by WiZ to turn off + reception of WALLOPS messages. + + MODE Angel +i ; Command from Angel to make herself + invisible. + + MODE WiZ -o ; WiZ 'deopping' (removing operator + status). + +3.1.6 Service message + + Command: SERVICE + Parameters: <nickname> <reserved> <distribution> <type> + <reserved> <info> + + The SERVICE command to register a new service. Command parameters + specify the service nickname, distribution, type and info of a new + service. + + The <distribution> parameter is used to specify the visibility of a + service. The service may only be known to servers which have a name + matching the distribution. For a matching server to have knowledge + of the service, the network path between that server and the server + on which the service is connected MUST be composed of servers which + names all match the mask. + + The <type> parameter is currently reserved for future usage. + + Numeric Replies: + + ERR_ALREADYREGISTRED ERR_NEEDMOREPARAMS + ERR_ERRONEUSNICKNAME + RPL_YOURESERVICE RPL_YOURHOST + RPL_MYINFO + + Example: + + SERVICE dict * *.fr 0 0 :French Dictionary ; Service registering + itself with a name of "dict". This + service will only be available on + servers which name matches "*.fr". + +3.1.7 Quit + + Command: QUIT + Parameters: [ <Quit Message> ] + + A client session is terminated with a quit message. The server + acknowledges this by sending an ERROR message to the client. + + Numeric Replies: + + None. + + Example: + + QUIT :Gone to have lunch ; Preferred message format. + + :syrk!kalt@millennium.stealth.net QUIT :Gone to have lunch ; User + syrk has quit IRC to have lunch. + +3.1.8 Squit + + Command: SQUIT + Parameters: <server> <comment> + + The SQUIT command is available only to operators. It is used to + disconnect server links. Also servers can generate SQUIT messages on + error conditions. A SQUIT message may also target a remote server + connection. In this case, the SQUIT message will simply be sent to + the remote server without affecting the servers in between the + operator and the remote server. + + The <comment> SHOULD be supplied by all operators who execute a SQUIT + for a remote server. The server ordered to disconnect its peer + generates a WALLOPS message with <comment> included, so that other + users may be aware of the reason of this action. + + Numeric replies: + + ERR_NOPRIVILEGES ERR_NOSUCHSERVER + ERR_NEEDMOREPARAMS + + Examples: + + SQUIT tolsun.oulu.fi :Bad Link ? ; Command to uplink of the server + tolson.oulu.fi to terminate its + connection with comment "Bad Link". + + :Trillian SQUIT cm22.eng.umd.edu :Server out of control ; Command + from Trillian from to disconnect + "cm22.eng.umd.edu" from the net with + comment "Server out of control". + +3.2 Channel operations + + This group of messages is concerned with manipulating channels, their + properties (channel modes), and their contents (typically users). + For this reason, these messages SHALL NOT be made available to + services. + + All of these messages are requests which will or will not be granted + by the server. The server MUST send a reply informing the user + whether the request was granted, denied or generated an error. When + the server grants the request, the message is typically sent back + (eventually reformatted) to the user with the prefix set to the user + itself. + + The rules governing how channels are managed are enforced by the + servers. These rules are beyond the scope of this document. More + details are found in "Internet Relay Chat: Channel Management" [IRC- + CHAN]. + +3.2.1 Join message + + Command: JOIN + Parameters: ( <channel> *( "," <channel> ) [ <key> *( "," <key> ) ] ) + / "0" + + The JOIN command is used by a user to request to start listening to + the specific channel. Servers MUST be able to parse arguments in the + form of a list of target, but SHOULD NOT use lists when sending JOIN + messages to clients. + + Once a user has joined a channel, he receives information about + all commands his server receives affecting the channel. This + includes JOIN, MODE, KICK, PART, QUIT and of course PRIVMSG/NOTICE. + This allows channel members to keep track of the other channel + members, as well as channel modes. + + If a JOIN is successful, the user receives a JOIN message as + confirmation and is then sent the channel's topic (using RPL_TOPIC) and + the list of users who are on the channel (using RPL_NAMREPLY), which + MUST include the user joining. + + Note that this message accepts a special argument ("0"), which is + a special request to leave all channels the user is currently a member + of. The server will process this message as if the user had sent + a PART command (See Section 3.2.2) for each channel he is a member + of. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_BANNEDFROMCHAN + ERR_INVITEONLYCHAN ERR_BADCHANNELKEY + ERR_CHANNELISFULL ERR_BADCHANMASK + ERR_NOSUCHCHANNEL ERR_TOOMANYCHANNELS + ERR_TOOMANYTARGETS ERR_UNAVAILRESOURCE + RPL_TOPIC + + Examples: + + JOIN #foobar ; Command to join channel #foobar. + + JOIN &foo fubar ; Command to join channel &foo using + key "fubar". + + JOIN #foo,&bar fubar ; Command to join channel #foo using + key "fubar" and &bar using no key. + + JOIN #foo,#bar fubar,foobar ; Command to join channel #foo using + key "fubar", and channel #bar using + key "foobar". + + JOIN #foo,#bar ; Command to join channels #foo and + #bar. + + JOIN 0 ; Leave all currently joined + channels. + + :WiZ!jto@tolsun.oulu.fi JOIN #Twilight_zone ; JOIN message from WiZ + on channel #Twilight_zone + +3.2.2 Part message + + Command: PART + Parameters: <channel> *( "," <channel> ) [ <Part Message> ] + + The PART command causes the user sending the message to be removed + from the list of active members for all given channels listed in the + parameter string. If a "Part Message" is given, this will be sent + instead of the default message, the nickname. This request is always + granted by the server. + + Servers MUST be able to parse arguments in the form of a list of + target, but SHOULD NOT use lists when sending PART messages to + clients. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_NOSUCHCHANNEL + ERR_NOTONCHANNEL + + Examples: + + PART #twilight_zone ; Command to leave channel + "#twilight_zone" + + PART #oz-ops,&group5 ; Command to leave both channels + "&group5" and "#oz-ops". + + :WiZ!jto@tolsun.oulu.fi PART #playzone :I lost + ; User WiZ leaving channel + "#playzone" with the message "I + lost". + +3.2.3 Channel mode message + + Command: MODE + Parameters: <channel> *( ( "-" / "+" ) *<modes> *<modeparams> ) + + The MODE command is provided so that users may query and change the + characteristics of a channel. For more details on available modes + and their uses, see "Internet Relay Chat: Channel Management" [IRC- + CHAN]. Note that there is a maximum limit of three (3) changes per + command for modes that take a parameter. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_KEYSET + ERR_NOCHANMODES ERR_CHANOPRIVSNEEDED + ERR_USERNOTINCHANNEL ERR_UNKNOWNMODE + RPL_CHANNELMODEIS + RPL_BANLIST RPL_ENDOFBANLIST + RPL_EXCEPTLIST RPL_ENDOFEXCEPTLIST + RPL_INVITELIST RPL_ENDOFINVITELIST + RPL_UNIQOPIS + + The following examples are given to help understanding the syntax of + the MODE command, but refer to modes defined in "Internet Relay Chat: + Channel Management" [IRC-CHAN]. + + Examples: + + MODE #Finnish +imI *!*@*.fi ; Command to make #Finnish channel + moderated and 'invite-only' with user + with a hostname matching *.fi + automatically invited. + + MODE #Finnish +o Kilroy ; Command to give 'chanop' privileges + to Kilroy on channel #Finnish. + + MODE #Finnish +v Wiz ; Command to allow WiZ to speak on + #Finnish. + + MODE #Fins -s ; Command to remove 'secret' flag + from channel #Fins. + + MODE #42 +k oulu ; Command to set the channel key to + "oulu". + + MODE #42 -k oulu ; Command to remove the "oulu" + channel key on channel "#42". + + MODE #eu-opers +l 10 ; Command to set the limit for the + number of users on channel + "#eu-opers" to 10. + + :WiZ!jto@tolsun.oulu.fi MODE #eu-opers -l + ; User "WiZ" removing the limit for + the number of users on channel "#eu- + opers". + + MODE &oulu +b ; Command to list ban masks set for + the channel "&oulu". + + MODE &oulu +b *!*@* ; Command to prevent all users from + joining. + + MODE &oulu +b *!*@*.edu +e *!*@*.bu.edu + ; Command to prevent any user from a + hostname matching *.edu from joining, + except if matching *.bu.edu + + MODE #bu +be *!*@*.edu *!*@*.bu.edu + ; Comment to prevent any user from a + hostname matching *.edu from joining, + except if matching *.bu.edu + + MODE #meditation e ; Command to list exception masks set + for the channel "#meditation". + + MODE #meditation I ; Command to list invitations masks + set for the channel "#meditation". + + MODE !12345ircd O ; Command to ask who the channel + creator for "!12345ircd" is + +3.2.4 Topic message + + Command: TOPIC + Parameters: <channel> [ <topic> ] + + The TOPIC command is used to change or view the topic of a channel. + The topic for channel <channel> is returned if there is no <topic> + given. If the <topic> parameter is present, the topic for that + channel will be changed, if this action is allowed for the user + requesting it. If the <topic> parameter is an empty string, the + topic for that channel will be removed. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_NOTONCHANNEL + RPL_NOTOPIC RPL_TOPIC + ERR_CHANOPRIVSNEEDED ERR_NOCHANMODES + + Examples: + + :WiZ!jto@tolsun.oulu.fi TOPIC #test :New topic ; User Wiz setting the + topic. + + TOPIC #test :another topic ; Command to set the topic on #test + to "another topic". + + TOPIC #test : ; Command to clear the topic on + #test. + + TOPIC #test ; Command to check the topic for + #test. + +3.2.5 Names message + + Command: NAMES + Parameters: [ <channel> *( "," <channel> ) [ <target> ] ] + + By using the NAMES command, a user can list all nicknames that are + visible to him. For more details on what is visible and what is not, + see "Internet Relay Chat: Channel Management" [IRC-CHAN]. The + <channel> parameter specifies which channel(s) to return information + about. There is no error reply for bad channel names. + + If no <channel> parameter is given, a list of all channels and their + occupants is returned. At the end of this list, a list of users who + are visible but either not on any channel or not on a visible channel + are listed as being on `channel' "*". + + If the <target> parameter is specified, the request is forwarded to + that server which will generate the reply. + + Wildcards are allowed in the <target> parameter. + + Numerics: + + ERR_TOOMANYMATCHES ERR_NOSUCHSERVER + RPL_NAMREPLY RPL_ENDOFNAMES + + Examples: + + NAMES #twilight_zone,#42 ; Command to list visible users on + #twilight_zone and #42 + + NAMES ; Command to list all visible + channels and users + +3.2.6 List message + + Command: LIST + Parameters: [ <channel> *( "," <channel> ) [ <target> ] ] + + The list command is used to list channels and their topics. If the + <channel> parameter is used, only the status of that channel is + displayed. + + If the <target> parameter is specified, the request is forwarded to + that server which will generate the reply. + + Wildcards are allowed in the <target> parameter. + + Numeric Replies: + + ERR_TOOMANYMATCHES ERR_NOSUCHSERVER + RPL_LIST RPL_LISTEND + + Examples: + + LIST ; Command to list all channels. + + LIST #twilight_zone,#42 ; Command to list channels + #twilight_zone and #42 + +3.2.7 Invite message + + Command: INVITE + Parameters: <nickname> <channel> + + The INVITE command is used to invite a user to a channel. The + parameter <nickname> is the nickname of the person to be invited to + the target channel <channel>. There is no requirement that the + channel the target user is being invited to must exist or be a valid + channel. However, if the channel exists, only members of the channel + are allowed to invite other users. When the channel has invite-only + flag set, only channel operators may issue INVITE command. + + Only the user inviting and the user being invited will receive + notification of the invitation. Other channel members are not + notified. (This is unlike the MODE changes, and is occasionally the + source of trouble for users.) + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_NOSUCHNICK + ERR_NOTONCHANNEL ERR_USERONCHANNEL + ERR_CHANOPRIVSNEEDED + RPL_INVITING RPL_AWAY + + Examples: + + :Angel!wings@irc.org INVITE Wiz #Dust + + ; Message to WiZ when he has been + invited by user Angel to channel + #Dust + + INVITE Wiz #Twilight_Zone ; Command to invite WiZ to + #Twilight_zone + +3.2.8 Kick command + + Command: KICK + Parameters: <channel> *( "," <channel> ) <user> *( "," <user> ) + [<comment>] + + The KICK command can be used to request the forced removal of a user + from a channel. It causes the <user> to PART from the <channel> by + force. For the message to be syntactically correct, there MUST be + either one channel parameter and multiple user parameter, or as many + channel parameters as there are user parameters. If a "comment" is + given, this will be sent instead of the default message, the nickname + of the user issuing the KICK. + + The server MUST NOT send KICK messages with multiple channels or + users to clients. This is necessarily to maintain backward + compatibility with old client software. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_NOSUCHCHANNEL + ERR_BADCHANMASK ERR_CHANOPRIVSNEEDED + ERR_USERNOTINCHANNEL ERR_NOTONCHANNEL + + Examples: + + KICK &Melbourne Matthew ; Command to kick Matthew from + &Melbourne + + KICK #Finnish John :Speaking English + ; Command to kick John from #Finnish + using "Speaking English" as the + reason (comment). + + :WiZ!jto@tolsun.oulu.fi KICK #Finnish John + ; KICK message on channel #Finnish + from WiZ to remove John from channel + +3.3 Sending messages + + The main purpose of the IRC protocol is to provide a base for clients + to communicate with each other. PRIVMSG, NOTICE and SQUERY + (described in Section 3.5 on Service Query and Commands) are the only + messages available which actually perform delivery of a text message + from one client to another - the rest just make it possible and try + to ensure it happens in a reliable and structured manner. + +3.3.1 Private messages + + Command: PRIVMSG + Parameters: <msgtarget> <text to be sent> + + PRIVMSG is used to send private messages between users, as well as to + send messages to channels. <msgtarget> is usually the nickname of + the recipient of the message, or a channel name. + + The <msgtarget> parameter may also be a host mask (#<mask>) or server + mask ($<mask>). In both cases the server will only send the PRIVMSG + to those who have a server or host matching the mask. The mask MUST + have at least 1 (one) "." in it and no wildcards following the last + ".". This requirement exists to prevent people sending messages to + "#*" or "$*", which would broadcast to all users. Wildcards are the + '*' and '?' characters. This extension to the PRIVMSG command is + only available to operators. + + Numeric Replies: + + ERR_NORECIPIENT ERR_NOTEXTTOSEND + ERR_CANNOTSENDTOCHAN ERR_NOTOPLEVEL + ERR_WILDTOPLEVEL ERR_TOOMANYTARGETS + ERR_NOSUCHNICK + RPL_AWAY + + Examples: + + :Angel!wings@irc.org PRIVMSG Wiz :Are you receiving this message ? + ; Message from Angel to Wiz. + + PRIVMSG Angel :yes I'm receiving it ! + ; Command to send a message to Angel. + + PRIVMSG jto@tolsun.oulu.fi :Hello ! + ; Command to send a message to a user + on server tolsun.oulu.fi with + username of "jto". + + PRIVMSG kalt%millennium.stealth.net@irc.stealth.net :Are you a frog? + ; Message to a user on server + irc.stealth.net with username of + "kalt", and connected from the host + millennium.stealth.net. + + PRIVMSG kalt%millennium.stealth.net :Do you like cheese? + ; Message to a user on the local + server with username of "kalt", and + connected from the host + millennium.stealth.net. + + PRIVMSG Wiz!jto@tolsun.oulu.fi :Hello ! + ; Message to the user with nickname + Wiz who is connected from the host + tolsun.oulu.fi and has the username + "jto". + + PRIVMSG $*.fi :Server tolsun.oulu.fi rebooting. + ; Message to everyone on a server + which has a name matching *.fi. + + PRIVMSG #*.edu :NSFNet is undergoing work, expect interruptions + ; Message to all users who come from + a host which has a name matching + *.edu. + +3.3.2 Notice + + Command: NOTICE + Parameters: <msgtarget> <text> + + The NOTICE command is used similarly to PRIVMSG. The difference + between NOTICE and PRIVMSG is that automatic replies MUST NEVER be + sent in response to a NOTICE message. This rule applies to servers + + too - they MUST NOT send any error reply back to the client on + receipt of a notice. The object of this rule is to avoid loops + between clients automatically sending something in response to + something it received. + + This command is available to services as well as users. + + This is typically used by services, and automatons (clients with + either an AI or other interactive program controlling their actions). + + See PRIVMSG for more details on replies and examples. + +3.4 Server queries and commands + + The server query group of commands has been designed to return + information about any server which is connected to the network. + + In these queries, where a parameter appears as <target>, wildcard + masks are usually valid. For each parameter, however, only one query + and set of replies is to be generated. In most cases, if a nickname + is given, it will mean the server to which the user is connected. + + These messages typically have little value for services, it is + therefore RECOMMENDED to forbid services from using them. + +3.4.1 Motd message + + Command: MOTD + Parameters: [ <target> ] + + The MOTD command is used to get the "Message Of The Day" of the given + server, or current server if <target> is omitted. + + Wildcards are allowed in the <target> parameter. + + Numeric Replies: + RPL_MOTDSTART RPL_MOTD + RPL_ENDOFMOTD ERR_NOMOTD + +3.4.2 Lusers message + + Command: LUSERS + Parameters: [ <mask> [ <target> ] ] + + The LUSERS command is used to get statistics about the size of the + IRC network. If no parameter is given, the reply will be about the + whole net. If a <mask> is specified, then the reply will only + + concern the part of the network formed by the servers matching the + mask. Finally, if the <target> parameter is specified, the request + is forwarded to that server which will generate the reply. + + Wildcards are allowed in the <target> parameter. + + Numeric Replies: + + RPL_LUSERCLIENT RPL_LUSEROP + RPL_LUSERUNKOWN RPL_LUSERCHANNELS + RPL_LUSERME ERR_NOSUCHSERVER + +3.4.3 Version message + + Command: VERSION + Parameters: [ <target> ] + + The VERSION command is used to query the version of the server + program. An optional parameter <target> is used to query the version + of the server program which a client is not directly connected to. + + Wildcards are allowed in the <target> parameter. + + Numeric Replies: + + ERR_NOSUCHSERVER RPL_VERSION + + Examples: + + VERSION tolsun.oulu.fi ; Command to check the version of + server "tolsun.oulu.fi". + +3.4.4 Stats message + + Command: STATS + Parameters: [ <query> [ <target> ] ] + + The stats command is used to query statistics of certain server. If + <query> parameter is omitted, only the end of stats reply is sent + back. + + A query may be given for any single letter which is only checked by + the destination server and is otherwise passed on by intermediate + servers, ignored and unaltered. + + Wildcards are allowed in the <target> parameter. + + Except for the ones below, the list of valid queries is + implementation dependent. The standard queries below SHOULD be + supported by the server: + + l - returns a list of the server's connections, showing how + long each connection has been established and the + traffic over that connection in Kbytes and messages for + each direction; + m - returns the usage count for each of commands supported + by the server; commands for which the usage count is + zero MAY be omitted; + o - returns a list of configured privileged users, + operators; + u - returns a string showing how long the server has been + up. + + It is also RECOMMENDED that client and server access configuration be + published this way. + + Numeric Replies: + + ERR_NOSUCHSERVER + RPL_STATSLINKINFO RPL_STATSUPTIME + RPL_STATSCOMMANDS RPL_STATSOLINE + RPL_ENDOFSTATS + + Examples: + + STATS m ; Command to check the command usage + for the server you are connected to + +3.4.5 Links message + + Command: LINKS + Parameters: [ [ <remote server> ] <server mask> ] + + With LINKS, a user can list all servernames, which are known by the + server answering the query. The returned list of servers MUST match + the mask, or if no mask is given, the full list is returned. + + If <remote server> is given in addition to <server mask>, the LINKS + command is forwarded to the first server found that matches that name + (if any), and that server is then required to answer the query. + + Numeric Replies: + + ERR_NOSUCHSERVER + RPL_LINKS RPL_ENDOFLINKS + + Examples: + + LINKS *.au ; Command to list all servers which + have a name that matches *.au; + + LINKS *.edu *.bu.edu ; Command to list servers matching + *.bu.edu as seen by the first server + matching *.edu. + +3.4.6 Time message + + Command: TIME + Parameters: [ <target> ] + + The time command is used to query local time from the specified + server. If the <target> parameter is not given, the server receiving + the command must reply to the query. + + Wildcards are allowed in the <target> parameter. + + Numeric Replies: + + ERR_NOSUCHSERVER RPL_TIME + + Examples: + TIME tolsun.oulu.fi ; check the time on the server + "tolson.oulu.fi" + +3.4.7 Connect message + + Command: CONNECT + Parameters: <target server> <port> [ <remote server> ] + + The CONNECT command can be used to request a server to try to + establish a new connection to another server immediately. CONNECT is + a privileged command and SHOULD be available only to IRC Operators. + If a <remote server> is given and its mask doesn't match name of the + parsing server, the CONNECT attempt is sent to the first match of + remote server. Otherwise the CONNECT attempt is made by the server + processing the request. + + The server receiving a remote CONNECT command SHOULD generate a + WALLOPS message describing the source and target of the request. + + Numeric Replies: + + ERR_NOSUCHSERVER ERR_NOPRIVILEGES + ERR_NEEDMOREPARAMS + + Examples: + + CONNECT tolsun.oulu.fi 6667 ; Command to attempt to connect local + server to tolsun.oulu.fi on port 6667 + +3.4.8 Trace message + + Command: TRACE + Parameters: [ <target> ] + + TRACE command is used to find the route to specific server and + information about its peers. Each server that processes this command + MUST report to the sender about it. The replies from pass-through + links form a chain, which shows route to destination. After sending + this reply back, the query MUST be sent to the next server until + given <target> server is reached. + + TRACE command is used to find the route to specific server. Each + server that processes this message MUST tell the sender about it by + sending a reply indicating it is a pass-through link, forming a chain + of replies. After sending this reply back, it MUST then send the + TRACE message to the next server until given server is reached. If + the <target> parameter is omitted, it is RECOMMENDED that TRACE + command sends a message to the sender telling which servers the local + server has direct connection to. + + If the destination given by <target> is an actual server, the + destination server is REQUIRED to report all servers, services and + operators which are connected to it; if the command was issued by an + operator, the server MAY also report all users which are connected to + it. If the destination given by <target> is a nickname, then only a + reply for that nickname is given. If the <target> parameter is + omitted, it is RECOMMENDED that the TRACE command is parsed as + targeted to the processing server. + + Wildcards are allowed in the <target> parameter. + + Numeric Replies: + + ERR_NOSUCHSERVER + + If the TRACE message is destined for another server, all + intermediate servers must return a RPL_TRACELINK reply to indicate + that the TRACE passed through it and where it is going next. + + RPL_TRACELINK + + A TRACE reply may be composed of any number of the following + numeric replies. + + RPL_TRACECONNECTING RPL_TRACEHANDSHAKE + RPL_TRACEUNKNOWN RPL_TRACEOPERATOR + RPL_TRACEUSER RPL_TRACESERVER + RPL_TRACESERVICE RPL_TRACENEWTYPE + RPL_TRACECLASS RPL_TRACELOG + RPL_TRACEEND + + Examples: + + TRACE *.oulu.fi ; TRACE to a server matching + *.oulu.fi + +3.4.9 Admin command + + Command: ADMIN + Parameters: [ <target> ] + + The admin command is used to find information about the administrator + of the given server, or current server if <target> parameter is + omitted. Each server MUST have the ability to forward ADMIN messages + to other servers. + + Wildcards are allowed in the <target> parameter. + + Numeric Replies: + + ERR_NOSUCHSERVER + RPL_ADMINME RPL_ADMINLOC1 + RPL_ADMINLOC2 RPL_ADMINEMAIL + + Examples: + + ADMIN tolsun.oulu.fi ; request an ADMIN reply from + tolsun.oulu.fi + + ADMIN syrk ; ADMIN request for the server to + which the user syrk is connected + +3.4.10 Info command + + Command: INFO + Parameters: [ <target> ] + + The INFO command is REQUIRED to return information describing the + server: its version, when it was compiled, the patchlevel, when it + was started, and any other miscellaneous information which may be + considered to be relevant. + + Wildcards are allowed in the <target> parameter. + + Numeric Replies: + + ERR_NOSUCHSERVER + RPL_INFO RPL_ENDOFINFO + + Examples: + + INFO csd.bu.edu ; request an INFO reply from + csd.bu.edu + + INFO Angel ; request info from the server that + Angel is connected to. + +3.5 Service Query and Commands + + The service query group of commands has been designed to return + information about any service which is connected to the network. + +3.5.1 Servlist message + + Command: SERVLIST + Parameters: [ <mask> [ <type> ] ] + + The SERVLIST command is used to list services currently connected to + the network and visible to the user issuing the command. The + optional parameters may be used to restrict the result of the query + (to matching services names, and services type). + + Numeric Replies: + + RPL_SERVLIST RPL_SERVLISTEND + +3.5.2 Squery + + Command: SQUERY + Parameters: <servicename> <text> + + The SQUERY command is used similarly to PRIVMSG. The only difference + is that the recipient MUST be a service. This is the only way for a + text message to be delivered to a service. + + See PRIVMSG for more details on replies and example. + + Examples: + + SQUERY irchelp :HELP privmsg + ; Message to the service with + nickname irchelp. + + SQUERY dict@irc.fr :fr2en blaireau + ; Message to the service with name + dict@irc.fr. + +3.6 User based queries + + User queries are a group of commands which are primarily concerned + with finding details on a particular user or group users. When using + wildcards with any of these commands, if they match, they will only + return information on users who are 'visible' to you. The visibility + of a user is determined as a combination of the user's mode and the + common set of channels you are both on. + + Although services SHOULD NOT be using this class of message, they are + allowed to. + +3.6.1 Who query + + Command: WHO + Parameters: [ <mask> [ "o" ] ] + + The WHO command is used by a client to generate a query which returns + a list of information which 'matches' the <mask> parameter given by + the client. In the absence of the <mask> parameter, all visible + (users who aren't invisible (user mode +i) and who don't have a + common channel with the requesting client) are listed. The same + result can be achieved by using a <mask> of "0" or any wildcard which + will end up matching every visible user. + + The <mask> passed to WHO is matched against users' host, server, real + name and nickname if the channel <mask> cannot be found. + + If the "o" parameter is passed only operators are returned according + to the <mask> supplied. + + Numeric Replies: + + ERR_NOSUCHSERVER + RPL_WHOREPLY RPL_ENDOFWHO + + Examples: + + WHO *.fi ; Command to list all users who match + against "*.fi". + + WHO jto* o ; Command to list all users with a + match against "jto*" if they are an + operator. + +3.6.2 Whois query + + Command: WHOIS + Parameters: [ <target> ] <mask> *( "," <mask> ) + + This command is used to query information about particular user. + The server will answer this command with several numeric messages + indicating different statuses of each user which matches the mask (if + you are entitled to see them). If no wildcard is present in the + <mask>, any information about that nick which you are allowed to see + is presented. + + If the <target> parameter is specified, it sends the query to a + specific server. It is useful if you want to know how long the user + in question has been idle as only local server (i.e., the server the + user is directly connected to) knows that information, while + everything else is globally known. + + Wildcards are allowed in the <target> parameter. + + Numeric Replies: + + ERR_NOSUCHSERVER ERR_NONICKNAMEGIVEN + RPL_WHOISUSER RPL_WHOISCHANNELS + RPL_WHOISCHANNELS RPL_WHOISSERVER + RPL_AWAY RPL_WHOISOPERATOR + RPL_WHOISIDLE ERR_NOSUCHNICK + RPL_ENDOFWHOIS + + Examples: + + WHOIS wiz ; return available user information + about nick WiZ + + WHOIS eff.org trillian ; ask server eff.org for user + information about trillian + +3.6.3 Whowas + + Command: WHOWAS + Parameters: <nickname> *( "," <nickname> ) [ <count> [ <target> ] ] + + Whowas asks for information about a nickname which no longer exists. + This may either be due to a nickname change or the user leaving IRC. + In response to this query, the server searches through its nickname + history, looking for any nicks which are lexically the same (no wild + card matching here). The history is searched backward, returning the + most recent entry first. If there are multiple entries, up to + <count> replies will be returned (or all of them if no <count> + parameter is given). If a non-positive number is passed as being + <count>, then a full search is done. + + Wildcards are allowed in the <target> parameter. + + Numeric Replies: + + ERR_NONICKNAMEGIVEN ERR_WASNOSUCHNICK + RPL_WHOWASUSER RPL_WHOISSERVER + RPL_ENDOFWHOWAS + + Examples: + + WHOWAS Wiz ; return all information in the nick + history about nick "WiZ"; + + WHOWAS Mermaid 9 ; return at most, the 9 most recent + entries in the nick history for + "Mermaid"; + + WHOWAS Trillian 1 *.edu ; return the most recent history for + "Trillian" from the first server + found to match "*.edu". + +3.7 Miscellaneous messages + + Messages in this category do not fit into any of the above categories + but are nonetheless still a part of and REQUIRED by the protocol. + +3.7.1 Kill message + + Command: KILL + Parameters: <nickname> <comment> + + The KILL command is used to cause a client-server connection to be + closed by the server which has the actual connection. Servers + generate KILL messages on nickname collisions. It MAY also be + available available to users who have the operator status. + + Clients which have automatic reconnect algorithms effectively make + this command useless since the disconnection is only brief. It does + however break the flow of data and can be used to stop large amounts + of 'flooding' from abusive users or accidents. Abusive users usually + don't care as they will reconnect promptly and resume their abusive + behaviour. To prevent this command from being abused, any user may + elect to receive KILL messages generated for others to keep an 'eye' + on would be trouble spots. + + In an arena where nicknames are REQUIRED to be globally unique at all + times, KILL messages are sent whenever 'duplicates' are detected + (that is an attempt to register two users with the same nickname) in + the hope that both of them will disappear and only 1 reappear. + + When a client is removed as the result of a KILL message, the server + SHOULD add the nickname to the list of unavailable nicknames in an + attempt to avoid clients to reuse this name immediately which is + usually the pattern of abusive behaviour often leading to useless + "KILL loops". See the "IRC Server Protocol" document [IRC-SERVER] + for more information on this procedure. + + The comment given MUST reflect the actual reason for the KILL. For + server-generated KILLs it usually is made up of details concerning + the origins of the two conflicting nicknames. For users it is left + up to them to provide an adequate reason to satisfy others who see + it. To prevent/discourage fake KILLs from being generated to hide + the identify of the KILLer, the comment also shows a 'kill-path' + which is updated by each server it passes through, each prepending + its name to the path. + + Numeric Replies: + + ERR_NOPRIVILEGES ERR_NEEDMOREPARAMS + ERR_NOSUCHNICK ERR_CANTKILLSERVER + + NOTE: + It is RECOMMENDED that only Operators be allowed to kill other users + with KILL command. This command has been the subject of many + controversies over the years, and along with the above + recommendation, it is also widely recognized that not even operators + should be allowed to kill users on remote servers. + +3.7.2 Ping message + + Command: PING + Parameters: <server1> [ <server2> ] + + The PING command is used to test the presence of an active client or + server at the other end of the connection. Servers send a PING + message at regular intervals if no other activity detected coming + from a connection. If a connection fails to respond to a PING + message within a set amount of time, that connection is closed. A + PING message MAY be sent even if the connection is active. + + When a PING message is received, the appropriate PONG message MUST be + sent as reply to <server1> (server which sent the PING message out) + as soon as possible. If the <server2> parameter is specified, it + represents the target of the ping, and the message gets forwarded + there. + + Numeric Replies: + + ERR_NOORIGIN ERR_NOSUCHSERVER + + Examples: + + PING tolsun.oulu.fi ; Command to send a PING message to + server + + PING WiZ tolsun.oulu.fi ; Command from WiZ to send a PING + message to server "tolsun.oulu.fi" + + PING :irc.funet.fi ; Ping message sent by server + "irc.funet.fi" + +3.7.3 Pong message + + Command: PONG + Parameters: <server> [ <server2> ] + + PONG message is a reply to ping message. If parameter <server2> is + given, this message MUST be forwarded to given target. The <server> + parameter is the name of the entity who has responded to PING message + and generated this message. + + Numeric Replies: + + ERR_NOORIGIN ERR_NOSUCHSERVER + + Example: + + PONG csd.bu.edu tolsun.oulu.fi ; PONG message from csd.bu.edu to + tolsun.oulu.fi + +3.7.4 Error + + Command: ERROR + Parameters: <error message> + + The ERROR command is for use by servers when reporting a serious or + fatal error to its peers. It may also be sent from one server to + another but MUST NOT be accepted from any normal unknown clients. + + Only an ERROR message SHOULD be used for reporting errors which occur + with a server-to-server link. An ERROR message is sent to the server + at the other end (which reports it to appropriate local users and + logs) and to appropriate local users and logs. It is not to be + passed onto any other servers by a server if it is received from a + server. + + The ERROR message is also used before terminating a client + connection. + + When a server sends a received ERROR message to its operators, the + message SHOULD be encapsulated inside a NOTICE message, indicating + that the client was not responsible for the error. + + Numerics: + + None. + + Examples: + + ERROR :Server *.fi already exists ; ERROR message to the other server + which caused this error. + + NOTICE WiZ :ERROR from csd.bu.edu -- Server *.fi already exists + ; Same ERROR message as above but + sent to user WiZ on the other server. + +4. Optional features + + This section describes OPTIONAL messages. They are not required in a + working server implementation of the protocol described herein. In + the absence of the feature, an error reply message MUST be generated + or an unknown command error. If the message is destined for another + server to answer then it MUST be passed on (elementary parsing + REQUIRED) The allocated numerics for this are listed with the + messages below. + + From this section, only the USERHOST and ISON messages are available + to services. + +4.1 Away + + Command: AWAY + Parameters: [ <text> ] + + With the AWAY command, clients can set an automatic reply string for + any PRIVMSG commands directed at them (not to a channel they are on). + The server sends an automatic reply to the client sending the PRIVMSG + command. The only replying server is the one to which the sending + client is connected to. + + The AWAY command is used either with one parameter, to set an AWAY + message, or with no parameters, to remove the AWAY message. + + Because of its high cost (memory and bandwidth wise), the AWAY + message SHOULD only be used for client-server communication. A + server MAY choose to silently ignore AWAY messages received from + other servers. To update the away status of a client across servers, + the user mode 'a' SHOULD be used instead. (See Section 3.1.5) + + Numeric Replies: + + RPL_UNAWAY RPL_NOWAWAY + + Example: + + AWAY :Gone to lunch. Back in 5 ; Command to set away message to + "Gone to lunch. Back in 5". + +4.2 Rehash message + + Command: REHASH + Parameters: None + + The rehash command is an administrative command which can be used by + an operator to force the server to re-read and process its + configuration file. + + Numeric Replies: + + RPL_REHASHING ERR_NOPRIVILEGES + + Example: + + REHASH ; message from user with operator + status to server asking it to reread + its configuration file. + +4.3 Die message + + Command: DIE + Parameters: None + + An operator can use the DIE command to shutdown the server. This + message is optional since it may be viewed as a risk to allow + arbitrary people to connect to a server as an operator and execute + this command. + + The DIE command MUST always be fully processed by the server to which + the sending client is connected and MUST NOT be passed onto other + connected servers. + + Numeric Replies: + + ERR_NOPRIVILEGES + + Example: + + DIE ; no parameters required. + +4.4 Restart message + + Command: RESTART + Parameters: None + + An operator can use the restart command to force the server to + restart itself. This message is optional since it may be viewed as a + risk to allow arbitrary people to connect to a server as an operator + and execute this command, causing (at least) a disruption to service. + + The RESTART command MUST always be fully processed by the server to + which the sending client is connected and MUST NOT be passed onto + other connected servers. + + Numeric Replies: + + ERR_NOPRIVILEGES + + Example: + + RESTART ; no parameters required. + +4.5 Summon message + + Command: SUMMON + Parameters: <user> [ <target> [ <channel> ] ] + + The SUMMON command can be used to give users who are on a host + running an IRC server a message asking them to please join IRC. This + message is only sent if the target server (a) has SUMMON enabled, (b) + the user is logged in and (c) the server process can write to the + user's tty (or similar). + + If no <server> parameter is given it tries to summon <user> from the + server the client is connected to is assumed as the target. + + If summon is not enabled in a server, it MUST return the + ERR_SUMMONDISABLED numeric. + + Numeric Replies: + + ERR_NORECIPIENT ERR_FILEERROR + ERR_NOLOGIN ERR_NOSUCHSERVER + ERR_SUMMONDISABLED RPL_SUMMONING + + Examples: + + SUMMON jto ; summon user jto on the server's + host + + SUMMON jto tolsun.oulu.fi ; summon user jto on the host which a + server named "tolsun.oulu.fi" is + running. + +4.6 Users + + Command: USERS + Parameters: [ <target> ] + + The USERS command returns a list of users logged into the server in a + format similar to the UNIX commands who(1), rusers(1) and finger(1). + If disabled, the correct numeric MUST be returned to indicate this. + + Because of the security implications of such a command, it SHOULD be + disabled by default in server implementations. Enabling it SHOULD + require recompiling the server or some equivalent change rather than + simply toggling an option and restarting the server. The procedure + to enable this command SHOULD also include suitable large comments. + + Numeric Replies: + + ERR_NOSUCHSERVER ERR_FILEERROR + RPL_USERSSTART RPL_USERS + RPL_NOUSERS RPL_ENDOFUSERS + ERR_USERSDISABLED + + Disabled Reply: + + ERR_USERSDISABLED + + Example: + + USERS eff.org ; request a list of users logged in + on server eff.org + +4.7 Operwall message + + Command: WALLOPS + Parameters: <Text to be sent> + + The WALLOPS command is used to send a message to all currently + connected users who have set the 'w' user mode for themselves. (See + Section 3.1.5 "User modes"). + + After implementing WALLOPS as a user command it was found that it was + often and commonly abused as a means of sending a message to a lot of + people. Due to this, it is RECOMMENDED that the implementation of + WALLOPS allows and recognizes only servers as the originators of + WALLOPS. + + Numeric Replies: + + ERR_NEEDMOREPARAMS + + Example: + + :csd.bu.edu WALLOPS :Connect '*.uiuc.edu 6667' from Joshua ; WALLOPS + message from csd.bu.edu announcing a + CONNECT message it received from + Joshua and acted upon. + +4.8 Userhost message + + Command: USERHOST + Parameters: <nickname> *( SPACE <nickname> ) + + The USERHOST command takes a list of up to 5 nicknames, each + separated by a space character and returns a list of information + about each nickname that it found. The returned list has each reply + separated by a space. + + Numeric Replies: + + RPL_USERHOST ERR_NEEDMOREPARAMS + + Example: + + USERHOST Wiz Michael syrk ; USERHOST request for information on + nicks "Wiz", "Michael", and "syrk" + + :ircd.stealth.net 302 yournick :syrk=+syrk@millennium.stealth.net + ; Reply for user syrk + +4.9 Ison message + + Command: ISON + Parameters: <nickname> *( SPACE <nickname> ) + + The ISON command was implemented to provide a quick and efficient + means to get a response about whether a given nickname was currently + on IRC. ISON only takes one (1) type of parameter: a space-separated + list of nicks. For each nickname in the list that is present, the + + server adds that to its reply string. Thus the reply string may + return empty (none of the given nicks are present), an exact copy of + the parameter string (all of them present) or any other subset of the + set of nicks given in the parameter. The only limit on the number of + nicks that may be checked is that the combined length MUST NOT be too + large as to cause the server to chop it off so it fits in 512 + characters. + + ISON is only processed by the server local to the client sending the + command and thus not passed onto other servers for further + processing. + + Numeric Replies: + + RPL_ISON ERR_NEEDMOREPARAMS + + Example: + + ISON phone trillian WiZ jarlek Avalon Angel Monstah syrk + ; Sample ISON request for 7 nicks. + +5. Replies + + The following is a list of numeric replies which are generated in + response to the commands given above. Each numeric is given with its + number, name and reply string. + +5.1 Command responses + + Numerics in the range from 001 to 099 are used for client-server + connections only and should never travel between servers. Replies + generated in the response to commands are found in the range from 200 + to 399. + + 001 RPL_WELCOME + "Welcome to the Internet Relay Network + <nick>!<user>@<host>" + 002 RPL_YOURHOST + "Your host is <servername>, running version <ver>" + 003 RPL_CREATED + "This server was created <date>" + 004 RPL_MYINFO + "<servername> <version> <available user modes> + <available channel modes>" + + - The server sends Replies 001 to 004 to a user upon + successful registration. + + 005 RPL_BOUNCE + "Try server <server name>, port <port number>" + + - Sent by the server to a user to suggest an alternative + server. This is often used when the connection is + refused because the server is already full. + + 302 RPL_USERHOST + ":*1<reply> *( " " <reply> )" + + - Reply format used by USERHOST to list replies to + the query list. The reply string is composed as + follows: + + reply = nickname [ "*" ] "=" ( "+" / "-" ) hostname + + The '*' indicates whether the client has registered + as an Operator. The '-' or '+' characters represent + whether the client has set an AWAY message or not + respectively. + + 303 RPL_ISON + ":*1<nick> *( " " <nick> )" + + - Reply format used by ISON to list replies to the + query list. + + 301 RPL_AWAY + "<nick> :<away message>" + 305 RPL_UNAWAY + ":You are no longer marked as being away" + 306 RPL_NOWAWAY + ":You have been marked as being away" + + - These replies are used with the AWAY command (if + allowed). RPL_AWAY is sent to any client sending a + PRIVMSG to a client which is away. RPL_AWAY is only + sent by the server to which the client is connected. + Replies RPL_UNAWAY and RPL_NOWAWAY are sent when the + client removes and sets an AWAY message. + + 311 RPL_WHOISUSER + "<nick> <user> <host> * :<real name>" + 312 RPL_WHOISSERVER + "<nick> <server> :<server info>" + 313 RPL_WHOISOPERATOR + "<nick> :is an IRC operator" + + 317 RPL_WHOISIDLE + "<nick> <integer> :seconds idle" + 318 RPL_ENDOFWHOIS + "<nick> :End of WHOIS list" + 319 RPL_WHOISCHANNELS + "<nick> :*( ( "@" / "+" ) <channel> " " )" + + - Replies 311 - 313, 317 - 319 are all replies + generated in response to a WHOIS message. Given that + there are enough parameters present, the answering + server MUST either formulate a reply out of the above + numerics (if the query nick is found) or return an + error reply. The '*' in RPL_WHOISUSER is there as + the literal character and not as a wild card. For + each reply set, only RPL_WHOISCHANNELS may appear + more than once (for long lists of channel names). + The '@' and '+' characters next to the channel name + indicate whether a client is a channel operator or + has been granted permission to speak on a moderated + channel. The RPL_ENDOFWHOIS reply is used to mark + the end of processing a WHOIS message. + + 314 RPL_WHOWASUSER + "<nick> <user> <host> * :<real name>" + 369 RPL_ENDOFWHOWAS + "<nick> :End of WHOWAS" + + - When replying to a WHOWAS message, a server MUST use + the replies RPL_WHOWASUSER, RPL_WHOISSERVER or + ERR_WASNOSUCHNICK for each nickname in the presented + list. At the end of all reply batches, there MUST + be RPL_ENDOFWHOWAS (even if there was only one reply + and it was an error). + + 321 RPL_LISTSTART + Obsolete. Not used. + + 322 RPL_LIST + "<channel> <# visible> :<topic>" + 323 RPL_LISTEND + ":End of LIST" + + - Replies RPL_LIST, RPL_LISTEND mark the actual replies + with data and end of the server's response to a LIST + command. If there are no channels available to return, + only the end reply MUST be sent. + + 325 RPL_UNIQOPIS + "<channel> <nickname>" + + 324 RPL_CHANNELMODEIS + "<channel> <mode> <mode params>" + + 331 RPL_NOTOPIC + "<channel> :No topic is set" + 332 RPL_TOPIC + "<channel> :<topic>" + + - When sending a TOPIC message to determine the + channel topic, one of two replies is sent. If + the topic is set, RPL_TOPIC is sent back else + RPL_NOTOPIC. + + 341 RPL_INVITING + "<channel> <nick>" + + - Returned by the server to indicate that the + attempted INVITE message was successful and is + being passed onto the end client. + + 342 RPL_SUMMONING + "<user> :Summoning user to IRC" + + - Returned by a server answering a SUMMON message to + indicate that it is summoning that user. + + 346 RPL_INVITELIST + "<channel> <invitemask>" + 347 RPL_ENDOFINVITELIST + "<channel> :End of channel invite list" + + - When listing the 'invitations masks' for a given channel, + a server is required to send the list back using the + RPL_INVITELIST and RPL_ENDOFINVITELIST messages. A + separate RPL_INVITELIST is sent for each active mask. + After the masks have been listed (or if none present) a + RPL_ENDOFINVITELIST MUST be sent. + + 348 RPL_EXCEPTLIST + "<channel> <exceptionmask>" + 349 RPL_ENDOFEXCEPTLIST + "<channel> :End of channel exception list" + + - When listing the 'exception masks' for a given channel, + a server is required to send the list back using the + RPL_EXCEPTLIST and RPL_ENDOFEXCEPTLIST messages. A + separate RPL_EXCEPTLIST is sent for each active mask. + After the masks have been listed (or if none present) + a RPL_ENDOFEXCEPTLIST MUST be sent. + + 351 RPL_VERSION + "<version>.<debuglevel> <server> :<comments>" + + - Reply by the server showing its version details. + The <version> is the version of the software being + used (including any patchlevel revisions) and the + <debuglevel> is used to indicate if the server is + running in "debug mode". + + The "comments" field may contain any comments about + the version or further version details. + + 352 RPL_WHOREPLY + "<channel> <user> <host> <server> <nick> + ( "H" / "G" > ["*"] [ ( "@" / "+" ) ] + :<hopcount> <real name>" + + 315 RPL_ENDOFWHO + "<name> :End of WHO list" + + - The RPL_WHOREPLY and RPL_ENDOFWHO pair are used + to answer a WHO message. The RPL_WHOREPLY is only + sent if there is an appropriate match to the WHO + query. If there is a list of parameters supplied + with a WHO message, a RPL_ENDOFWHO MUST be sent + after processing each list item with <name> being + the item. + + 353 RPL_NAMREPLY + "( "=" / "*" / "@" ) <channel> + :[ "@" / "+" ] <nick> *( " " [ "@" / "+" ] <nick> ) + - "@" is used for secret channels, "*" for private + channels, and "=" for others (public channels). + + 366 RPL_ENDOFNAMES + "<channel> :End of NAMES list" + + - To reply to a NAMES message, a reply pair consisting + of RPL_NAMREPLY and RPL_ENDOFNAMES is sent by the + server back to the client. If there is no channel + found as in the query, then only RPL_ENDOFNAMES is + + returned. The exception to this is when a NAMES + message is sent with no parameters and all visible + channels and contents are sent back in a series of + RPL_NAMEREPLY messages with a RPL_ENDOFNAMES to mark + the end. + + 364 RPL_LINKS + "<mask> <server> :<hopcount> <server info>" + 365 RPL_ENDOFLINKS + "<mask> :End of LINKS list" + + - In replying to the LINKS message, a server MUST send + replies back using the RPL_LINKS numeric and mark the + end of the list using an RPL_ENDOFLINKS reply. + + 367 RPL_BANLIST + "<channel> <banmask>" + 368 RPL_ENDOFBANLIST + "<channel> :End of channel ban list" + + - When listing the active 'bans' for a given channel, + a server is required to send the list back using the + RPL_BANLIST and RPL_ENDOFBANLIST messages. A separate + RPL_BANLIST is sent for each active banmask. After the + banmasks have been listed (or if none present) a + RPL_ENDOFBANLIST MUST be sent. + + 371 RPL_INFO + ":<string>" + 374 RPL_ENDOFINFO + ":End of INFO list" + + - A server responding to an INFO message is required to + send all its 'info' in a series of RPL_INFO messages + with a RPL_ENDOFINFO reply to indicate the end of the + replies. + + 375 RPL_MOTDSTART + ":- <server> Message of the day - " + 372 RPL_MOTD + ":- <text>" + 376 RPL_ENDOFMOTD + ":End of MOTD command" + + - When responding to the MOTD message and the MOTD file + is found, the file is displayed line by line, with + each line no longer than 80 characters, using + + RPL_MOTD format replies. These MUST be surrounded + by a RPL_MOTDSTART (before the RPL_MOTDs) and an + RPL_ENDOFMOTD (after). + + 381 RPL_YOUREOPER + ":You are now an IRC operator" + + - RPL_YOUREOPER is sent back to a client which has + just successfully issued an OPER message and gained + operator status. + + 382 RPL_REHASHING + "<config file> :Rehashing" + + - If the REHASH option is used and an operator sends + a REHASH message, an RPL_REHASHING is sent back to + the operator. + + 383 RPL_YOURESERVICE + "You are service <servicename>" + + - Sent by the server to a service upon successful + registration. + + 391 RPL_TIME + "<server> :<string showing server's local time>" + + - When replying to the TIME message, a server MUST send + the reply using the RPL_TIME format above. The string + showing the time need only contain the correct day and + time there. There is no further requirement for the + time string. + + 392 RPL_USERSSTART + ":UserID Terminal Host" + 393 RPL_USERS + ":<username> <ttyline> <hostname>" + 394 RPL_ENDOFUSERS + ":End of users" + 395 RPL_NOUSERS + ":Nobody logged in" + + - If the USERS message is handled by a server, the + replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and + RPL_NOUSERS are used. RPL_USERSSTART MUST be sent + first, following by either a sequence of RPL_USERS + or a single RPL_NOUSER. Following this is + RPL_ENDOFUSERS. + + 200 RPL_TRACELINK + "Link <version & debug level> <destination> + <next server> V<protocol version> + <link uptime in seconds> <backstream sendq> + <upstream sendq>" + 201 RPL_TRACECONNECTING + "Try. <class> <server>" + 202 RPL_TRACEHANDSHAKE + "H.S. <class> <server>" + 203 RPL_TRACEUNKNOWN + "???? <class> [<client IP address in dot form>]" + 204 RPL_TRACEOPERATOR + "Oper <class> <nick>" + 205 RPL_TRACEUSER + "User <class> <nick>" + 206 RPL_TRACESERVER + "Serv <class> <int>S <int>C <server> + <nick!user|*!*>@<host|server> V<protocol version>" + 207 RPL_TRACESERVICE + "Service <class> <name> <type> <active type>" + 208 RPL_TRACENEWTYPE + "<newtype> 0 <client name>" + 209 RPL_TRACECLASS + "Class <class> <count>" + 210 RPL_TRACERECONNECT + Unused. + 261 RPL_TRACELOG + "File <logfile> <debug level>" + 262 RPL_TRACEEND + "<server name> <version & debug level> :End of TRACE" + + - The RPL_TRACE* are all returned by the server in + response to the TRACE message. How many are + returned is dependent on the TRACE message and + whether it was sent by an operator or not. There + is no predefined order for which occurs first. + Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and + RPL_TRACEHANDSHAKE are all used for connections + which have not been fully established and are either + unknown, still attempting to connect or in the + process of completing the 'server handshake'. + RPL_TRACELINK is sent by any server which handles + a TRACE message and has to pass it on to another + server. The list of RPL_TRACELINKs sent in + response to a TRACE command traversing the IRC + network should reflect the actual connectivity of + the servers themselves along that path. + + RPL_TRACENEWTYPE is to be used for any connection + which does not fit in the other categories but is + being displayed anyway. + RPL_TRACEEND is sent to indicate the end of the list. + + 211 RPL_STATSLINKINFO + "<linkname> <sendq> <sent messages> + <sent Kbytes> <received messages> + <received Kbytes> <time open>" + + - reports statistics on a connection. <linkname> + identifies the particular connection, <sendq> is + the amount of data that is queued and waiting to be + sent <sent messages> the number of messages sent, + and <sent Kbytes> the amount of data sent, in + Kbytes. <received messages> and <received Kbytes> + are the equivalent of <sent messages> and <sent + Kbytes> for received data, respectively. <time + open> indicates how long ago the connection was + opened, in seconds. + + 212 RPL_STATSCOMMANDS + "<command> <count> <byte count> <remote count>" + + - reports statistics on commands usage. + + 219 RPL_ENDOFSTATS + "<stats letter> :End of STATS report" + + 242 RPL_STATSUPTIME + ":Server Up %d days %d:%02d:%02d" + + - reports the server uptime. + + 243 RPL_STATSOLINE + "O <hostmask> * <name>" + + - reports the allowed hosts from where user may become IRC + operators. + + 221 RPL_UMODEIS + "<user mode string>" + + - To answer a query about a client's own mode, + RPL_UMODEIS is sent back. + + 234 RPL_SERVLIST + "<name> <server> <mask> <type> <hopcount> <info>" + + 235 RPL_SERVLISTEND + "<mask> <type> :End of service listing" + + - When listing services in reply to a SERVLIST message, + a server is required to send the list back using the + RPL_SERVLIST and RPL_SERVLISTEND messages. A separate + RPL_SERVLIST is sent for each service. After the + services have been listed (or if none present) a + RPL_SERVLISTEND MUST be sent. + + 251 RPL_LUSERCLIENT + ":There are <integer> users and <integer> + services on <integer> servers" + 252 RPL_LUSEROP + "<integer> :operator(s) online" + 253 RPL_LUSERUNKNOWN + "<integer> :unknown connection(s)" + 254 RPL_LUSERCHANNELS + "<integer> :channels formed" + 255 RPL_LUSERME + ":I have <integer> clients and <integer> + servers" + + - In processing an LUSERS message, the server + sends a set of replies from RPL_LUSERCLIENT, + RPL_LUSEROP, RPL_USERUNKNOWN, + RPL_LUSERCHANNELS and RPL_LUSERME. When + replying, a server MUST send back + RPL_LUSERCLIENT and RPL_LUSERME. The other + replies are only sent back if a non-zero count + is found for them. + + 256 RPL_ADMINME + "<server> :Administrative info" + 257 RPL_ADMINLOC1 + ":<admin info>" + 258 RPL_ADMINLOC2 + ":<admin info>" + 259 RPL_ADMINEMAIL + ":<admin info>" + + - When replying to an ADMIN message, a server + is expected to use replies RPL_ADMINME + through to RPL_ADMINEMAIL and provide a text + message with each. For RPL_ADMINLOC1 a + description of what city, state and country + the server is in is expected, followed by + details of the institution (RPL_ADMINLOC2) + + and finally the administrative contact for the + server (an email address here is REQUIRED) + in RPL_ADMINEMAIL. + + 263 RPL_TRYAGAIN + "<command> :Please wait a while and try again." + + - When a server drops a command without processing it, + it MUST use the reply RPL_TRYAGAIN to inform the + originating client. + +5.2 Error Replies + + Error replies are found in the range from 400 to 599. + + 401 ERR_NOSUCHNICK + "<nickname> :No such nick/channel" + + - Used to indicate the nickname parameter supplied to a + command is currently unused. + + 402 ERR_NOSUCHSERVER + "<server name> :No such server" + + - Used to indicate the server name given currently + does not exist. + + 403 ERR_NOSUCHCHANNEL + "<channel name> :No such channel" + + - Used to indicate the given channel name is invalid. + + 404 ERR_CANNOTSENDTOCHAN + "<channel name> :Cannot send to channel" + + - Sent to a user who is either (a) not on a channel + which is mode +n or (b) not a chanop (or mode +v) on + a channel which has mode +m set or where the user is + banned and is trying to send a PRIVMSG message to + that channel. + + 405 ERR_TOOMANYCHANNELS + "<channel name> :You have joined too many channels" + + - Sent to a user when they have joined the maximum + number of allowed channels and they try to join + another channel. + + 406 ERR_WASNOSUCHNICK + "<nickname> :There was no such nickname" + + - Returned by WHOWAS to indicate there is no history + information for that nickname. + + 407 ERR_TOOMANYTARGETS + "<target> :<error code> recipients. <abort message>" + + - Returned to a client which is attempting to send a + PRIVMSG/NOTICE using the user@host destination format + and for a user@host which has several occurrences. + + - Returned to a client which trying to send a + PRIVMSG/NOTICE to too many recipients. + + - Returned to a client which is attempting to JOIN a safe + channel using the shortname when there are more than one + such channel. + + 408 ERR_NOSUCHSERVICE + "<service name> :No such service" + + - Returned to a client which is attempting to send a SQUERY + to a service which does not exist. + + 409 ERR_NOORIGIN + ":No origin specified" + + - PING or PONG message missing the originator parameter. + + 411 ERR_NORECIPIENT + ":No recipient given (<command>)" + 412 ERR_NOTEXTTOSEND + ":No text to send" + 413 ERR_NOTOPLEVEL + "<mask> :No toplevel domain specified" + 414 ERR_WILDTOPLEVEL + "<mask> :Wildcard in toplevel domain" + 415 ERR_BADMASK + "<mask> :Bad Server/host mask" + + - 412 - 415 are returned by PRIVMSG to indicate that + the message wasn't delivered for some reason. + ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that + are returned when an invalid use of + "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted. + + 421 ERR_UNKNOWNCOMMAND + "<command> :Unknown command" + + - Returned to a registered client to indicate that the + command sent is unknown by the server. + + 422 ERR_NOMOTD + ":MOTD File is missing" + + - Server's MOTD file could not be opened by the server. + + 423 ERR_NOADMININFO + "<server> :No administrative info available" + + - Returned by a server in response to an ADMIN message + when there is an error in finding the appropriate + information. + + 424 ERR_FILEERROR + ":File error doing <file op> on <file>" + + - Generic error message used to report a failed file + operation during the processing of a message. + + 431 ERR_NONICKNAMEGIVEN + ":No nickname given" + + - Returned when a nickname parameter expected for a + command and isn't found. + + 432 ERR_ERRONEUSNICKNAME + "<nick> :Erroneous nickname" + + - Returned after receiving a NICK message which contains + characters which do not fall in the defined set. See + section 2.3.1 for details on valid nicknames. + + 433 ERR_NICKNAMEINUSE + "<nick> :Nickname is already in use" + + - Returned when a NICK message is processed that results + in an attempt to change to a currently existing + nickname. + + 436 ERR_NICKCOLLISION + "<nick> :Nickname collision KILL from <user>@<host>" + + - Returned by a server to a client when it detects a + nickname collision (registered of a NICK that + already exists by another server). + + 437 ERR_UNAVAILRESOURCE + "<nick/channel> :Nick/channel is temporarily unavailable" + + - Returned by a server to a user trying to join a channel + currently blocked by the channel delay mechanism. + + - Returned by a server to a user trying to change nickname + when the desired nickname is blocked by the nick delay + mechanism. + + 441 ERR_USERNOTINCHANNEL + "<nick> <channel> :They aren't on that channel" + + - Returned by the server to indicate that the target + user of the command is not on the given channel. + + 442 ERR_NOTONCHANNEL + "<channel> :You're not on that channel" + + - Returned by the server whenever a client tries to + perform a channel affecting command for which the + client isn't a member. + + 443 ERR_USERONCHANNEL + "<user> <channel> :is already on channel" + + - Returned when a client tries to invite a user to a + channel they are already on. + + 444 ERR_NOLOGIN + "<user> :User not logged in" + + - Returned by the summon after a SUMMON command for a + user was unable to be performed since they were not + logged in. + + 445 ERR_SUMMONDISABLED + ":SUMMON has been disabled" + + - Returned as a response to the SUMMON command. MUST be + returned by any server which doesn't implement it. + + 446 ERR_USERSDISABLED + ":USERS has been disabled" + + - Returned as a response to the USERS command. MUST be + returned by any server which does not implement it. + + 451 ERR_NOTREGISTERED + ":You have not registered" + + - Returned by the server to indicate that the client + MUST be registered before the server will allow it + to be parsed in detail. + + 461 ERR_NEEDMOREPARAMS + "<command> :Not enough parameters" + + - Returned by the server by numerous commands to + indicate to the client that it didn't supply enough + parameters. + + 462 ERR_ALREADYREGISTRED + ":Unauthorized command (already registered)" + + - Returned by the server to any link which tries to + change part of the registered details (such as + password or user details from second USER message). + + 463 ERR_NOPERMFORHOST + ":Your host isn't among the privileged" + + - Returned to a client which attempts to register with + a server which does not been setup to allow + connections from the host the attempted connection + is tried. + + 464 ERR_PASSWDMISMATCH + ":Password incorrect" + + - Returned to indicate a failed attempt at registering + a connection for which a password was required and + was either not given or incorrect. + + 465 ERR_YOUREBANNEDCREEP + ":You are banned from this server" + + - Returned after an attempt to connect and register + yourself with a server which has been setup to + explicitly deny connections to you. + + 466 ERR_YOUWILLBEBANNED + + - Sent by a server to a user to inform that access to the + server will soon be denied. + + 467 ERR_KEYSET + "<channel> :Channel key already set" + 471 ERR_CHANNELISFULL + "<channel> :Cannot join channel (+l)" + 472 ERR_UNKNOWNMODE + "<char> :is unknown mode char to me for <channel>" + 473 ERR_INVITEONLYCHAN + "<channel> :Cannot join channel (+i)" + 474 ERR_BANNEDFROMCHAN + "<channel> :Cannot join channel (+b)" + 475 ERR_BADCHANNELKEY + "<channel> :Cannot join channel (+k)" + 476 ERR_BADCHANMASK + "<channel> :Bad Channel Mask" + 477 ERR_NOCHANMODES + "<channel> :Channel doesn't support modes" + 478 ERR_BANLISTFULL + "<channel> <char> :Channel list is full" + + 481 ERR_NOPRIVILEGES + ":Permission Denied- You're not an IRC operator" + + - Any command requiring operator privileges to operate + MUST return this error to indicate the attempt was + unsuccessful. + + 482 ERR_CHANOPRIVSNEEDED + "<channel> :You're not channel operator" + + - Any command requiring 'chanop' privileges (such as + MODE messages) MUST return this error if the client + making the attempt is not a chanop on the specified + channel. + + 483 ERR_CANTKILLSERVER + ":You can't kill a server!" + + - Any attempts to use the KILL command on a server + are to be refused and this error returned directly + to the client. + + 484 ERR_RESTRICTED + ":Your connection is restricted!" + + - Sent by the server to a user upon connection to indicate + the restricted nature of the connection (user mode "+r"). + + 485 ERR_UNIQOPPRIVSNEEDED + ":You're not the original channel operator" + + - Any MODE requiring "channel creator" privileges MUST + return this error if the client making the attempt is not + a chanop on the specified channel. + + 491 ERR_NOOPERHOST + ":No O-lines for your host" + + - If a client sends an OPER message and the server has + not been configured to allow connections from the + client's host as an operator, this error MUST be + returned. + + 501 ERR_UMODEUNKNOWNFLAG + ":Unknown MODE flag" + + - Returned by the server to indicate that a MODE + message was sent with a nickname parameter and that + the a mode flag sent was not recognized. + + 502 ERR_USERSDONTMATCH + ":Cannot change mode for other users" + + - Error sent to any user trying to view or change the + user mode for a user other than themselves. + +5.3 Reserved numerics + + These numerics are not described above since they fall into one of + the following categories: + + 1. no longer in use; + + 2. reserved for future planned use; + + 3. in current use but are part of a non-generic 'feature' of + the current IRC server. + + 231 RPL_SERVICEINFO 232 RPL_ENDOFSERVICES + 233 RPL_SERVICE + 300 RPL_NONE 316 RPL_WHOISCHANOP + 361 RPL_KILLDONE 362 RPL_CLOSING + 363 RPL_CLOSEEND 373 RPL_INFOSTART + 384 RPL_MYPORTIS + + 213 RPL_STATSCLINE 214 RPL_STATSNLINE + 215 RPL_STATSILINE 216 RPL_STATSKLINE + 217 RPL_STATSQLINE 218 RPL_STATSYLINE + 240 RPL_STATSVLINE 241 RPL_STATSLLINE + 244 RPL_STATSHLINE 244 RPL_STATSSLINE + 246 RPL_STATSPING 247 RPL_STATSBLINE + 250 RPL_STATSDLINE + + 492 ERR_NOSERVICEHOST + +6. Current implementations + + The IRC software, version 2.10 is the only complete implementation of + the IRC protocol (client and server). Because of the small amount of + changes in the client protocol since the publication of RFC 1459 + [IRC], implementations that follow it are likely to be compliant with + this protocol or to require a small amount of changes to reach + compliance. + +7. Current problems + + There are a number of recognized problems with the IRC Client + Protocol, and more generally with the IRC Server Protocol. In order + to preserve backward compatibility with old clients, this protocol + has almost not evolved since the publication of RFC 1459 [IRC]. + +7.1 Nicknames + + The idea of the nickname on IRC is very convenient for users to use + when talking to each other outside of a channel, but there is only a + finite nickname space and being what they are, it's not uncommon for + several people to want to use the same nick. If a nickname is chosen + by two people using this protocol, either one will not succeed or + both will removed by use of a server KILL (See Section 3.7.1). + +7.2 Limitation of wildcards + + There is no way to escape the escape character "\" (%x5C). While + this isn't usually a problem, it makes it impossible to form a mask + with a backslash character ("\") preceding a wildcard. + +7.3 Security considerations + + Security issues related to this protocol are discussed in the "IRC + Server Protocol" [IRC-SERVER] as they are mostly an issue for the + server side of the connection. + +8. Current support and availability + + Mailing lists for IRC related discussion: + General discussion: ircd-users@irc.org + Protocol development: ircd-dev@irc.org + + Software implementations: + ftp://ftp.irc.org/irc/server + ftp://ftp.funet.fi/pub/unix/irc + ftp://ftp.irc.org/irc/clients + + Newsgroup: alt.irc + +9. Acknowledgements + + Parts of this document were copied from the RFC 1459 [IRC] which + first formally documented the IRC Protocol. It has also benefited + from many rounds of review and comments. In particular, the + following people have made significant contributions to this + document: + + Matthew Green, Michael Neumayer, Volker Paulsen, Kurt Roeckx, Vesa + Ruokonen, Magnus Tjernstrom, Stefan Zehl. + +10. References + + [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [ABNF] Crocker, D. and P. Overell, "Augmented BNF for Syntax + Specifications: ABNF", RFC 2234, November 1997. + + [HNAME] Braden, R., "Requirements for Internet Hosts -- + Application and Support", STD 3, RFC 1123, October 1989. + + [IRC] Oikarinen, J. & D. Reed, "Internet Relay Chat Protocol", + RFC 1459, May 1993. + + [IRC-ARCH] Kalt, C., "Internet Relay Chat: Architecture", RFC 2810, + April 2000. + + [IRC-CHAN] Kalt, C., "Internet Relay Chat: Channel Management", RFC + 2811, April 2000. + + [IRC-SERVER] Kalt, C., "Internet Relay Chat: Server Protocol", RFC + 2813, April 2000. + +11. Author's Address + + Christophe Kalt + 99 Teaneck Rd, Apt #117 + Ridgefield Park, NJ 07660 + USA + + EMail: kalt@stealth.net + +12. Full Copyright Statement + + Copyright (C) The Internet Society (2000). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. diff --git a/doc/technical/rfc2813.txt b/doc/technical/rfc2813.txt new file mode 100644 index 0000000..175de1d --- /dev/null +++ b/doc/technical/rfc2813.txt @@ -0,0 +1,1173 @@ +$Id$ + +Network Working Group C. Kalt +Request for Comments: 2813 April 2000 +Updates: 1459 +Category: Informational + + Internet Relay Chat: Server Protocol + +Status of this Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2000). All Rights Reserved. + +Abstract + + While based on the client-server model, the IRC (Internet Relay Chat) + protocol allows servers to connect to each other effectively forming + a network. + + This document defines the protocol used by servers to talk to each + other. It was originally a superset of the client protocol but has + evolved differently. + + First formally documented in May 1993 as part of RFC 1459 [IRC], most + of the changes brought since then can be found in this document as + development was focused on making the protocol scale better. Better + scalability has allowed existing world-wide networks to keep growing + and reach sizes which defy the old specification. + +Table of Contents + + 1. Introduction ............................................... 3 + 2. Global database ............................................ 3 + 2.1 Servers ................................................ 3 + 2.2 Clients ................................................ 4 + 2.2.1 Users ............................................. 4 + 2.2.2 Services .......................................... 4 + 2.3 Channels ............................................... 4 + 3. The IRC Server Specification ............................... 5 + 3.1 Overview ............................................... 5 + 3.2 Character codes ........................................ 5 + 3.3 Messages ............................................... 5 + 3.3.1 Message format in Augmented BNF ................... 6 + 3.4 Numeric replies ........................................ 7 + 4. Message Details ............................................ 7 + 4.1 Connection Registration ................................ 8 + 4.1.1 Password message .................................. 8 + 4.1.2 Server message .................................... 9 + 4.1.3 Nick .............................................. 10 + 4.1.4 Service message ................................... 11 + 4.1.5 Quit .............................................. 12 + 4.1.6 Server quit message ............................... 13 + 4.2 Channel operations ..................................... 14 + 4.2.1 Join message ...................................... 14 + 4.2.2 Njoin message ..................................... 15 + 4.2.3 Mode message ...................................... 16 + 5. Implementation details .................................... 16 + 5.1 Connection 'Liveness' .................................. 16 + 5.2 Accepting a client to server connection ................ 16 + 5.2.1 Users ............................................. 16 + 5.2.2 Services .......................................... 17 + 5.3 Establishing a server-server connection. ............... 17 + 5.3.1 Link options ...................................... 17 + 5.3.1.1 Compressed server to server links ............ 18 + 5.3.1.2 Anti abuse protections ....................... 18 + 5.3.2 State information exchange when connecting ........ 18 + 5.4 Terminating server-client connections .................. 19 + 5.5 Terminating server-server connections .................. 19 + 5.6 Tracking nickname changes .............................. 19 + 5.7 Tracking recently used nicknames ....................... 20 + 5.8 Flood control of clients ............................... 20 + 5.9 Non-blocking lookups ................................... 21 + 5.9.1 Hostname (DNS) lookups ............................ 21 + 5.9.2 Username (Ident) lookups .......................... 21 + 6. Current problems ........................................... 21 + 6.1 Scalability ............................................ 21 + 6.2 Labels ................................................. 22 + + 6.2.1 Nicknames ......................................... 22 + 6.2.2 Channels .......................................... 22 + 6.2.3 Servers ........................................... 22 + 6.3 Algorithms ............................................. 22 + 7. Security Considerations .................................... 23 + 7.1 Authentication ......................................... 23 + 7.2 Integrity .............................................. 23 + 8. Current support and availability ........................... 24 + 9. Acknowledgements ........................................... 24 + 10. References ................................................ 24 + 11. Author's Address .......................................... 25 + 12. Full Copyright Statement ................................... 26 + +1. Introduction + + This document is intended for people working on implementing an IRC + server but will also be useful to anyone implementing an IRC service. + + Servers provide the three basic services required for realtime + conferencing defined by the "Internet Relay Chat: Architecture" + [IRC-ARCH]: client locator (via the client protocol [IRC-CLIENT]), + message relaying (via the server protocol defined in this document) + and channel hosting and management (following specific rules [IRC- + CHAN]). + +2. Global database + + Although the IRC Protocol defines a fairly distributed model, each + server maintains a "global state database" about the whole IRC + network. This database is, in theory, identical on all servers. + +2.1 Servers + + Servers are uniquely identified by their name which has a maximum + length of sixty three (63) characters. See the protocol grammar + rules (section 3.3.1) for what may and may not be used in a server + name. + + Each server is typically known by all other servers, however it is + possible to define a "hostmask" to group servers together according + to their name. Inside the hostmasked area, all the servers have a + name which matches the hostmask, and any other server with a name + matching the hostmask SHALL NOT be connected to the IRC network + outside the hostmasked area. Servers which are outside the area have + no knowledge of the individual servers present inside the area, + instead they are presented with a virtual server which has the + hostmask for name. + +2.2 Clients + + For each client, all servers MUST have the following information: a + netwide unique identifier (whose format depends on the type of + client) and the server to which the client is connected. + +2.2.1 Users + + Each user is distinguished from other users by a unique nickname + having a maximum length of nine (9) characters. See the protocol + grammar rules (section 3.3.1) for what may and may not be used in a + nickname. In addition to the nickname, all servers MUST have the + following information about all users: the name of the host that the + user is running on, the username of the user on that host, and the + server to which the client is connected. + +2.2.2 Services + + Each service is distinguished from other services by a service name + composed of a nickname and a server name. The nickname has a maximum + length of nine (9) characters. See the protocol grammar rules + (section 3.3.1) for what may and may not be used in a nickname. The + server name used to compose the service name is the name of the + server to which the service is connected. In addition to this + service name all servers MUST know the service type. + + Services differ from users by the format of their identifier, but + more importantly services and users don't have the same type of + access to the server: services can request part or all of the global + state information that a server maintains, but have a more restricted + set of commands available to them (See "IRC Client Protocol" [IRC- + CLIENT] for details on which) and are not allowed to join channels. + Finally services are not usually subject to the "Flood control" + mechanism described in section 5.8. + +2.3 Channels + + Alike services, channels have a scope [IRC-CHAN] and are not + necessarily known to all servers. When a channel existence is known + to a server, the server MUST keep track of the channel members, as + well as the channel modes. + +3. The IRC Server Specification + +3.1 Overview + + The protocol as described herein is for use with server to server + connections. For client to server connections, see the IRC Client + Protocol specification. + + There are, however, more restrictions on client connections (which + are considered to be untrustworthy) than on server connections. + +3.2 Character codes + + No specific character set is specified. The protocol is based on a a + set of codes which are composed of eight (8) bits, making up an + octet. Each message may be composed of any number of these octets; + however, some octet values are used for control codes which act as + message delimiters. + + Regardless of being an 8-bit protocol, the delimiters and keywords + are such that protocol is mostly usable from US-ASCII terminal and a + telnet connection. + + Because of IRC's Scandinavian origin, the characters {}|^ are + considered to be the lower case equivalents of the characters []\~, + respectively. This is a critical issue when determining the + equivalence of two nicknames, or channel names. + +3.3 Messages + + Servers and clients send each other messages which may or may not + generate a reply. Most communication between servers do not generate + any reply, as servers mostly perform routing tasks for the clients. + + Each IRC message may consist of up to three main parts: the prefix + (OPTIONAL), the command, and the command parameters (maximum of + fifteen (15)). The prefix, command, and all parameters are separated + by one ASCII space character (0x20) each. + + The presence of a prefix is indicated with a single leading ASCII + colon character (':', 0x3b), which MUST be the first character of the + message itself. There MUST be NO gap (whitespace) between the colon + and the prefix. The prefix is used by servers to indicate the true + origin of the message. If the prefix is missing from the message, it + is assumed to have originated from the connection from which it was + received. Clients SHOULD not use a prefix when sending a message + from themselves; if they use one, the only valid prefix is the + registered nickname associated with the client. + + When a server receives a message, it MUST identify its source using + the (eventually assumed) prefix. If the prefix cannot be found in + the server's internal database, it MUST be discarded, and if the + prefix indicates the message comes from an (unknown) server, the link + from which the message was received MUST be dropped. Dropping a link + in such circumstances is a little excessive but necessary to maintain + the integrity of the network and to prevent future problems. Another + common error condition is that the prefix found in the server's + internal database identifies a different source (typically a source + registered from a different link than from which the message + arrived). If the message was received from a server link and the + prefix identifies a client, a KILL message MUST be issued for the + client and sent to all servers. In other cases, the link from which + the message arrived SHOULD be dropped for clients, and MUST be + dropped for servers. In all cases, the message MUST be discarded. + + The command MUST either be a valid IRC command or a three (3) digit + number represented in ASCII text. + + IRC messages are always lines of characters terminated with a CR-LF + (Carriage Return - Line Feed) pair, and these messages SHALL NOT + exceed 512 characters in length, counting all characters including + the trailing CR-LF. Thus, there are 510 characters maximum allowed + for the command and its parameters. There is no provision for + continuation message lines. See section 5 for more details about + current implementations. + +3.3.1 Message format in Augmented BNF + + The protocol messages must be extracted from the contiguous stream of + octets. The current solution is to designate two characters, CR and + LF, as message separators. Empty messages are silently ignored, + which permits use of the sequence CR-LF between messages without + extra problems. + + The extracted message is parsed into the components <prefix>, + <command> and list of parameters (<params>). + + The Augmented BNF representation for this is found in "IRC Client + Protocol" [IRC-CLIENT]. + + The extended prefix (["!" user "@" host ]) MUST NOT be used in server + to server communications and is only intended for server to client + messages in order to provide clients with more useful information + about who a message is from without the need for additional queries. + +3.4 Numeric replies + + Most of the messages sent to the server generate a reply of some + sort. The most common reply is the numeric reply, used for both + errors and normal replies. The numeric reply MUST be sent as one + message consisting of the sender prefix, the three digit numeric, and + the target of the reply. A numeric reply is not allowed to originate + from a client; any such messages received by a server are silently + dropped. In all other respects, a numeric reply is just like a normal + message, except that the keyword is made up of 3 numeric digits + rather than a string of letters. A list of different replies is + supplied in "IRC Client Protocol" [IRC-CLIENT]. + +4. Message Details + + All the messages recognized by the IRC server and client are + described in the IRC Client Protocol specification. + + Where the reply ERR_NOSUCHSERVER is returned, it means that the + target of the message could not be found. The server MUST NOT send + any other replies after this error for that command. + + The server to which a client is connected is required to parse the + complete message, returning any appropriate errors. If the server + encounters a fatal error while parsing a message, an error MUST be + sent back to the client and the parsing terminated. A fatal error + may follow from incorrect command, a destination which is otherwise + unknown to the server (server, client or channel names fit this + category), not enough parameters or incorrect privileges. + + If a full set of parameters is presented, then each MUST be checked + for validity and appropriate responses sent back to the client. In + the case of messages which use parameter lists using the comma as an + item separator, a reply MUST be sent for each item. + + In the examples below, some messages appear using the full format: + + :Name COMMAND parameter list + + Such examples represent a message from "Name" in transit between + servers, where it is essential to include the name of the original + sender of the message so remote servers may send back a reply along + the correct path. + + The message details for client to server communication are described + in the "IRC Client Protocol" [IRC-CLIENT]. Some sections in the + following pages apply to some of these messages, they are additions + to the message specifications which are only relevant to server to + + server communication, or to the server implementation. The messages + which are introduced here are only used for server to server + communication. + +4.1 Connection Registration + + The commands described here are used to register a connection with + another IRC server. + +4.1.1 Password message + + Command: PASS + Parameters: <password> <version> <flags> [<options>] + + The PASS command is used to set a 'connection password'. The + password MUST be set before any attempt to register the connection is + made. Currently this means that servers MUST send a PASS command + before any SERVER command. Only one (1) PASS command SHALL be + accepted from a connection. + + The last three (3) parameters MUST be ignored if received from a + client (e.g. a user or a service). They are only relevant when + received from a server. + + The <version> parameter is a string of at least four (4) characters, + and up to fourteen (14) characters. The first four (4) characters + MUST be digits and indicate the protocol version known by the server + issuing the message. The protocol described by this document is + version 2.10 which is encoded as "0210". The remaining OPTIONAL + characters are implementation dependent and should describe the + software version number. + + The <flags> parameter is a string of up to one hundred (100) + characters. It is composed of two substrings separated by the + character "|" (%x7C). If present, the first substring MUST be the + name of the implementation. The reference implementation (See + Section 8, "Current support and availability") uses the string "IRC". + If a different implementation is written, which needs an identifier, + then that identifier should be registered through publication of an + RFC. The second substring is implementation dependent. Both + substrings are OPTIONAL, but the character "|" is REQUIRED. The + character "|" MUST NOT appear in either substring. + + Finally, the last parameter, <options>, is used for link options. + The only options defined by the protocol are link compression (using + the character "Z"), and an abuse protection flag (using the character + + "P"). See sections 5.3.1.1 (Compressed server to server links) and + 5.3.1.2 (Anti abuse protections) respectively for more information on + these options. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_ALREADYREGISTRED + + Example: + + PASS moresecretpassword 0210010000 IRC|aBgH$ Z + +4.1.2 Server message + + Command: SERVER + Parameters: <servername> <hopcount> <token> <info> + + The SERVER command is used to register a new server. A new connection + introduces itself as a server to its peer. This message is also used + to pass server data over whole net. When a new server is connected + to net, information about it MUST be broadcasted to the whole + network. + + The <info> parameter may contain space characters. + + <hopcount> is used to give all servers some internal information on + how far away each server is. Local peers have a value of 0, and each + passed server increments the value. With a full server list, it + would be possible to construct a map of the entire server tree, but + hostmasks prevent this from being done. + + The <token> parameter is an unsigned number used by servers as an + identifier. This identifier is subsequently used to reference a + server in the NICK and SERVICE messages sent between servers. Server + tokens only have a meaning for the point-to-point peering they are + used and MUST be unique for that connection. They are not global. + + The SERVER message MUST only be accepted from either (a) a connection + which is yet to be registered and is attempting to register as a + server, or (b) an existing connection to another server, in which + case the SERVER message is introducing a new server behind that + server. + + Most errors that occur with the receipt of a SERVER command result in + the connection being terminated by the destination host (target + SERVER). Because of the severity of such event, error replies are + usually sent using the "ERROR" command rather than a numeric. + + If a SERVER message is parsed and it attempts to introduce a server + which is already known to the receiving server, the connection, from + which that message arrived, MUST be closed (following the correct + procedures), since a duplicate route to a server has been formed and + the acyclic nature of the IRC tree breaks. In some conditions, the + connection from which the already known server has registered MAY be + closed instead. It should be noted that this kind of error can also + be the result of a second running server, problem which cannot be + fixed within the protocol and typically requires human intervention. + This type of problem is particularly insidious, as it can quite + easily result in part of the IRC network to be isolated, with one of + the two servers connected to each partition therefore making it + impossible for the two parts to unite. + + Numeric Replies: + + ERR_ALREADYREGISTRED + + Example: + + SERVER test.oulu.fi 1 1 :Experimental server ; New server + test.oulu.fi introducing itself and + attempting to register. + + :tolsun.oulu.fi SERVER csd.bu.edu 5 34 :BU Central Server ; Server + tolsun.oulu.fi is our uplink for + csd.bu.edu which is 5 hops away. The + token "34" will be used by + tolsun.oulu.fi when introducing new + users or services connected to + csd.bu.edu. + +4.1.3 Nick + + Command: NICK + Parameters: <nickname> <hopcount> <username> <host> <servertoken> + <umode> <realname> + + This form of the NICK message MUST NOT be allowed from user + connections. However, it MUST be used instead of the NICK/USER pair + to notify other servers of new users joining the IRC network. + + This message is really the combination of three distinct messages: + NICK, USER and MODE [IRC-CLIENT]. + + The <hopcount> parameter is used by servers to indicate how far away + a user is from its home server. A local connection has a hopcount of + 0. The hopcount value is incremented by each passed server. + + The <servertoken> parameter replaces the <servername> parameter of + the USER (See section 4.1.2 for more information on server tokens). + + Examples: + + NICK syrk 5 kalt millennium.stealth.net 34 +i :Christophe Kalt ; New + user with nickname "syrk", username + "kalt", connected from host + "millennium.stealth.net" to server + "34" ("csd.bu.edu" according to the + previous example). + + :krys NICK syrk ; The other form of the NICK message, + as defined in "IRC Client Protocol" + [IRC-CLIENT] and used between + servers: krys changed his nickname to + syrk + +4.1.4 Service message + + Command: SERVICE + Parameters: <servicename> <servertoken> <distribution> <type> + <hopcount> <info> + + The SERVICE command is used to introduce a new service. This form of + the SERVICE message SHOULD NOT be allowed from client (unregistered, + or registered) connections. However, it MUST be used between servers + to notify other servers of new services joining the IRC network. + + The <servertoken> is used to identify the server to which the service + is connected. (See section 4.1.2 for more information on server + tokens). + + The <hopcount> parameter is used by servers to indicate how far away + a service is from its home server. A local connection has a hopcount + of 0. The hopcount value is incremented by each passed server. + + The <distribution> parameter is used to specify the visibility of a + service. The service may only be known to servers which have a name + matching the distribution. For a matching server to have knowledge + of the service, the network path between that server and the server + to which the service is connected MUST be composed of servers whose + names all match the mask. Plain "*" is used when no restriction is + wished. + + The <type> parameter is currently reserved for future usage. + + Numeric Replies: + + ERR_ALREADYREGISTRED ERR_NEEDMOREPARAMS + ERR_ERRONEUSNICKNAME + RPL_YOURESERVICE RPL_YOURHOST + RPL_MYINFO + + Example: + +SERVICE dict@irc.fr 9 *.fr 0 1 :French Dictionary r" registered on + server "9" is being announced to + another server. This service will + only be available on servers whose + name matches "*.fr". + +4.1.5 Quit + + Command: QUIT + Parameters: [<Quit Message>] + + A client session ends with a quit message. The server MUST close the + connection to a client which sends a QUIT message. If a "Quit + Message" is given, this will be sent instead of the default message, + the nickname or service name. + + When "netsplit" (See Section 4.1.6) occur, the "Quit Message" is + composed of the names of two servers involved, separated by a space. + The first name is that of the server which is still connected and the + second name is either that of the server which has become + disconnected or that of the server to which the leaving client was + connected: + + <Quit Message> = ":" servername SPACE servername + + Because the "Quit Message" has a special meaning for "netsplits", + servers SHOULD NOT allow a client to use a <Quit Message> in the + format described above. + + If, for some other reason, a client connection is closed without the + client issuing a QUIT command (e.g. client dies and EOF occurs on + socket), the server is REQUIRED to fill in the quit message with some + sort of message reflecting the nature of the event which caused it to + happen. Typically, this is done by reporting a system specific + error. + + Numeric Replies: + + None. + + Examples: + + :WiZ QUIT :Gone to have lunch ; Preferred message format. + +4.1.6 Server quit message + + Command: SQUIT + Parameters: <server> <comment> + + The SQUIT message has two distinct uses. + + The first one (described in "Internet Relay Chat: Client Protocol" + [IRC-CLIENT]) allows operators to break a local or remote server + link. This form of the message is also eventually used by servers to + break a remote server link. + + The second use of this message is needed to inform other servers when + a "network split" (also known as "netsplit") occurs, in other words + to inform other servers about quitting or dead servers. If a server + wishes to break the connection to another server it MUST send a SQUIT + message to the other server, using the name of the other server as + the server parameter, which then closes its connection to the + quitting server. + + The <comment> is filled in by servers which SHOULD place an error or + similar message here. + + Both of the servers which are on either side of the connection being + closed are REQUIRED to send out a SQUIT message (to all its other + server connections) for all other servers which are considered to be + behind that link. + + Similarly, a QUIT message MAY be sent to the other still connected + servers on behalf of all clients behind that quitting link. In + addition to this, all channel members of a channel which lost a + member due to the "split" MUST be sent a QUIT message. Messages to + channel members are generated by each client's local server. + + If a server connection is terminated prematurely (e.g., the server on + the other end of the link died), the server which detects this + disconnection is REQUIRED to inform the rest of the network that the + connection has closed and fill in the comment field with something + appropriate. + + When a client is removed as the result of a SQUIT message, the server + SHOULD add the nickname to the list of temporarily unavailable + nicknames in an attempt to prevent future nickname collisions. See + + section 5.7 (Tracking recently used nicknames) for more information + on this procedure. + + Numeric replies: + + ERR_NOPRIVILEGES ERR_NOSUCHSERVER + ERR_NEEDMOREPARAMS + + Example: + + SQUIT tolsun.oulu.fi :Bad Link ? ; the server link tolson.oulu.fi + has been terminated because of "Bad + Link". + + :Trillian SQUIT cm22.eng.umd.edu :Server out of control ; message + from Trillian to disconnect + "cm22.eng.umd.edu" from the net + because "Server out of control". + +4.2 Channel operations + + This group of messages is concerned with manipulating channels, their + properties (channel modes), and their contents (typically users). In + implementing these, a number of race conditions are inevitable when + users at opposing ends of a network send commands which will + ultimately clash. It is also REQUIRED that servers keep a nickname + history to ensure that wherever a <nick> parameter is given, the + server check its history in case it has recently been changed. + +4.2.1 Join message + + Command: JOIN + Parameters: <channel>[ %x7 <modes> ] + *( "," <channel>[ %x7 <modes> ] ) + + The JOIN command is used by client to start listening a specific + channel. Whether or not a client is allowed to join a channel is + checked only by the local server the client is connected to; all + other servers automatically add the user to the channel when the + command is received from other servers. + + Optionally, the user status (channel modes 'O', 'o', and 'v') on the + channel may be appended to the channel name using a control G (^G or + ASCII 7) as separator. Such data MUST be ignored if the message + wasn't received from a server. This format MUST NOT be sent to + clients, it can only be used between servers and SHOULD be avoided. + + The JOIN command MUST be broadcast to all servers so that each server + knows where to find the users who are on the channel. This allows + optimal delivery of PRIVMSG and NOTICE messages to the channel. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_BANNEDFROMCHAN + ERR_INVITEONLYCHAN ERR_BADCHANNELKEY + ERR_CHANNELISFULL ERR_BADCHANMASK + ERR_NOSUCHCHANNEL ERR_TOOMANYCHANNELS + ERR_TOOMANYTARGETS ERR_UNAVAILRESOURCE + RPL_TOPIC + + Examples: + + :WiZ JOIN #Twilight_zone ; JOIN message from WiZ + +4.2.2 Njoin message + + Command: NJOIN + Parameters: <channel> [ "@@" / "@" ] [ "+" ] <nickname> + *( "," [ "@@" / "@" ] [ "+" ] <nickname> ) + + The NJOIN message is used between servers only. If such a message is + received from a client, it MUST be ignored. It is used when two + servers connect to each other to exchange the list of channel members + for each channel. + + Even though the same function can be performed by using a succession + of JOIN, this message SHOULD be used instead as it is more efficient. + The prefix "@@" indicates that the user is the "channel creator", the + character "@" alone indicates a "channel operator", and the character + '+' indicates that the user has the voice privilege. + + Numeric Replies: + + ERR_NEEDMOREPARAMS ERR_NOSUCHCHANNEL + ERR_ALREADYREGISTRED + + Examples: + + :ircd.stealth.net NJOIN #Twilight_zone :@WiZ,+syrk,avalon ; NJOIN + message from ircd.stealth.net + announcing users joining the + #Twilight_zone channel: WiZ with + channel operator status, syrk with + voice privilege and avalon with no + privilege. + +4.2.3 Mode message + + The MODE message is a dual-purpose command in IRC. It allows both + usernames and channels to have their mode changed. + + When parsing MODE messages, it is RECOMMENDED that the entire message + be parsed first, and then the changes which resulted passed on. + + It is REQUIRED that servers are able to change channel modes so that + "channel creator" and "channel operators" may be created. + +5. Implementation details + + A the time of writing, the only current implementation of this + protocol is the IRC server, version 2.10. Earlier versions may + implement some or all of the commands described by this document with + NOTICE messages replacing many of the numeric replies. Unfortunately, + due to backward compatibility requirements, the implementation of + some parts of this document varies with what is laid out. One + notable difference is: + + * recognition that any LF or CR anywhere in a message marks + the end of that message (instead of requiring CR-LF); + + The rest of this section deals with issues that are mostly of + importance to those who wish to implement a server but some parts + also apply directly to clients as well. + +5.1 Connection 'Liveness' + + To detect when a connection has died or become unresponsive, the + server MUST poll each of its connections. The PING command (See "IRC + Client Protocol" [IRC-CLIENT]) is used if the server doesn't get a + response from its peer in a given amount of time. + + If a connection doesn't respond in time, its connection is closed + using the appropriate procedures. + +5.2 Accepting a client to server connection + +5.2.1 Users + + When a server successfully registers a new user connection, it is + REQUIRED to send to the user unambiguous messages stating: the user + identifiers upon which it was registered (RPL_WELCOME), the server + name and version (RPL_YOURHOST), the server birth information + (RPL_CREATED), available user and channel modes (RPL_MYINFO), and it + MAY send any introductory messages which may be deemed appropriate. + + In particular the server SHALL send the current user/service/server + count (as per the LUSER reply) and finally the MOTD (if any, as per + the MOTD reply). + + After dealing with registration, the server MUST then send out to + other servers the new user's nickname (NICK message), other + information as supplied by itself (USER message) and as the server + could discover (from DNS servers). The server MUST NOT send this + information out with a pair of NICK and USER messages as defined in + "IRC Client Protocol" [IRC-CLIENT], but MUST instead take advantage + of the extended NICK message defined in section 4.1.3. + +5.2.2 Services + + Upon successfully registering a new service connection, the server is + subject to the same kind of REQUIREMENTS as for a user. Services + being somewhat different, only the following replies are sent: + RPL_YOURESERVICE, RPL_YOURHOST, RPL_MYINFO. + + After dealing with this, the server MUST then send out to other + servers (SERVICE message) the new service's nickname and other + information as supplied by the service (SERVICE message) and as the + server could discover (from DNS servers). + +5.3 Establishing a server-server connection. + + The process of establishing a server-to-server connection is fraught + with danger since there are many possible areas where problems can + occur - the least of which are race conditions. + + After a server has received a connection following by a PASS/SERVER + pair which were recognized as being valid, the server SHOULD then + reply with its own PASS/SERVER information for that connection as + well as all of the other state information it knows about as + described below. + + When the initiating server receives a PASS/SERVER pair, it too then + checks that the server responding is authenticated properly before + accepting the connection to be that server. + +5.3.1 Link options + + Server links are based on a common protocol (defined by this + document) but a particular link MAY set specific options using the + PASS message (See Section 4.1.1). + +5.3.1.1 Compressed server to server links + + If a server wishes to establish a compressed link with its peer, it + MUST set the 'Z' flag in the options parameter to the PASS message. + If both servers request compression and both servers are able to + initialize the two compressed streams, then the remainder of the + communication is to be compressed. If any server fails to initialize + the stream, it will send an uncompressed ERROR message to its peer + and close the connection. + + The data format used for the compression is described by RFC 1950 + [ZLIB], RFC 1951 [DEFLATE] and RFC 1952 [GZIP]. + +5.3.1.2 Anti abuse protections + + Most servers implement various kinds of protections against possible + abusive behaviours from non trusted parties (typically users). On + some networks, such protections are indispensable, on others they are + superfluous. To require that all servers implement and enable such + features on a particular network, the 'P' flag is used when two + servers connect. If this flag is present, it means that the server + protections are enabled, and that the server REQUIRES all its server + links to enable them as well. + + Commonly found protections are described in sections 5.7 (Tracking + recently used nicknames) and 5.8 (Flood control of clients). + +5.3.2 State information exchange when connecting + + The order of state information being exchanged between servers is + essential. The REQUIRED order is as follows: + + * all known servers; + + * all known client information; + + * all known channel information. + + Information regarding servers is sent via extra SERVER messages, + client information with NICK and SERVICE messages and channels with + NJOIN/MODE messages. + + NOTE: channel topics SHOULD NOT be exchanged here because the TOPIC + command overwrites any old topic information, so at best, the two + sides of the connection would exchange topics. + + By passing the state information about servers first, any collisions + with servers that already exist occur before nickname collisions + caused by a second server introducing a particular nickname. Due to + the IRC network only being able to exist as an acyclic graph, it may + be possible that the network has already reconnected in another + location. In this event, the place where the server collision occurs + indicates where the net needs to split. + +5.4 Terminating server-client connections + + When a client connection unexpectedly closes, a QUIT message is + generated on behalf of the client by the server to which the client + was connected. No other message is to be generated or used. + +5.5 Terminating server-server connections + + If a server-server connection is closed, either via a SQUIT command + or "natural" causes, the rest of the connected IRC network MUST have + its information updated by the server which detected the closure. + The terminating server then sends a list of SQUITs (one for each + server behind that connection). (See Section 4.1.6 (SQUIT)). + +5.6 Tracking nickname changes + + All IRC servers are REQUIRED to keep a history of recent nickname + changes. This is important to allow the server to have a chance of + keeping in touch of things when nick-change race conditions occur + with commands manipulating them. Messages which MUST trace nick + changes are: + + * KILL (the nick being disconnected) + + * MODE (+/- o,v on channels) + + * KICK (the nick being removed from channel) + + No other commands need to check nick changes. + + In the above cases, the server is required to first check for the + existence of the nickname, then check its history to see who that + nick now belongs to (if anyone!). This reduces the chances of race + conditions but they can still occur with the server ending up + affecting the wrong client. When performing a change trace for an + above command it is RECOMMENDED that a time range be given and + entries which are too old ignored. + + For a reasonable history, a server SHOULD be able to keep previous + nickname for every client it knows about if they all decided to + change. This size is limited by other factors (such as memory, etc). + +5.7 Tracking recently used nicknames + + This mechanism is commonly known as "Nickname Delay", it has been + proven to significantly reduce the number of nickname collisions + resulting from "network splits"/reconnections as well as abuse. + + In addition of keeping track of nickname changes, servers SHOULD keep + track of nicknames which were recently used and were released as the + result of a "network split" or a KILL message. These nicknames are + then unavailable to the server local clients and cannot be re-used + (even though they are not currently in use) for a certain period of + time. + + The duration for which a nickname remains unavailable SHOULD be set + considering many factors among which are the size (user wise) of the + IRC network, and the usual duration of "network splits". It SHOULD + be uniform on all servers for a given IRC network. + +5.8 Flood control of clients + + With a large network of interconnected IRC servers, it is quite easy + for any single client attached to the network to supply a continuous + stream of messages that result in not only flooding the network, but + also degrading the level of service provided to others. Rather than + require every 'victim' to provide their own protection, flood + protection was written into the server and is applied to all clients + except services. The current algorithm is as follows: + + * check to see if client's `message timer' is less than current time + (set to be equal if it is); + + * read any data present from the client; + + * while the timer is less than ten (10) seconds ahead of the current + time, parse any present messages and penalize the client by two (2) + seconds for each message; + + * additional penalties MAY be used for specific commands which + generate a lot of traffic across the network. + + This in essence means that the client may send one (1) message every + two (2) seconds without being adversely affected. Services MAY also + be subject to this mechanism. + +5.9 Non-blocking lookups + + In a real-time environment, it is essential that a server process + does as little waiting as possible so that all the clients are + serviced fairly. Obviously this requires non-blocking IO on all + network read/write operations. For normal server connections, this + was not difficult, but there are other support operations that may + cause the server to block (such as disk reads). Where possible, such + activity SHOULD be performed with a short timeout. + +5.9.1 Hostname (DNS) lookups + + Using the standard resolver libraries from Berkeley and others has + meant large delays in some cases where replies have timed out. To + avoid this, a separate set of DNS routines were written for the + current implementation. Routines were setup for non-blocking IO + operations with local cache, and then polled from within the main + server IO loop. + +5.9.2 Username (Ident) lookups + + Although there are numerous ident libraries (implementing the + "Identification Protocol" [IDENT]) for use and inclusion into other + programs, these caused problems since they operated in a synchronous + manner and resulted in frequent delays. Again the solution was to + write a set of routines which would cooperate with the rest of the + server and work using non-blocking IO. + +6. Current problems + + There are a number of recognized problems with this protocol, all of + which are hoped to be solved sometime in the near future during its + rewrite. Currently, work is underway to find working solutions to + these problems. + +6.1 Scalability + + It is widely recognized that this protocol does not scale + sufficiently well when used in a large arena. The main problem comes + from the requirement that all servers know about all other servers + and clients and that information regarding them be updated as soon as + it changes. It is also desirable to keep the number of servers low + so that the path length between any two points is kept minimal and + the spanning tree as strongly branched as possible. + +6.2 Labels + + The current IRC protocol has 4 types of labels: the nickname, the + channel name, the server name and the service name. Each of the four + types has its own domain and no duplicates are allowed inside that + domain. Currently, it is possible for users to pick the label for + any of the first three, resulting in collisions. It is widely + recognized that this needs reworking, with a plan for unique names + for nicks that don't collide being desirable as well as a solution + allowing a cyclic tree. + +6.2.1 Nicknames + + The idea of the nickname on IRC is very convenient for users to use + when talking to each other outside of a channel, but there is only a + finite nickname space and being what they are, it's not uncommon for + several people to want to use the same nick. If a nickname is chosen + by two people using this protocol, either one will not succeed or + both will be removed by use of KILL (See Section 3.7.1 of "IRC Client + Protocol" [IRC-CLIENT]). + +6.2.2 Channels + + The current channel layout requires that all servers know about all + channels, their inhabitants and properties. Besides not scaling + well, the issue of privacy is also a concern. A collision of + channels is treated as an inclusive event (people from both nets on + channel with common name are considered to be members of it) rather + than an exclusive one such as used to solve nickname collisions. + + This protocol defines "Safe Channels" which are very unlikely to be + the subject of a channel collision. Other channel types are kept for + backward compatibility. + +6.2.3 Servers + + Although the number of servers is usually small relative to the + number of users and channels, they too are currently REQUIRED to be + known globally, either each one separately or hidden behind a mask. + +6.3 Algorithms + + In some places within the server code, it has not been possible to + avoid N^2 algorithms such as checking the channel list of a set of + clients. + + In current server versions, there are only few database consistency + checks, most of the time each server assumes that a neighbouring + server is correct. This opens the door to large problems if a + connecting server is buggy or otherwise tries to introduce + contradictions to the existing net. + + Currently, because of the lack of unique internal and global labels, + there are a multitude of race conditions that exist. These race + conditions generally arise from the problem of it taking time for + messages to traverse and effect the IRC network. Even by changing to + unique labels, there are problems with channel-related commands being + disrupted. + +7. Security Considerations + +7.1 Authentication + + Servers only have two means of authenticating incoming connections: + plain text password, and DNS lookups. While these methods are weak + and widely recognized as unsafe, their combination has proven to be + sufficient in the past: + + * public networks typically allow user connections with only few + restrictions, without requiring accurate authentication. + + * private networks which operate in a controlled environment often + use home-grown authentication mechanisms not available on the + internet: reliable ident servers [IDENT], or other proprietary + mechanisms. + + The same comments apply to the authentication of IRC Operators. + + It should also be noted that while there has been no real demand over + the years for stronger authentication, and no real effort to provide + better means to safely authenticate users, the current protocol + offers enough to be able to easily plug-in external authentication + methods based on the information that a client can submit to the + server upon connection: nickname, username, password. + +7.2 Integrity + + Since the PASS and OPER messages of the IRC protocol are sent in + clear text, a stream layer encryption mechanism (like "The TLS + Protocol" [TLS]) could be used to protect these transactions. + +8. Current support and availability + + Mailing lists for IRC related discussion: + General discussion: ircd-users@irc.org + Protocol development: ircd-dev@irc.org + + Software implementations: + ftp://ftp.irc.org/irc/server + ftp://ftp.funet.fi/pub/unix/irc + ftp://coombs.anu.edu.au/pub/irc + + Newsgroup: alt.irc + +9. Acknowledgements + + Parts of this document were copied from the RFC 1459 [IRC] which + first formally documented the IRC Protocol. It has also benefited + from many rounds of review and comments. In particular, the + following people have made significant contributions to this + document: + + Matthew Green, Michael Neumayer, Volker Paulsen, Kurt Roeckx, Vesa + Ruokonen, Magnus Tjernstrom, Stefan Zehl. + +10. References + + [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [ABNF] Crocker, D. and P. Overell, "Augmented BNF for Syntax + Specifications: ABNF", RFC 2234, November 1997. + + [IRC] Oikarinen, J. and D. Reed, "Internet Relay Chat + Protocol", RFC 1459, May 1993. + + [IRC-ARCH] Kalt, C., "Internet Relay Chat: Architecture", RFC 2810, + April 2000. + + [IRC-CLIENT] Kalt, C., "Internet Relay Chat: Client Protocol", RFC + 2812, April 2000. + + [IRC-CHAN] Kalt, C., "Internet Relay Chat: Channel Management", RFC + 2811, April 2000. + + [ZLIB] Deutsch, P. and J-L. Gailly, "ZLIB Compressed Data + Format Specification version 3.3", RFC 1950, May 1996. + + [DEFLATE] Deutsch, P., "DEFLATE Compressed Data Format + Specification version 1.3", RFC 1951, May 1996. + + [GZIP] Deutsch, P., "GZIP file format specification version + 4.3", RFC 1952, May 1996. + + [IDENT] St. Johns, M., "The Identification Protocol", RFC 1413, + February 1993. + + [TLS] Dierks, T. and C. Allen, "The TLS Protocol", RFC 2246, + January 1999. + +11. Author's Address + + Christophe Kalt + 99 Teaneck Rd, Apt #117 + Ridgefield Park, NJ 07660 + USA + + EMail: kalt@stealth.net + +12. Full Copyright Statement + + Copyright (C) The Internet Society (2000). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. diff --git a/doc/technical/send.txt b/doc/technical/send.txt new file mode 100644 index 0000000..38fd916 --- /dev/null +++ b/doc/technical/send.txt @@ -0,0 +1,262 @@ +PREFIXES +======== + + Server prefixes are the ":%s" strings at the beginning of messages. +They are used by servers to route the message properly and by servers to +local clients to update their idea of who is whom. + +":nick!user@host" is a prefix ":name" where name is either a nick +or name of a server is another valid prefix. + +Typical prefix for a local client to a channel: + +":Dianora!db@irc.db.net" + +for a prefix to a remote server: +":Dianora" + +e.g. as seen locally on a channel: + +":Dianora!db@irc.db.net PRIVMSG #us-opers :ON TOP OF ...\r\n" + +e.g. as seen sent to a remote server: +":Dianora PRIVMSG #us-opers :ON TOP OF ...\r\n" + + It has been argued that full prefixes sent locally are a waste of bandwidth +(Isomer from Undernet has argued this). i.e. instead of sending: +":nick!user@host" for a local prefix, one could just send ":nick".. +Unfortunately, this breaks many clients badly. Personally I feel that +until clients are updated to understand that a full prefix isn't always +going to be sent, that this should be held off on. + + As much as possible, prefix generation is now moved "upstairs" as +much as possible. i.e. if its known its a local client only, then the +onus of the prefix generation, is the users, not hidden in send.c +This allows somewhat faster code to be written, as the prefix doesn't +have to be regenerated over and over again. + + Prefixes aren't sent in all cases, such as a new user using NICK +A prefix is needed when it must be routed. + +i.e. + +NICK newnick + + There is obviously no prefix needed from a locally connected client. + + + +FUNCTIONS +========= + +sendto_one() - Should be used for _local_ clients only + it expects the prefix to be pre-built by user. + + usage - sendto_one(struct Client *to, char *pattern, ...); + + typical use: + + sendto_one(acptr,":%s NOTICE %s :I'm tired", me.name); + Note: This was from a server "me" hence only one + name in prefix. + + This would be an example of a client sptr, noticing + acptr IF acptr is known to be a local client: + + sendto_one(acptr,":%s!%s@%s NOTICE %s :You there?", + sptr->name, + sptr->username, + sptr->host, + acptr->name); + +sendto_channel_butone() + - This function sends a var args message to a channel globally, + except to the client specified as "one", the prefix + is built by this function on the fly as it has to + be sent both to local clients on this server and to + remote servers. +D clients are omitted, as this is used + only for PRIVMSG/NOTICE. + + usage - sendto_channel_butone(struct Client *one, + struct Client *from, + struct Channel *chptr, + const char *pattern, ... ); + + sendto_channel_butone(cptr, sptr, chptr + "PRIVMSG %s :HI!", + chptr->chname); + + e.g. if channel message is coming from "cptr" + it must not be sent back to cptr. + + +sendto_ll_serv_butone(struct Client *one, struct Client *sptr, int add, + const char *pattern, ...) + + - This function is almost identical to sendto_channel_butone + however, it will also not send on a nick as given by sptr, + if target server does not "know" about it. + As the name implies, it is used for "lazylinks" + +sendto_server() + - This function sends specified var args message + to all connected servers except the client "one" + - chptr can be NULL, in which case it goes to server + - caps is a set of CAPS to send =to= + - nocaps is a set of CAPS to not send =to= + + usage - sendto_server(struct Client *one, + struct Channel *chptr, + unsigned long caps, + unsigned long nocaps, + unsigned long llflags, + const char *pattern, ... ); + + +sendto_common_channels_local() + - This function is used only by m_nick and exit_one_client + its used to propagate nick changes to all channels user + is in, and QUIT messages to all channels user is in. + As it only sends to local clients, prefix generation + is left to the user. It also sends the message to the + user if the user isn't on any channels. + + usage - sendto_common_channels_local(struct Client *user, + const char *pattern, + ...); + +sendto_channel_local() + - This function is used only to send locally, never + to remote servers. This is useful when removing + local chanops, or adding a local chanop. MODE/SJOIN + sent to remote server allows that server to propagate + mode changes to its clients locally. If nodeaf is YES, + +D clients are omitted (used for delivering WALLCHOPS). + + usage - sendto_channel_local(type, nodeaf, + struct Channel *chptr, + const char *pattern, ... ); + + + prefix must be pre-built. type is a flag + denoting ONE of + ALL_MEMBERS - all members locally are sent to + NON_CHANOPS - only non-chanops see this + ONLY_CHANOPS_VOICED - both chanops and voiced see this + ONLY_CHANOPS - only chanops see this + + +sendto_match_butone() +match_it() - both only used for the old style oper masking + i.e. /msg #hostmask which in hyb7 is /msg $#hostmask + or /msg $servermask in hyb7 /msg $$servermask + + usage - match_it(struct Client *one, + const char *mask, + int what); + + one is the client to match on either hostmask or servermask + mask is the actual mask + what is either MATCH_HOST or MATCH_SERVER + + usage - sendto_match_butone(struct Client *one, + struct Client *from, + char *mark, + int what, + const char *pattern, ... ); + +sendto_channel_remote() + - Is only used to send a message to a remote server + + +sendto_match_cap_servs() + - Is used only to send MODE lists to remote server + who are capable of it. i.e. MODE #channel +e nick!user@host + +sendto_match_noncap_servs() + - Is used only to send MODE lists to remote servers that + are not capable of it. i.e. MODE #channel +o nick + - This allows you to send a MODE #channel +h nick via + sendto_match_cap_servs and MODE #channel +o nick to + servers which don't support it. + +sendto_anywhere() + - Allows the sending of a message to any client on the net + without knowing whether its local or remote. The penalty + is the calculation of a run-time prefix. + It is less efficient then sendto_one() + + usage - sendto_anywhere(struct Client *to, + struct Client *from, + const char *pattern, ...); + + e.g. + sendto_anywhere(acptr, sptr, + "PRIVMSG Larz :Hi, Where ever you are"); + +sendto_realops_flags() + - combines old sendto_realops and sendto_realops_flags + sends specified message to opers locally only + depending on two flags, UMODE i.e. +y +d or UMODE_SERVNOTICE + or special case, UMODE_ALL (see client.h UMODE flags ) + to send to any oper. The second flag gives the level + of whom to send the messages to, OPERS, ADMINS only or both. + (See send.h for those flags) + + usage - sendto_realops_flags(int umode, int level, + const char *pattern, ... ); + + e.g. + sendto_realops_flags(UMODE_ALL, L_ALL, + "Don't eat the yellow snow"); + +sendto_wallops_flags() + - sends specified message to opers locally, + depending on flags. used for messages that need + to be in wallops form + + usage - sendto_wall_flags(int flags, + struct Client *, const char *patterm ...); + + e.g. + sendto_wallops_flags(UMODE_WALLOP, + sptr, "Message"); + +ts_warn() - Only used to send warning messages to all opers + without flooding them with warnings. + It limits the number of warnings to no more than 5 + every 5 seconds. It probably can go away now. + + usage - ts_warn(const char *pattern, ... ); + +*** LOCAL HELPER FUNCTIONS (static) *** + +send_format() - Used to format a varargs buffer into given buffer + returns length of buffer built, enforces RFC1459 length + limits and appends \r\n as per rfc. + + usage - send_format(char *sendbuf, + const char *pattern, ... ); + +send_message() + - This local function does the actual send of message + + usage: send_message(struct Client *to, char *msg, int len); + + The message has to be pre-formatted and the length + must be pre-calculated. + +send_message_remote() + - This local function does the actual send of message to + remote clients + + usage: send_message_remote(struct Client *to, + struct Client *from, char *msg, int len); + + The message has to be pre-formatted and the length + must be pre-calculated. + + +-- Diane Bruce + +$Id$ diff --git a/doc/technical/ts3.txt b/doc/technical/ts3.txt new file mode 100644 index 0000000..e2f4927 --- /dev/null +++ b/doc/technical/ts3.txt @@ -0,0 +1,321 @@ +$Id$ + Protocol changes for +TSora + --------------------------- + +Note: + +The protocols described here implement TimeStamps on IRC channels and +nicks. The idea of IRC TimeStamps was started on Undernet, and first +implemented by Run <carlo@runaway.xs4all.nl>. The protocols used here +are not exactly the same as the ones used on Undernet; the nick-kill +handling is very similar and must be credited to Run, while the +"TimeStamped channel description" protocol is quite different. + +TSora servers keep track of which version of the TS protocol (if any) +their neighboring servers are using, and take it into account when +sending messages to them. This allows for seamless integration of TS +servers into a non-TS net, and for upgrades of the protocol. + +Each server knows which is the lowest and the highest version of the +TS protocol it can interact with; currently both of these are set to 1: + +#define TS_CURRENT 1 /* the highest TS ver we can do */ +#define TS_MIN 1 /* the lowest TS ver we can do */ + +Timings and TS versions: +======================== + +. Keep a 'delta' value to be added to the result of all calls to time(), + initially 0. + +. Send a second argument to the PASS command, ending in the 'TS' string. + +. Send a + + SVINFO <TS_CURRENT> <TS_MIN> <STANDALONE> :<UTC-TIME> + + just after "SERVER", where <STANDALONE> is 1 if we're connected to + more TSora servers, and 0 if not, and <UTC-TIME> is our idea of the + current UTC time, fixed with the delta. + +. When we receive a "SVINFO <x> <y> <z> :<t>" line from a connecting + server, we ignore it if TS_CURRENT<y or x<TS_MIN, otherwise we + set a flag remembering that that server is TS-aware, remember the TS + version to use with it (min(TS_CURRENT, x)). Additionally, if this is + our first connected TS server, we set our delta to t-<OUR_UTC> if + z==0, and to (t-<OUR_UTC>)/2 if z!=0. The SVINFO data is kept around + until the server has effectively registered with SERVER, and used + *after* sending our own SVINFO to that server. + +Explanations: + + Servers will always know which of their directly-linked servers can do + TS, and will use the TS protocol only with servers that do understand + it. This makes it possible to switch to full TS in just one + code-replacement step, without incompatibilities. + + As long as not all servers are TS-aware, the net will be divided into + "zones" of linked TS-aware servers. Channel modes will be kept + synchronized at least within the zone in which the channel was + created, and nick collisions between servers in the same zone will + result in only one client being killed. + + Time synchronization ensures that servers have the same idea of the + current time, and achieves this purpose as long as TS servers are + introduced one by one within the same 'zone'. The merging of two zones + cannot synchronize them completely, but it is to be expected that + within each zone the effective time will be very close to the real + time. + + By sending TSINFO after SERVER rather than before, we avoid the extra + lag created by the identd check on the server. To be able to send + immediately a connect burst of either type (TS or not), we need to + know before that if the server does TS or not, so we send that + information with PASS as an extra argument. And to avoid being + incompatible with 2.9 servers, which check that this second argument + begins with "2.9", we check that it *ends* with "TS". + + The current time is only used when setting a TS on a new channel or + nick, and once such a TS is set, it is never modified because of + synchronization, as it is much more important that the TS for a + channel or nick stays the same across all servers than that it is + accurate to the second. + + Note that Undernet's 2.8.x servers have no time synchronization at + all, and have had no problems because of it - all of this is more to + catch the occasional server with a way-off clock than anything. + +NICK handling patches (anti-nick-collide + shorter connect burst): +================================================================== + +. For each nick, store a TS value = the TS value received if any, or our + UTC+delta at the time we first heard of the nick. TS's are propagated + to TS-aware servers whenever sending a NICK command. + +. Nick changes reset the TS to the current time. + +. When sending a connect burst to another TS server, replace the + NICK/USER pair with only one NICK command containing the nick, the + hopcount, the TS, the umode, and all the USER information. + + The format for a full NICK line is: + NICK <nick> <hops> <TS> <umode> <user> <host> <server> :<ircname> + + The umode is a + followed by any applying usermodes. + + The format for a nick-change NICK line is: + :<oldnick> NICK <newnick> :<TS> + +. When a NICK is received from a TS server, that conflicts with an + existing nick: + + if the userhosts differ or one is not known: + * if the timestamps are equal, kill ours and the old one if it + was a nick change + * if the incoming timestamp is older than ours, kill ours and + propagate the new one + * if the incoming timestamp is younger, ignore the line, but kill + the old nick if it was a nick change + + if the userhosts are the same: + * if the timestamps are equal, kill ours and the old one if it + was a nick change + * if the incoming timestamp is younger, kill ours and propagate + the new one + * if the incoming timestamp is older, ignore the line but kill + the old nick if it was a nick change + +. When a NICK is received from a non-TS server that conflicts with + an existing nick, kill both. + +. Do not send "Fake Prefix" kills in response to lines coming from TS + servers; the sanitization works anyway, and this allows the "newer + nick overruled" case to work. + +Explanations: + + The modified nick-introduction syntax allows for a slightly shorter + connect-burst, and most importantly lets the server compare + user@host's when determining which nick to kill: if the user@host + is the same, then the older nick must be killed rather than the + newer. + + When talking to a non-TS server, we need to behave exactly like one + because it expects us to. When talkign to a TS server, we don't kill + the nicks it's introducing, as we know it'll be smart enough to do it + itself when seeing our own introduced nick. + + When we see a nick arriving from a non-TS server, it won't have a TS, + but it's safe enough to give it the current time rather than keeping + it 0; such TS's won't be the same all across the network (as long as + there is more than one TS zone), and when there's a collision, the TS + used will be the one in the zone the collision occurs in. + + Also, it is important to note that by the time a server sees (and + chooses to ignore) a nick introduction, the introducing server has + also had the time to put umode changes for that nick on its queue, so + we must ignore them too... so we need to ignore fake-prefix lines + rather than sending kills for them. This is safe enough, as the rest + of the protocol ensures that they'll get killed anyway (and the + Undernet does it too, so it's been more than enough tested). Just for + an extra bit of compatibility, we still kill fake prefixes coming from + non-TS servers. + + This part of the TS protocol is almost exactly the same as the + Undernet's .anc (anti-nick-collide) patches, except that Undernet + servers don't add usermodes to the NICK line. + +TimeStamped channel descriptions (avoiding hacked ops and desynchs): +==================================================================== + +. For each channel, keep a timestamp, set to the current time when the + channel is created by a client on the local server, or to the received + value if the channel has been propagated from a TS server, or to 0 + otherwise. This value will have the semantics of "the time of creation + of the current ops on the channel", and 0 will mean that the channel + is in non-TS mode. + + A new server protocol command is introduced, SJOIN, which introduces + a full channel description: a timestamp, all the modes (except bans), + and the list of channel members with their ops and voices. This + command will be used instead of JOIN and of (most) MODEs both in + connect bursts and when propagating channel creations among TS + servers. SJOIN will never be accepted from or sent to users. + + The syntax for the command is: + + SJOIN <TS> #<channel> <modes> :[@][+]<nick_1> ... [@][+]<nick_n> + + The fields have the following meanings: + + * <TS> is the timestamp for the channel + + * <modes> is the list of global channel modes, starting with a + + and a letter for each of the active modes (spmntkil), followed + by an argument for +l if there is a limit, and an argument for + +k if there's a key (in the same order they were mentioned in + the string of letters). + + A channel with no modes will have a "+" in that field. + + A special value of "0" means that the server does not specify the + modes, and will be used when more than one SJOIN line is needed + to completely describe a channel, or when propagating a SJOIN + the modes of which were rejected. + + * Each nick is preceded by a "@" if the user has ops, and a "+" if + the user has a voice. For mode +ov, both flags are used. + + SJOINs will be propagated (when appropriate) to neighboring TS + servers, and converted to JOINs and MODEs for neighboring non-TS + servers. + + To propagate channels for which not all users fit in one + SJOIN line, several SJOINs will be sent consecutively, only the first + one including actual information in the <mode> field. + + An extra ad-hoc restriction is imposed on SJOIN messages, to simplify + processing: if a channel has ops, then the first <nick> of the first + SJOIN sent to propagate that channel must be one of the ops. + + Servers will never attempt to reconstruct a SJOIN from JOIN/MODE + information being received at the moment from other servers. + +. For each user on a channel, keep an extra flag (like ops and voice) + that is set when the user has received channel ops from another + server (in a SJOIN channel description), which we rejected (ignored). + Mode changes (but NOT kicks) coming from a TS server and from someone + with this flag set will be ignored. The flag will be reset when the + user gets ops from another user or server. + +. On deops done by non-local users, coming from TS servers, on channels + with a non-zero TS, do not check that the user has ops but check that + their 'deopped' flag is not set. For kicks coming from a TS server, do + not check either. This will avoid desynchs, and 'bad' modechanges are + avoided anyway. Other mode changes will still only be taken into + account and propagated when done by users that are seen as having ops. + +. When a MODE change that ops someone is received from a server for a + channel, that channel's TS is set to 0, and the mode change is + propagated. + +. When a SJOIN is received for a channel, deal with it in this way: + * received-TS = 0: + + if we have ops or the SJOIN doesn't op anyone, SJOIN propagated + with our own TS. + + otherwise, TS set to 0 and SJOIN propagated with 0. + * received-TS > 0, own-TS = 0: + + if the SJOIN ops someone or we don't have ops, set our TS to the + received TS and propagate. + + otherwise, propagate with TS = 0. + * received-TS = own-TS: propagate. + * received-TS < own-TS: + + if the SJOIN ops someone, remove *all* modes (except bans) from + the channel and propagate these mode changes to all neighboring + non-TS servers, and copy the received TS and propagate the SJOIN. + + if the SJOIN does not op anyone and we have ops, propagate + with our own TS. + + otherwise, copy the received TS and propagate the SJOIN. + * received-TS > own-TS: + + if the SJOIN does not introduce any ops, process and propagate + with our own TS. + + if we have ops: for each person the mode change would op, set the + 'deopped' flag; process all the JOINs ignoring the '@' and '+' + flags; propagate without the flags and with our TS. + + if we don't have ops: set our TS to the received one, propagate + with the flags. + +Explanations: + + This part of the protocol is the one that is most different (and + incompatible) with the Undernet's: we never timestamp MODE changes, + but instead we introduce the concept of time-stamped channel + descriptions. This way each server can determine, based on its state + and the received description, what the correct modes for a channel + are, and deop its own users if necessary. With this protocol, there is + *never* the need to reverse and bounce back a mode change. This is + both faster and more bandwith-effective. + + The end goal is to have a protocol will eventually protect channels + against hacked ops, while minimizing the impact on a mixed-server net. + In order to do this, whenever there is a conflict between a TS server + and a non-TS one, the non-TS one's idea of the whole situation + prevails. This means that channels will only have a TS when they have + been created on a TS-aware server, and will lose it whenever a server + op comes from a non-TS server. Also, at most one 'zone' will have a TS + for any given channel at any given time, ensuring that there won't be + any deops when zones are merged. However, when TS zones are merged, if + the side that has a TS also has ops, then the TS is kept across the + whole new zone. Effective protection will only be ensured once all + servers run TS patches and channels have been re-created, as there is + no way servers can assign a TS to a channel they are not creating + (like they do with nicks) without having unwanted deops later. + + The visible effects of this timestamped channel-description protocol + are that when a split rejoins, and one side has hacked ops, the other + side doesn't see any server mode changes (just like with Undernet's + TS), but the side that has hacked ops sees: + + * first the first server on the other side deopping and devoicing + everyone, and fixing the +spmntkli modes + * then other users joining, and getting server ops and voices + + The less obvious part of this protocol is its behavior in the case + that the younger side of a rejoin has servers that are lagged with + each other. In such a situation, a SJOIN that clears all modes and + sets the legitimate ones is being propagated from one server, and + lagged illegitimate mode changes and kicks are being propagated in the + opposite direction. In this case, a kick done by someone who is being + deopped by the SJOIN must be taken into account to keep the name list + in sync (and since it can only be kicking someone who also was on the + younger side), while a deop does not matter (and will be ignored by + the first server on the other side), and an opping *needs* to be + discareded to avoid hacked ops. + + The main property of timestamped channel descriptions that makes them + a very stable protocol even with lag and splits, is that they leave a + server in the same final state, independently of the order in which + channel descriptions coming from different servers are received. Even + when SJOINs and MODEs for the same channel are being propagated in + different direction because of several splits rejoining, the final + state will be the same, independently of the exact order in which each + server received the SJOINs, and will be the same across all the + servers in the same zone. diff --git a/doc/technical/ts5.txt b/doc/technical/ts5.txt new file mode 100644 index 0000000..de10506 --- /dev/null +++ b/doc/technical/ts5.txt @@ -0,0 +1,147 @@ + Overview of the TS5 system + Lee H <lee@leeh.co.uk> + +$Id$ + +For the purposes of this document, ircd versions: + hybrid6.0 + ircd-comstud-1.12 + CSr31pl4 + +and prior, are TS3. + +ircd-hybrid-6.2 and later support TS5. + +Whats TS5? +---------- + +The difference between TS5 and TS3 is what happened on opless channels. TS +works by establishing which server has the oldest version of the channel, +the version that is oldest, keeps its modes and ops, the version that is +youngest, removes their modes and ops, and accepts the older version. + +There was an exception to this rule with opless channels, if a channel was +opless, TS3 would allow anybody to keep their ops and modes on the channel. +TS5 aims to stop this, by removing this exception. + +Example1: + +An irc network, with server A (every server is ts3) + +UserA is on ServerA, in channel #broken. This channel is opless, and has a +TS of 800000000. ServerA splits, and whilst it is split, UserA cycles +channel #broken, recreates the channel and is given ops. On ServerA #broken +now has a TS of 900000000 and has ops. ServerA rejoins with the network, +via HubB. HubB realises #broken is opless, so allows UserA to retain ops. +The TS is moved forward to 900000000. + +The network now sees #broken as having a TS of 900000000, with UserA being +opped. + +Example2: + +An irc network, with server C (every server is ts5) + +Same scenario as above. ServerC splits and UserC cycles channel #broken, +recreating it with a TS of 900000000. ServerC rejoins with the network via +HubD. HubD realises #broken has a TS of 800000000 locally, and ServerC is +showing a TS of 900000000, it ignores ServerC's modes and ops. The channel +remains opless. ServerC receives HubD's modes, and it notices HubD has a +lower TS of channel #broken. It removes UserC's ops, removes the channel +modes on #broken, and accepts HubD's status. + +The network version of #broken hasnt changed. It is still opless, with a TS +of 800000000. + + +As you can see, TS5 makes splitting a server to regain ops useless, as it +cannot be abused to give ops after a netsplit. + +The problem with TS5 however, is what happens on a mixed TS5/TS3 network. +Channels where the older TS has ops will behave the same way on TS5 and TS3, +however an opless channel will behave differently, as you can see above. + +The result of TS5/TS3 mixed can be a desync: + +Example1: + +As per Example1 above, except the rest of the network is TS5, ServerA is +TS3. ServerA would keep its modes and ops, whilst the rest of the network +would remove them. This means only ServerA would see UserA as opped. The +desync can be abused, as UserA can send modes. Hybrid6.0 servers will +accept these modes from the unopped client, so if UserA ops UserB, who then +ops UserA, the channel will be the same across all Hybrid6.0 and Hybrid6.1 +servers. + +Example2: + +As per Example2 above, except the rest of the network is TS3. ServerC is +TS5. ServerC would remove its modes and ops, therefore UserC would not be +opped on ServerC, therefore it could not send any mode changes to the +channel. Although it is opped elsewhere, it isnt opped locally, so the +desync cannot be abused. + +As you can see, the desync's that can occur can either be resynced, or are +useless to the user, so a mixed TS5/TS3 network is not a huge problem, +although a desync is NOT a good thing to have. + + +Why TS5? +-------- + +We have jumped to TS5 from TS3, because there was a version of ircd that was +TS4, so it was thought better to avoid a clash with an existing version. + + +Advantages +---------- + +It's a realistic event that a server will be attacked so it splits off a +network, then used to regain ops in a channel. TS5 makes this pointless, +the server will never give ops on a netsplit. TS5 is network wide, so it +leaves individual servers free to choose options like NO_JOIN_ON_SPLIT, +whilst keeping splits useless to users. + + +Disadvantages +------------- + +It's virtually impossible for a user to actively regain ops themselves (some +regard this as an advantage..) because on a large sized channel, its +impossible to get people to leave so it can be recreated, therefore if a +network did not have some form of services, it could possibly end up +requiring oper intervention, as you cant get everybody to leave, and you +cant use splits to regain ops, therefore if the channel is open (an +invite-only channel would gradually destroy itself as noone new can join) it +could be impossible for a user to regain ops. + +On a network that has some form of services, The effect of TS5 would be +minimal, however the services must be of sufficient quality to fix opless +channels, as TS5 renders netsplits for ops worthless. + + +Recommendations +--------------- + +If your network has good stable services, we recommend TS5 is enabled, as +people have no reason to abuse netsplits anyway. + +If your network has no services at all, then TS5 may cause problems with +users being left with a permanently opless channel. + +If your network occupies the middle ground, then its a choice between users +needing to be able to use splits to regain ops, or making netsplits that are +caused to regain ops worthless. + +If TS5 is chosen, the FULL network must upgrade and this should be done in a +relatively short space of time to minimise the possible desync effects. + + +Alternatives +------------ + +There is also NO_JOIN_ON_SPLIT and NO_OP_ON_SPLIT, however these use the +configuration of minimum servers and users, and sometimes a split that is +above these limits is enough to be abused to regain ops, whereas if the +limits are too high, clients will never be able to join anything or be opped +when they create a channel. diff --git a/doc/technical/ts6.txt b/doc/technical/ts6.txt new file mode 100644 index 0000000..d1e29e8 --- /dev/null +++ b/doc/technical/ts6.txt @@ -0,0 +1,267 @@ +$Id$ + +TS6 Proposal (v7) +Written by Lee H <lee@leeh.co.uk> + +Introduction +------------ + +This document aims to fix some of the flaws that are still present in the +current TS system. + +Whilst only one person may use a nickname at any one time, they are not +a reliable method of directing commands between servers. Clients can change +their nicknames, which can create desyncs. A reliable method of directing +messages between servers is required so that a message will always reach the +intended destination, even if the client changes nicks in between. + +UID solves this problem by ensuring that a client has a unique ID for the +duration of his connection. + +This document also aims to solve the lack of TS rules to channel 'bans' on +a netburst. Bans from both sides of a TS war (losing/winning) are kept. +Bursting the bans with a TS solves this problem. + +There is also a race condition in the current TS system, where a user can +issue a mode during a netburst and the mode will be set on the server +we are bursting to. + + +Definitions +----------- + +Throughout this document, the following terms are used: + +SID - A servers unique ID. This is three characters long and must be in + the form [0-9][A-Z0-9][A-Z0-9] +ID - A clients unique ID. This is six characters long and must be in + the form [A-Z][A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]. The + numbers [0-9] at the beginning of an ID are legal characters, but + reserved for future use. +UID - An ID concateneted to a SID. This forms the clients UID. +TS6 - The TS version 6. + + +Support +------- + +Support for this document is given by the TS version 6. + +Wherever a destination parameter or source parameter is used, it must use +the SID or UID if the server/client has one. A TS6 capable server must +translate any SIDs/UIDs back into the server/clients name when communicating +with a server that does not support TS6. + +A TS6 server must also support the QS (quitstorm) system, and the encap +specification found here: +http://www.leeh.co.uk/ircd/encap.txt + +The TS6 protocol does not supports masked entities. + + +Nick TS rules +------------- + +A server receiving a command that requires nick TS rules must check for a +collision between an existing user, and the nick in the received message. +(the "new user"). The collisions must obey the rules specified in Nick TS +collisions. + +If the TS received is lower than the TS of the existing user the server will +collide the existing user if the clients user@host are different, if the +clients user@hosts are identical it will collide the new user. + +If the TS received is equal to the TS of the existing user both clients are +collided. + +If the TS received is higher than the TS of the existing user, the server +will collide the existing user if the user@hosts are identical, if the +clients user@host are different it will collide the new user and drop the +message. + + +Nick TS collisions +------------------ + +If both users are to be collided, we must issue a KILL for the existing +user to all servers. If the new user has a UID then we must also issue a +KILL for that UID back to the server sending us data causing the collision. + +If only the existing user is being collided, we must issue a KILL for the +existing user to all servers except the server sending us data. If the +existing user has a UID and the server sending us data supports TS6 then +we must also issue a KILL for the existing users UID to the server sending +us data. + +If only the new user is being collided, we must issue a KILL for the new user +back to the server sending us data if the new user has a UID. + + +Channel TS rules +---------------- + +A server receiving a command that requires normal channel TS rules must +apply the following rules to the command. + +If the TS received is lower than our TS of the channel a TS6 server must +remove status modes (+ov etc) and channel modes (+nt etc). If the +originating server is TS6 capable (ie, it has a SID), the server must +also remove any ban modes (+b etc). The new modes and statuses are then +accepted. + +If any bans are removed, the server must send to non-TS6, directly connected +servers mode changes removing the bans after the command is propagated. +This prevents desync with banlists, and has to be sent after as clients are +still able to send mode changes before the triggering command arrives. + +If the TS received is equal to our TS of the channel the server should keep +its current modes and accept the received modes and statuses. + +If the TS received is higher than our TS of the channel the server should keep +its current modes and ignore the received modes and statuses. Any statuses +given in the received message will be removed. A server must mark clients +losing their op (+o) status who do not have a UID as 'deopped'. A server must +ignore any "MODE" commands from a user marked as 'deopped'. + + +Simple channel TS rules +----------------------- + +A server receiving a command that requires simple channel TS rules must +apply the following rules to the command. + +If the TS received is lower, or equal to our TS of the channel the modes are +accepted. If the TS received is higher than our TS of the channel the modes +are ignored and dropped. + +Simple channel TS rules do not affect current modes in the channel except +for the modes we are accepting. + + +The following commands are defined here as the TS6 protocol +----------------------------------------------------------- + +PASS: +PASS <PASSWORD> TS <TS_CURRENT> :<SID> + +This command is used for password verification with the server we are +connecting to. + +Due to the burst being sent on verification of the "SERVER" command, and +"SVINFO" being sent after "SERVER", we need to be aware of the TS version +earlier to decide whether to send a TS6 burst or not. + +The <PASSWORD> field is the password we have stored for this server, +<TS_CURRENT> is our current TS version. If this field is not present then +the server does not support TS6. <SID> is the SID of the server. + +UID: +:<SID> UID <NICK> <HOPS> <TS> +<UMODE> <USERNAME> <HOSTNAME> <IP> <UID> :<GECOS> + +This command is used for introducing clients to the network. + +The <SID> field is the SID of the server the client is connected to. +The <NICK> field is the nick of the client being introduced. The <HOPS> +field is the amount of server hops between the server being burst to and +the server the client is on. The <TS> field is the TS of the client, either +the time they connected or the time they last changed nick. The <UMODE> +field contains the clients usermodes that need to be transmitted between +servers. The <USERNAME> field contains the clients username/ident. The +<HOSTNAME> field contains the clients host. + +The <IP> field contains the clients IP. If the IP is not to be sent +(due to a spoof etc), the field must be sent as "0". The <UID> field is the +clients UID. The <GECOS> field is the clients gecos. + +A server receiving a UID command must apply nick TS rules to the nick. + +SID: +:<SID> SID <SERVERNAME> <HOPS> <SID> :<GECOS> + +This command is used for introducing servers to the network. + +The first <SID> field is the SID of the new servers uplink. The +<SERVERNAME> field is the new servers name. The <HOPS> field is the hops +between the server being introduced nd the server being burst to. + +The second <SID> field is the SID of the new server. The <GECOS> field i +is the new servers gecos. + +Upon receiving the SID command servers must check for a SID collision. +Two servers must not be allowed to link to the network with the same SID. +If a server detects a SID collision it must drop the link to the directly +connected server through which the command was received. + +Client and servers which do not have a UID/SID must be introduced by old +methods. + +SJOIN: +:<SID> SJOIN <TS> <CHANNAME> +<CHANMODES> :<UIDS> + +This command is used for introducing users to channels. + +The <SID> field is the SID of the server introducing users to the channel. +The <TS> field is the channels current TS, <CHANNAME> is the channels +current name, <CHANMODES> are the channels current modes. <UIDS> is a +space delimited list of clients UIDs to join to the channel. Each clients +UID is prefixed with their status on the channel, ie "@UID" for an opped +user. Multiple prefixes are allowed, "peons" (clients without a status) are +not prefixed. + +A server receiving an SJOIN must apply normal channel TS rules to the SJOIN. + +A TS6 server must not use the SJOIN command outside of a netburst +to introduce a single user to an existing channel. It must instead +use the "JOIN" command defined in this specification. A TS6 server must +still use SJOIN for creating channels. + +JOIN: +:<UID> JOIN <TS> <CHANNAME> +<CHANMODES> + +This command is used for introducing one user unopped to an existing channel. + +The <UID> field is the UID of the client joining the channel. The +<TS> field is the channels current TS, <CHANNAME> is the channels +current name, <CHANMODES> are the channels current modes. + +A server receiving a JOIN must apply normal channel TS rules to the JOIN. + +It should be noted that whilst JOIN would not normally create a +channel, during specific race conditions it can. This can create +a ban desync that this specification does not rectify. + +BMASK: +:<SID> BMASK <TS> <CHANNAME> <TYPE> :<MASKS> + +This command is used for bursting channel bans to a network. + +The <SID> field is the SID of the server bursting the bans. The +<TS> field is the channels current TS, <CHANNAME> is the channels +name. <TYPE> is a single character identifying the mode type (ie, +for a ban 'b'). <MASKS> is a space delimited list of masks of the +given mode,limited only in length to the size of the buffer as defined +by RFC1459. + +A server receiving a BMASK must apply simple channel TS rules to the BMASK. + +A TS6 server must translate BMASKs into raw modes for non-TS6 +capable servers. This command must be used only after SJOIN has +been sent for the given channel. + +It should be noted however, that a BMASK with a lower TS should +not be possible without a desync, due to it being sent after +SJOIN. + +TMODE: +:<UID> TMODE <TS> <CHANNAME> <MODESTRING> + +This command is used for clients issuing modes on a channel. + +<UID> is the UID of the client setting the mode. <TS> is the +current TS of the channel, <CHANNAME> is the channels name. +<MODESTRING> is the raw mode the client is setting. + +A server receiving a TMODE must apply simple channel TS rules to the TMODE. + +A TS6 server must translate MODEs issued by a local client into TMODE +to send to other TS6 capable servers. diff --git a/help/Makefile.am b/help/Makefile.am new file mode 100644 index 0000000..be4f764 --- /dev/null +++ b/help/Makefile.am @@ -0,0 +1,2 @@ +AUTOMAKE_OPTIONS = foreign +SUBDIRS = opers users diff --git a/help/Makefile.in b/help/Makefile.in new file mode 100644 index 0000000..b298e44 --- /dev/null +++ b/help/Makefile.in @@ -0,0 +1,596 @@ +# Makefile.in generated by automake 1.12.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = help +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBDIR = @LIBDIR@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PREFIX = @PREFIX@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +SUBDIRS = opers users +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign help/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign help/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done +cscopelist-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) \ + cscopelist-recursive ctags-recursive install-am install-strip \ + tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + cscopelist cscopelist-recursive ctags ctags-recursive \ + distclean distclean-generic distclean-libtool distclean-tags \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-recursive uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/help/opers/Makefile.am b/help/opers/Makefile.am new file mode 100644 index 0000000..448280e --- /dev/null +++ b/help/opers/Makefile.am @@ -0,0 +1,16 @@ +AUTOMAKE_OPTIONS = foreign + +helpfdir = $(pkgdatadir)/help/opers + +dist_helpf_DATA = accept cmode etrace ison list map nick ping resv stats trace \ + unxline whois admin connect gline gungline join locops module \ + notice pong svinfo uhelp user whowas away hash \ + kick lusers omotd post testgecos umode \ + userhost xline capab die help kill oper privmsg \ + server testline undline users challenge dline index kline \ + operwall quit set testmask ungline version \ + eob info knock motd part rehash sjoin time unkline wallops \ + close error invite links names pass restart squit topic \ + unresv who + +helpf: $(dist_helpf_DATA) diff --git a/help/opers/Makefile.in b/help/opers/Makefile.in new file mode 100644 index 0000000..92df928 --- /dev/null +++ b/help/opers/Makefile.in @@ -0,0 +1,476 @@ +# Makefile.in generated by automake 1.12.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = help/opers +DIST_COMMON = $(dist_helpf_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(helpfdir)" +DATA = $(dist_helpf_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBDIR = @LIBDIR@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PREFIX = @PREFIX@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +helpfdir = $(pkgdatadir)/help/opers +dist_helpf_DATA = accept cmode etrace ison list map nick ping resv stats trace \ + unxline whois admin connect gline gungline join locops module \ + notice pong svinfo uhelp user whowas away hash \ + kick lusers omotd post testgecos umode \ + userhost xline capab die help kill oper privmsg \ + server testline undline users challenge dline index kline \ + operwall quit set testmask ungline version \ + eob info knock motd part rehash sjoin time unkline wallops \ + close error invite links names pass restart squit topic \ + unresv who + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign help/opers/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign help/opers/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-dist_helpfDATA: $(dist_helpf_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_helpf_DATA)'; test -n "$(helpfdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(helpfdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(helpfdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(helpfdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(helpfdir)" || exit $$?; \ + done + +uninstall-dist_helpfDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_helpf_DATA)'; test -n "$(helpfdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(helpfdir)'; $(am__uninstall_files_from_dir) +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(helpfdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-dist_helpfDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_helpfDATA + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_helpfDATA \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am uninstall uninstall-am uninstall-dist_helpfDATA + + +helpf: $(dist_helpf_DATA) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/help/opers/accept b/help/opers/accept new file mode 100644 index 0000000..50ac159 --- /dev/null +++ b/help/opers/accept @@ -0,0 +1,9 @@ +ACCEPT [parameter] + +ACCEPT allows you to control who can send you a NOTICE or PRIVMSG +while you have user mode +g enabled. + +For +g: /QUOTE ACCEPT <n!u@h> -- Add a permitted mask + /QUOTE ACCEPT -<n!u@h> -- Remove a permitted mask + /QUOTE ACCEPT * -- List the present permitted masks + /QUOTE ACCEPT -- List the present permitted masks diff --git a/help/opers/admin b/help/opers/admin new file mode 100644 index 0000000..7b1b8a0 --- /dev/null +++ b/help/opers/admin @@ -0,0 +1,11 @@ +ADMIN [server] + +With no arguments, ADMIN shows the information that was set by the +administrator of the server. This information can take any form that +will fit in three lines of text but is usually a list of contacts +for the persons that run the server. + +With a second argument, the administrative information for the +specified server is displayed. + +See also: stats diff --git a/help/opers/away b/help/opers/away new file mode 100644 index 0000000..9f04479 --- /dev/null +++ b/help/opers/away @@ -0,0 +1,4 @@ +AWAY :[MSG] + +Without an argument, it will set you back. With an argument, +it will set you as AWAY with the specified message. diff --git a/help/opers/capab b/help/opers/capab new file mode 100644 index 0000000..36abc97 --- /dev/null +++ b/help/opers/capab @@ -0,0 +1 @@ +CAPAB - Server to Server Protocol Command. diff --git a/help/opers/challenge b/help/opers/challenge new file mode 100644 index 0000000..9e8d432 --- /dev/null +++ b/help/opers/challenge @@ -0,0 +1,10 @@ +CHALLENGE <nick|+response> + +CHALLENGE is used in the RSA controlled +oper {} system. CHALLENGE requires you to +issue the command using the nickname in the +operator block, while matching the username +and hostname specified. The server will +send you an RSA challenge. You must send +a valid RSA response back to the server, +proceeded with a '+' symbol. diff --git a/help/opers/close b/help/opers/close new file mode 100644 index 0000000..82fae6b --- /dev/null +++ b/help/opers/close @@ -0,0 +1,4 @@ +CLOSE + +Close any connections from clients or servers who have +not fully registered yet. diff --git a/help/opers/cmode b/help/opers/cmode new file mode 100644 index 0000000..5fe5147 --- /dev/null +++ b/help/opers/cmode @@ -0,0 +1,94 @@ +# $Id$ +MODE <channel> <+|-><modes> [parameters] + +=-=-=-=-=-=-=-=-=-=-= + CHANNELMODES +=-=-=-=-=-=-=-=-=-=-= + + MODE - DESCRIPTION +------------------------------------------------------------------------ + +NO PARAMETERS: +-------------- + + +n - 'No external messages'. This will prevent any user who + isn't in the channel from sending messages to the channel. + + +t - 'Ops Topic'. This will prevent any user who isn't opped, + or half-opped (+o/+h) from setting a channel topic. + + +s - 'Secret'. This will prevent the channel from being shown + in a /whois, and in the channel list. + + +p - 'Paranoia'. Controls whether halfops may invite users + into a channel or whether they may kick other members of a + channel. + + +m - 'Moderated'. This will prevent any user who isn't opped, + half-opped or voiced (+o/+h/+v) from talking in the channel. + + +i - 'Invite only'. This will prevent anyone from joining your + channel who hasn't received an /invite or whose host isn't in + the +I list. + + +r - 'Registered'. Channel has been registered with ChanServ. + This mode can be set by servers only. + + +O - 'IRCOps only'. This will prevent anyone who hasn't obtained + IRCOp status from joining your channel. Can be set by an IRCOp + only. + + +R - 'Registered only'.- Only registered clients may join a channel + with that mode set + + +S - 'SSL only'. This will prevent anyone who isn't securely connected + via SSL/TLS from joining your channel. + + +WITH PARAMETERS: +---------------- + + +k - 'Key'. This will require users joining to know the key, + they must then use /join #channel KEY + + PARAMS: /mode #channel +k key + + +l - 'Limit'. This will prevent more than LIMIT number of people + in the channel at any time. + + PARAMS: /mode #channel +l limit + + +v - 'Voice'. This will allow a user to talk in a moderated (+m) + channel. Shown by the +nick flag. + + PARAMS: /mode #channel +vvvv nick1 nick2 nick3 nick4 + + +h - 'Half-op'. This will allow a user to set all of the above + modes, (and some more below..), whilst stopping the user + from doing harm to the channel. Users who are +h CANNOT + kick opped (+o) users, or set modes +h/-h/+o/-o. + + They can perform all other modes, and can kick regular users. + + PARAMS: /mode #channel +hhhh nick1 nick2 nick3 nick4 + + +o - 'Op'. This gives the user full control over the channel. + An opped user may op other users, set any mode, and + remove ops from whoever they want. + + PARAMS: /mode #channel +oooo nick1 nick2 nick3 nick4 + + +b - 'Ban'. This will prevent a user from entering the channel, + based on a nick!ident@host match. + + PARAMS: /mode #channel +bbbb n!u@h1b n!u@h2b n!u@h3b n!u@h4 + + +e - 'Exempt'. This will allow a user to join a channel even if + they are banned (+b), based on a nick!ident@host match. + + PARAMS: /mode #channel +eeee n!u@h1b n!u@h2b n!u@h3b n!u@h4 + + +I - 'Invite Exempt'. This will allow a user to join an + invite-only (+i) channel, based on a nick!user@host match. + + PARAMS: /mode #channel +IIII n!u@h1b n!u@h2b n!u@h3b n!u@h4 diff --git a/help/opers/connect b/help/opers/connect new file mode 100644 index 0000000..929bfb8 --- /dev/null +++ b/help/opers/connect @@ -0,0 +1,16 @@ +CONNECT <server_A> [port] [server_B] + +When [server_B] is used, CONNECT asks [server_B] to +connect to <server_A>. Requires Oper Priv: R + +The [port] must be specified with [server_B], this is +usually 6667. To use the default port in the connect +block, you can use 0 as the port. + +When [server_B] is not used, CONNECT tries to connect +your server to <server_A>. + +When [port] is used, the connection will be attempted +to [port]. +When [port] is not used, 6667 is used as a default, +unless the port is specified in the conf file. diff --git a/help/opers/die b/help/opers/die new file mode 100644 index 0000000..876bc51 --- /dev/null +++ b/help/opers/die @@ -0,0 +1,6 @@ +DIE server.name :[reason] + +Terminates the IRC server with optional reason +[reason] + +- Requires Oper Priv: D diff --git a/help/opers/dline b/help/opers/dline new file mode 100644 index 0000000..f9c31da --- /dev/null +++ b/help/opers/dline @@ -0,0 +1,19 @@ +# $Id$ +DLINE <time> <nick|ip> :[reason] [| oper reason] + +<time> if present, gives number of minutes for DLINE + +Adds a DLINE to the dline.conf file +which will deny any connections from the IP address +of the banned client. The banned client will receive +a message saying he/she is banned with reason [reason] + +If an oper reason is added (the pipe must be specified +to separate the fields) this will be added into the +dline.conf but will not be shown to the user when they +are given the dline reason. + +In order to use <nick> rather than <ip>, <nick> must +be on your server. + +- Requires Oper Priv: K diff --git a/help/opers/eob b/help/opers/eob new file mode 100644 index 0000000..ec50689 --- /dev/null +++ b/help/opers/eob @@ -0,0 +1 @@ +EOB - Server to Server Protocol Command. diff --git a/help/opers/error b/help/opers/error new file mode 100644 index 0000000..e3f163b --- /dev/null +++ b/help/opers/error @@ -0,0 +1,8 @@ +ERROR :<message> + +ERROR is sent by the server to clients +or other servers when an exception occurs. + +If another server sends your server an +ERROR, it will be shown to all operators +on the server. diff --git a/help/opers/etrace b/help/opers/etrace new file mode 100644 index 0000000..b07de8f --- /dev/null +++ b/help/opers/etrace @@ -0,0 +1,9 @@ +ETRACE [nickname mask] + +The ETRACE command will display a list of locally connected users +in the following format: + +User/Oper class nickname username host gecos + +You can optionally give a parameter with nickname mask to limit +the output. Wildcards are allowed. diff --git a/help/opers/gline b/help/opers/gline new file mode 100644 index 0000000..6ce368d --- /dev/null +++ b/help/opers/gline @@ -0,0 +1,16 @@ +GLINE <user@host> :[reason] + +-- if glines are enabled -- +Attempts to add a global IRC-network wide ban on +<user@host> for the reason [reason]. + +It takes three different opers on three different +servers to do the same GLINE within a short interval, +to have a GLINE triggered for a compiled time of hours. + +GLINE user@ip.ip.ip.ip +will gline the user at the unresolved ip. +ip.ip.ip.ip can be in CIDR form i.e. 192.168.0.0/24 +or 192.168.0.* (which is converted to CIDR form internally) + +- Requires Oper Priv: G diff --git a/help/opers/gungline b/help/opers/gungline new file mode 100644 index 0000000..558ea56 --- /dev/null +++ b/help/opers/gungline @@ -0,0 +1,16 @@ +GUNGLINE <user@host> :[reason] + +-- if glines are enabled -- +Attempts to remove a global IRC-network wide ban on +<user@host> for the reason [reason]. + +It takes three different opers on three different +servers to do the same GUNGLINE within a short interval, +to have a GUNGLINE triggered for a compiled time of hours. + +GUNGLINE user@ip.ip.ip.ip +will ungline the user at the unresolved ip. +ip.ip.ip.ip can be in CIDR form i.e. 192.168.0.0/24 +or 192.168.0.* (which is converted to CIDR form internally) + +- Requires Oper Priv: G diff --git a/help/opers/hash b/help/opers/hash new file mode 100644 index 0000000..04e3fee --- /dev/null +++ b/help/opers/hash @@ -0,0 +1,3 @@ +HASH + +Shows the hash statistics. diff --git a/help/opers/help b/help/opers/help new file mode 100644 index 0000000..fd20128 --- /dev/null +++ b/help/opers/help @@ -0,0 +1,6 @@ +HELP [topic] + +HELP displays the contents of the help +file for topic requested. If no topic is +requested, it will perform the equivalent +to HELP index. diff --git a/help/opers/index b/help/opers/index new file mode 100644 index 0000000..e2ac194 --- /dev/null +++ b/help/opers/index @@ -0,0 +1,28 @@ +# $Id$ +Help topics available to opers only: + +CAPAB CLOSE +CONNECT CRYPTLINK DIE DLINE +DROP EOB ETRACE GLINE +HASH KILL KLINE LOCOPS +MODULE NOTICE OMOTD OPERWALL +POST PRIVMSG REHASH RESTART +RESV SERVER SET SJOIN +SQUIT STATS SVINFO TESTGECOS +TESTLINE TESTMASK TRACE UHELP +UMODE UNDLINE UNGLINE UNKLINE +UNRESV UNXLINE WALLOPS +XLINE + +Help topics available to users: + +ACCEPT ADMIN AWAY CHALLENGE +CMODE ERROR HELP INFO +INVITE ISON JOIN KICK +KNOCK LINKS LIST LUSERS +MAP MOTD NAMES NICK +NOTICE OPER PART PASS +PING PONG PRIVMSG QUIT +STATS TIME TOPIC UMODE +USER USERHOST USERS VERSION +WHO WHOIS WHOWAS diff --git a/help/opers/info b/help/opers/info new file mode 100644 index 0000000..3a05e16 --- /dev/null +++ b/help/opers/info @@ -0,0 +1,7 @@ +INFO + +INFO displays the copyright, list of authors and contributors +to ircd, and the server configuration (as defined in setup.h, +defaults.h, and ircd.conf). + +# $Id$ diff --git a/help/opers/invite b/help/opers/invite new file mode 100644 index 0000000..6e64fa3 --- /dev/null +++ b/help/opers/invite @@ -0,0 +1,4 @@ +INVITE <nickname> <channel> + +INVITE sends a notice to the user that you have +asked him/her to come to the specified channel. diff --git a/help/opers/ison b/help/opers/ison new file mode 100644 index 0000000..f79de3a --- /dev/null +++ b/help/opers/ison @@ -0,0 +1,6 @@ +ISON <nick_A> [nick_B] :[nick_C] [nick_D] + +ISON will return a list of users who are present +on the network from the list that was passed in. + +This command is rarely used directly. diff --git a/help/opers/join b/help/opers/join new file mode 100644 index 0000000..2065b6f --- /dev/null +++ b/help/opers/join @@ -0,0 +1,11 @@ +# $Id$ +JOIN <#channel1[,#channel2,#channel3...]> [key] + +The JOIN command allows you to enter a public chat area known as +a channel. You can join more than one channel at a time, +separating their names with comma's (','). + +If the channel has a key set, the second argument must be +given to enter. This allows channels to be password protected. + +See also: part, list diff --git a/help/opers/kick b/help/opers/kick new file mode 100644 index 0000000..a3ce273 --- /dev/null +++ b/help/opers/kick @@ -0,0 +1,6 @@ +KICK <channel> <nick> :[msg] + +The KICK command will remove the specified user +from the specified channel, using the optional +kick message. You must be a channel operator to +use this command. diff --git a/help/opers/kill b/help/opers/kill new file mode 100644 index 0000000..b24c2aa --- /dev/null +++ b/help/opers/kill @@ -0,0 +1,5 @@ +KILL <nick> <reason> + +Disconnects user <nick> from the IRC server he/she +is connected to with reason <reason>. +- Requires Oper Priv: O for users not on your IRC server diff --git a/help/opers/kline b/help/opers/kline new file mode 100644 index 0000000..257e11b --- /dev/null +++ b/help/opers/kline @@ -0,0 +1,29 @@ +# $Id$ +KLINE [time] <nick|user@host> :[reason] [| oper reason] + +[time] if present, gives number of minutes for KLINE + +Adds a KLINE to the kline.conf file which +will ban the specified user from using that server. +The banned client will receive a message saying he/she +is banned with reason [reason] + +If an oper reason is added (the pipe must be specified +to separate the fields) this will be added into the +kline.conf but will not be shown to the user when they +are given the kline reason. + +KLINE user@ip.ip.ip.ip :[reason] [| oper reason] +will kline the user at the unresolved ip. +ip.ip.ip.ip can be in CIDR form i.e. 192.168.0.0/24 +or 192.168.0.* (which is converted to CIDR form internally) + +For a temporary KLINE, length of kline is given in +minutes as the first parameter [time] i.e. +KLINE 10 <nick|user@host> :cool off for 10 minutes + +KLINE <user@host> ON irc.server :[reason] [| oper reason] +will kline the user on irc.server if irc.server accepts +remote klines. + +- Requires Oper Priv: K diff --git a/help/opers/knock b/help/opers/knock new file mode 100644 index 0000000..904d5a8 --- /dev/null +++ b/help/opers/knock @@ -0,0 +1,7 @@ +KNOCK <channel> + +KNOCK requests access to a channel that +for some reason is not open. + +KNOCK cannot be used if you are banned, the +channel is +p, or it is open. diff --git a/help/opers/links b/help/opers/links new file mode 100644 index 0000000..ce4b417 --- /dev/null +++ b/help/opers/links @@ -0,0 +1,17 @@ +LINKS [mask] [remote] + +LINKS shows a list of all servers linked to the host server. + +With a mask parameter, LINKS will just show servers matching +that parameter. With the remote server parameter, LINKS will +request the LINKS data from the remote server, matching the +mask given. + +The information provided by the LINKS command can be helpful +for determining the overall shape of the network in addition to +it's size. + +NOTE: the links command employs an intensive process to generate +it's output, so sparing use is recommended. + +See also: connect squit diff --git a/help/opers/list b/help/opers/list new file mode 100644 index 0000000..f21197d --- /dev/null +++ b/help/opers/list @@ -0,0 +1,24 @@ +LIST [options] + +Without any arguments, LIST will give an entire list of all +channels which are not set as secret (+s). The list will be in +the form: + + <#channel> <amount of users> :[topic] + +If you want to use a specific filter, you can pass one or more +options separated by commas (','). Recognized options are: + *mask* List channels matching *mask* + !*mask* List channels NOT matching *mask* + >num Show only channels which contain more than <num> users + <num Show only channels which contain less than <num> users + C>num Display channels created within last <num> minutes + C<num Display channels created earlier than <num> minutes ago + T>num Limit matches to those channels whose topics are older + than <num> minutes + T<num Limit matches to those channels whose topics have been + changed within last <num> minutes + +To stop a running LIST request, use /LIST command again. + +See also: join diff --git a/help/opers/locops b/help/opers/locops new file mode 100644 index 0000000..e7ef5d4 --- /dev/null +++ b/help/opers/locops @@ -0,0 +1,4 @@ +LOCOPS :<message> + +Sends an LOCOPS message of <message> to all +opers on local server who are umode +l diff --git a/help/opers/lusers b/help/opers/lusers new file mode 100644 index 0000000..663e5a5 --- /dev/null +++ b/help/opers/lusers @@ -0,0 +1,7 @@ +LUSERS [mask] [remoteserver] + +LUSERS will display client count statistics +for the specified mask, or all users if a +mask was not specified. If a remote server +is specified, it will request the information +from that server. diff --git a/help/opers/map b/help/opers/map new file mode 100644 index 0000000..b5eb8f5 --- /dev/null +++ b/help/opers/map @@ -0,0 +1,3 @@ +MAP + +Shows the network map. diff --git a/help/opers/module b/help/opers/module new file mode 100644 index 0000000..8fe0408 --- /dev/null +++ b/help/opers/module @@ -0,0 +1,22 @@ +MODULE <option> [module name] + +<option> can be one of the following: + LIST - List the modules that are currently loaded into the + ircd, along with their address and version. + When a match string is provided, LIST only prints + modules with names matching the match string. + + LOAD - Loads a module into the ircd. + The optional path can be an absolute path + from / or from the IRCD_PREFIX + (ie modules/autoload/m_users.la) + + UNLOAD - Unload a module from the ircd. + Use just the module name, the path is not needed. + When a module is unloaded, all commands associated + with it are unloaded as well. + + RELOAD - Reloads all modules. + All modules are unloaded, then those in modules/autoload + are loaded. If "*" has been specified as module name, + all modules will be reloaded. diff --git a/help/opers/motd b/help/opers/motd new file mode 100644 index 0000000..70b5f83 --- /dev/null +++ b/help/opers/motd @@ -0,0 +1,6 @@ +# $Id$ +MOTD [servername] + +MOTD will display the message of the day for the +server name specified, or the local server if there +was no parameter. diff --git a/help/opers/names b/help/opers/names new file mode 100644 index 0000000..4b69fc2 --- /dev/null +++ b/help/opers/names @@ -0,0 +1,11 @@ +NAMES [channel] + +With no channel argument, NAMES shows the names (nicks) of all clients +logged in to the server that do not have +i flag. + +With the #channel argument, it displays the nicks on that channel, +also respecting the +i flag of each client. If the channel specified +is a channel that the issuing client is currently in, all nicks are +listed in similar fashion to when the user first joins a channel. + +See also: join diff --git a/help/opers/nick b/help/opers/nick new file mode 100644 index 0000000..32d56d1 --- /dev/null +++ b/help/opers/nick @@ -0,0 +1,7 @@ +NICK <nickname> + +When first connected to the IRC server, NICK is required to +set the client's nickname. + +NICK will also change the client's nickname once a connection +has been established. diff --git a/help/opers/notice b/help/opers/notice new file mode 100644 index 0000000..0387f76 --- /dev/null +++ b/help/opers/notice @@ -0,0 +1,36 @@ +NOTICE <nick|channel> :message + +NOTICE will send a notice message to the +user or channel specified. + +NOTICE supports the following prefixes for sending +messages to specific clients in a channel: + +@ - channel operators only +% - channel operators and half-ops ++ - operators, half-ops, and voiced users + +Two other targets are permitted: + +$$servermask - Send a message to a server or set of + servers +$#hostmask - Send a message to users matching the + hostmask specified. + +These two are operator only. + +The nick can be extended to fit into the following +syntax: + +username[%hostname]@servername + +This syntax (without the hostname) is used to securely +send a message to a service or a bot. + +An extension of this is the syntax to send to all opers +on a server. + +opers@servername + +In Hybrid 7, all opers on a server will see a message that +looks like a modified WALLOPS diff --git a/help/opers/omotd b/help/opers/omotd new file mode 100644 index 0000000..4e5fb5c --- /dev/null +++ b/help/opers/omotd @@ -0,0 +1,4 @@ +# $Id$ +OMOTD + +OMOTD will display the operator message of the day. diff --git a/help/opers/oper b/help/opers/oper new file mode 100644 index 0000000..08962bf --- /dev/null +++ b/help/opers/oper @@ -0,0 +1,8 @@ +OPER <name> <password> + +The OPER command requires two arguments to be given. The first +argument is the name of the operator as specified in the +configuration file. The second argument is the password for +the operator matching the name and host. + +The operator privileges are shown on a sucessful OPER. diff --git a/help/opers/operwall b/help/opers/operwall new file mode 100644 index 0000000..e331548 --- /dev/null +++ b/help/opers/operwall @@ -0,0 +1,4 @@ +OPERWALL :<message> + +Sends an OPERWALL message of <message> to all +opers who are umode +z diff --git a/help/opers/part b/help/opers/part new file mode 100644 index 0000000..9cf8f14 --- /dev/null +++ b/help/opers/part @@ -0,0 +1,9 @@ +PART <#channel> :[part message] + +PART requires at least a channel argument to be given. It will +exit the client from the specified channel. + +An optional part message may be given to be displayed to the +channel. + +See also: join diff --git a/help/opers/pass b/help/opers/pass new file mode 100644 index 0000000..d4a618d --- /dev/null +++ b/help/opers/pass @@ -0,0 +1,6 @@ +PASS <password> + +PASS is used during registration to access +a password protected auth {} block. + +PASS is also used during server registration. diff --git a/help/opers/ping b/help/opers/ping new file mode 100644 index 0000000..9de6ed5 --- /dev/null +++ b/help/opers/ping @@ -0,0 +1,6 @@ +PING <source> :<target> + +PING will request a PONG from the target. If a +user or operator issues this command, the source +will always be turned into the nick that issued +the PING. diff --git a/help/opers/pong b/help/opers/pong new file mode 100644 index 0000000..c05c65a --- /dev/null +++ b/help/opers/pong @@ -0,0 +1,6 @@ +PONG <pinged-client> :<source-client> + +PONG is the response to a PING command. The +source client is the user or server that issued +the command, and the pinged client is the +user or server that received the PING. diff --git a/help/opers/post b/help/opers/post new file mode 100644 index 0000000..362ca3d --- /dev/null +++ b/help/opers/post @@ -0,0 +1,5 @@ +POST + +The POST command is used to help protect against +insecure HTTP proxies. Any proxy that sends a POST +command during registration will be exited. diff --git a/help/opers/privmsg b/help/opers/privmsg new file mode 100644 index 0000000..e0e8835 --- /dev/null +++ b/help/opers/privmsg @@ -0,0 +1,36 @@ +PRIVMSG <nick1|channel1[,nick2|channel2...]> :message + +PRIVMSG will send a standard message to the +user or channel specified. + +PRIVMSG supports the following prefixes for sending +messages to specific clients in a channel: + +@ - channel operators only +% - channel operators and half-ops ++ - operators, half-ops, and voiced users + +Two other targets are permitted: + +$$servermask - Send a message to a server or set of + servers +$#hostmask - Send a message to users matching the + hostmask specified. + +These two are operator only. + +The nick can be extended to fit into the following +syntax: + +username[%hostname]@servername + +This syntax (without the hostname) is used to securely +send a message to a service or a bot. + +An extension of this is the syntax to send to all opers +on a server. + +opers@servername + +In Hybrid 7, all opers on a server will see a message that +looks like a modified WALLOPS diff --git a/help/opers/quit b/help/opers/quit new file mode 100644 index 0000000..b6d0735 --- /dev/null +++ b/help/opers/quit @@ -0,0 +1,5 @@ +QUIT :[quit message] + +QUIT sends a message to the IRC server letting it know you would +like to disconnect. The quit message will be displayed to the +users in the channels you were in when you are disconnected. diff --git a/help/opers/rehash b/help/opers/rehash new file mode 100644 index 0000000..8c2f561 --- /dev/null +++ b/help/opers/rehash @@ -0,0 +1,11 @@ +REHASH [option] + +When no [option] is given, ircd will re-read the +ircd.conf file. + +[option] can be one of the following: + DNS - Re-read the /etc/resolv.conf file + MOTD - Re-reads MOTD file + OMOTD - Re-reads Oper MOTD file + +- Requires Oper Priv: H diff --git a/help/opers/restart b/help/opers/restart new file mode 100644 index 0000000..1d7ea48 --- /dev/null +++ b/help/opers/restart @@ -0,0 +1,5 @@ +RESTART server.name :[reason] + +Restarts the IRC server. + +- Requires Oper Priv: D diff --git a/help/opers/resv b/help/opers/resv new file mode 100644 index 0000000..64c29d9 --- /dev/null +++ b/help/opers/resv @@ -0,0 +1,9 @@ +RESV <channel|nick> :<reason> + +-- RESV a channel or nick +Will create a resv for the given channel/nick, stopping +local users from joining the channel, or using the +nick. Will not affect remote clients. + +If the oper is an admin, they may create a wildcard +resv, for example: clones* diff --git a/help/opers/server b/help/opers/server new file mode 100644 index 0000000..b618436 --- /dev/null +++ b/help/opers/server @@ -0,0 +1 @@ +SERVER - Server to Server Protocol Command. diff --git a/help/opers/set b/help/opers/set new file mode 100644 index 0000000..a3bf2ed --- /dev/null +++ b/help/opers/set @@ -0,0 +1,41 @@ +SET <option> <value> + +<option> can be one of the following: + AUTOCONN - Sets auto-connect on or off for a particular + server + AUTOCONNALL - Sets auto-connect on or off for all servers + FLOODCOUNT - The number of lines allowed before + throttling a connection due to flooding + Note that this variable is used for both + channels and clients + IDLETIME - The number of seconds a client can be idle + before disconnecting them + JFLOODCOUNT - Sets the number of joins in JFLOODTIME to + count as flooding. Use 0 to disable. + JFLOODTIME - The amount of time in seconds in JFLOODCOUNT to consider + as join flooding. Use 0 to disable. + LOG - Sets the Logging level for what is logged + to ircd.log and syslog. + MAX - Sets the number of max connections + to <value>. (This number cannot exceed + HARD_FDLIMIT in defaults.h) + MSGLOCALE - Set the message locale + standard - Compiled in defaults + custom - Old CUSTOM_ERR messages + REJECTTIME - Sets the amount of time before disconnecting + a rejected client. Use 0 to disable. + SPAMNUM - Sets how many join/parts to channels + constitutes a possible spambot. + SPAMTIME - Below this time on a channel + counts as a join/part as above. + SPLITMODE - Sets splitmode to <value>: + ON - splitmode is permanently on + OFF - splitmode is permanently off + AUTO - ircd chooses splitmode based on + SPLITUSERS and SPLITNUM + SPLITNUM - Sets the minimum amount of servers needed to + deactivate automatic splitmode. + SPLITUSERS - Sets the minimum amount of users needed to + deactivate automatic splitmode. + +# $Id$ diff --git a/help/opers/sjoin b/help/opers/sjoin new file mode 100644 index 0000000..026ab5f --- /dev/null +++ b/help/opers/sjoin @@ -0,0 +1 @@ +SJOIN - Server to Server Protocol Command. diff --git a/help/opers/squit b/help/opers/squit new file mode 100644 index 0000000..9c0ff05 --- /dev/null +++ b/help/opers/squit @@ -0,0 +1,5 @@ +# $Id$ +SQUIT <server> :[reason] + +Splits <server> away from your side of the net with [reason]. +- Requires Oper Priv: R for servers not connected to you diff --git a/help/opers/stats b/help/opers/stats new file mode 100644 index 0000000..7295349 --- /dev/null +++ b/help/opers/stats @@ -0,0 +1,42 @@ +# $Id$ +STATS <letter> [server|nick] + +Queries server [server] (or your own server if no +server parameter is given) for info corresponding to +<letter>. + + (X = Admin only.) +LETTER (* = Oper only.) +------ (^ = Can be configured to be oper only.) +X A - Shows the ADNS DNS servers in use +* c - Shows connect blocks +* d - Shows temporary D lines +* D - Shows D lines +* e - Shows exemptions to D lines +X E - Shows Events +X f - Shows File Descriptors +* g - Shows pending G lines +* G - Shows G lines +X h - Shows ircd callback statistics +* H - Shows H/L lines +^ i - Shows I lines +^ K - Shows K lines (or matched klines) +^ k - Shows temporary K lines (or matched temp klines) +* L - Shows IP and generic info about [nick] +* l - Shows hostname and generic info about [nick] + m - Shows commands and their usage +^ o - Shows O/o lines +* P - Shows configured ports + p - Shows opers connected and their idle times +* q - Shows resv'd nicks and channels +* r - Shows resource usage by ircd +* s - Shows the server cache +* t - Shows generic server stats +* U - Shows shared blocks (Old U: lines) + u - Shows server uptime +* v - Shows connected servers and their idle times +* x - Shows gecos bans (Old X: lines) +* y - Shows Y lines +* z - Shows memory stats +* Z - Show ziplinks stats +* ? - Shows connected servers and sendq info about them diff --git a/help/opers/svinfo b/help/opers/svinfo new file mode 100644 index 0000000..936db99 --- /dev/null +++ b/help/opers/svinfo @@ -0,0 +1 @@ +SVINFO - Server to Server Protocol Command. diff --git a/help/opers/testgecos b/help/opers/testgecos new file mode 100644 index 0000000..f131a8a --- /dev/null +++ b/help/opers/testgecos @@ -0,0 +1,3 @@ +TESTGECOS <gecos> + +Looks for matching xlines for the given gecos. diff --git a/help/opers/testline b/help/opers/testline new file mode 100644 index 0000000..a080e55 --- /dev/null +++ b/help/opers/testline @@ -0,0 +1,5 @@ +TESTLINE <user@host>|ip + +-- Looks up given user@host or user@ip +returns info on any found I line or K line for that user, +or D-line on ip. diff --git a/help/opers/testmask b/help/opers/testmask new file mode 100644 index 0000000..162765e --- /dev/null +++ b/help/opers/testmask @@ -0,0 +1,5 @@ +# $Id$ +TESTMASK <user@host> + +Will test the given user@host mask, reporting how many local and +global clients match the given mask. diff --git a/help/opers/time b/help/opers/time new file mode 100644 index 0000000..40d79a1 --- /dev/null +++ b/help/opers/time @@ -0,0 +1,6 @@ +TIME [server] + +The TIME command will return the server's local date and time. + +If an argument is supplied, the time for the server specified +will be returned. diff --git a/help/opers/topic b/help/opers/topic new file mode 100644 index 0000000..eb7e3a3 --- /dev/null +++ b/help/opers/topic @@ -0,0 +1,10 @@ +TOPIC <#channel> :[new topic] + +With only a channel argument, TOPIC shows the current topic of +the specified channel. + +With a second argument, it changes the topic on that channel to +<new topic>. If the channel is +t, only chanops may change the +topic. + +See also: cmode diff --git a/help/opers/trace b/help/opers/trace new file mode 100644 index 0000000..7817af6 --- /dev/null +++ b/help/opers/trace @@ -0,0 +1,11 @@ +TRACE [server | nick] + +With no argument, TRACE gives a list of all clients connected +to the local server, both users and operators. + +With one argument which is a server, TRACE displays the path +to the specified server, and all clients on that server. + +With one argument which is a client, TRACE displays the +path to that client, and that client's information. + diff --git a/help/opers/uhelp b/help/opers/uhelp new file mode 100644 index 0000000..74ba8ce --- /dev/null +++ b/help/opers/uhelp @@ -0,0 +1,5 @@ +UHELP [topic] + +UHELP allows an operator to view help topics +for users without opening a second client +or removing their operator status. diff --git a/help/opers/umode b/help/opers/umode new file mode 100644 index 0000000..0bb70c7 --- /dev/null +++ b/help/opers/umode @@ -0,0 +1,33 @@ +# $Id$ +MODE <nick> <+|-><modes> + +Usermodes: (* designates that the umode is oper only) + + USERMODE DESCRIPTION +----------------------------------------------------------------- + +o - Designates this client is an IRC Operator. + Use the /oper command to attain this. + +i - Designates this client 'invisible'. + * +w - Can see server wallops. + * +z - Can see oper wallops. + * +l - Can see oper locops (local wallops). + * +s - Can see generic server messages and oper kills. + * +c - Can see client connections and exits. + * +u - Can see unauthorized client connections. + * +j - Can see 'rejected' client notices. + * +k - Can see server kill messages. + * +f - Can see 'I-line is full' notices. + * +y - Can see stats/links/admin requests to name a few. + * +d - Can see server debug messages. + * +n - Can see client nick changes. + +r - User has been registered and identified for its nick. + This mode can be set by servers and services only. + +R - Only registered clients may message you. + * +x - Can see new server introduction and split messages. + * +b - Can see possible bot / join flood warnings. + * +a - Is marked as a server admin in stats p/o. + +D - "deaf": don't receive channel messages + +G - "soft caller id": block private messages from people not on + any common channels with you (unless they are /accept'ed) + +g - "caller id" mode: only allow /accept clients to message you + * +H - Operator status is hidden to other users. diff --git a/help/opers/undline b/help/opers/undline new file mode 100644 index 0000000..0f35931 --- /dev/null +++ b/help/opers/undline @@ -0,0 +1,6 @@ +# $Id$ +UNDLINE <ip> + +Will attempt to undline the given <ip> + +- Requires Oper Priv: U diff --git a/help/opers/ungline b/help/opers/ungline new file mode 100644 index 0000000..16ac875 --- /dev/null +++ b/help/opers/ungline @@ -0,0 +1,9 @@ +# $Id$ +UNGLINE <user@host> + +-- if glines are enabled -- +Will attempt to remove gline matching <user@host> +This will only remove the gline from YOUR server, it +does not try to remove it globally. + +- Requires Oper Privs: G diff --git a/help/opers/unkline b/help/opers/unkline new file mode 100644 index 0000000..e5682a7 --- /dev/null +++ b/help/opers/unkline @@ -0,0 +1,13 @@ +# $Id$ +UNKLINE <user@host> + +Will attempt to unkline the given <user@host> +Will unkline a temporary kline. +If the kline is conf based, the kline will not be removed. + +UNKLINE <user@host> ON irc.server +will unkline the user on irc.server if irc.server accepts +remote unklines. If the kline is conf based, the kline will +not be removed. + +- Requires Oper Priv: U diff --git a/help/opers/unresv b/help/opers/unresv new file mode 100644 index 0000000..440e9f0 --- /dev/null +++ b/help/opers/unresv @@ -0,0 +1,13 @@ +# $Id$ +UNRESV <channel|nick> + +-- Remove a RESV on a channel or nick +Will attempt to remove the resv for the given +channel/nick. If the resv is conf based, the resv +will not be removed. + +UNRESV <channel|nick> ON irc.server +will unresv the <channel|nick> on irc.server if irc.server +accepts remote unresvs. If the resv is conf based, the resv +will not be removed. + diff --git a/help/opers/unxline b/help/opers/unxline new file mode 100644 index 0000000..7a8e93b --- /dev/null +++ b/help/opers/unxline @@ -0,0 +1,11 @@ +# $Id$ +UNXLINE <gecos> + +Removes an XLINE + +UNXLINE <gecos> ON irc.server +will unxline the gecos on irc.server if irc.server accepts +remote unxlines. If the xline is conf based, the xline +will not be removed. + +- Requires Oper Priv: X diff --git a/help/opers/user b/help/opers/user new file mode 100644 index 0000000..f95bcdc --- /dev/null +++ b/help/opers/user @@ -0,0 +1,7 @@ +USER <username> <unused> <unused> :<real name/gecos> + +USER is used during registration to set your gecos +and to set your username if the server cannot get +a valid ident response. The second and third fields +are not used, but there must be something in them. +The reason is backwards compatibility diff --git a/help/opers/userhost b/help/opers/userhost new file mode 100644 index 0000000..f776fcd --- /dev/null +++ b/help/opers/userhost @@ -0,0 +1,10 @@ +USERHOST <nick> + +USERHOST displays the username, hostname, +operator status, and presence of valid ident of +the specified nickname. + +If you use USERHOST on yourself, the hostname +is replaced with the IP you are connecting from. +This is needed to provide DCC support for spoofed +hostnames. diff --git a/help/opers/users b/help/opers/users new file mode 100644 index 0000000..bb56456 --- /dev/null +++ b/help/opers/users @@ -0,0 +1,6 @@ +USERS [remoteserver] + +USERS will display the local and global current +and maximum user statistics for the specified +server, or the local server if there was no +parameter. diff --git a/help/opers/version b/help/opers/version new file mode 100644 index 0000000..9ba8914 --- /dev/null +++ b/help/opers/version @@ -0,0 +1,5 @@ +# $Id$ +VERSION [servername] + +VERSION will display the server version of the specified +server, or the local server if there was no parameter. diff --git a/help/opers/wallops b/help/opers/wallops new file mode 100644 index 0000000..3b6e13c --- /dev/null +++ b/help/opers/wallops @@ -0,0 +1,6 @@ +WALLOPS :<message> + +Sends a WALLOPS message of <message> to all opers +who are umode +z. + +Server sent WALLOPS go to all opers who are umode +w. diff --git a/help/opers/who b/help/opers/who new file mode 100644 index 0000000..d5aa825 --- /dev/null +++ b/help/opers/who @@ -0,0 +1,36 @@ +WHO <#channel|user> + +The WHO command displays information about a user, +such as their GECOS information, their user@host, +whether they are an IRC operator or not, etc. A +sample WHO result from a command issued like +"WHO pokey" may look something like this: + +#lamers pokey H pokey@ppp.newbies.net :0 Jim Jones + +The first field indicates the last channel the user +has joined. The second is the user's nickname. +The third field describes the status information about +the user. The possible combinations for this field +are listed below: + +H - The user is not away. +G - The user is set away. +* - The user is an IRC operator. +@ - The user is a channel op in the channel listed + in the first field. ++ - The user is voiced in the channel listed. +% - The user is a half-op in the channel listed. + +The next field contains the username@host of the user. +The final field displays the number of server hops and +the user's GECOS information. + +This command may be executed on a channel, such as +"WHO #lamers" The output will consist of WHO +listings for each user on the channel. + +This command may also be used in conjunction with wildcards +such as * and ?. + +See also: whois, userhost diff --git a/help/opers/whois b/help/opers/whois new file mode 100644 index 0000000..b45c19b --- /dev/null +++ b/help/opers/whois @@ -0,0 +1,8 @@ +WHOIS [remoteserver|nick] nick + +WHOIS will display detailed user information for +the specified nick. If the first parameter is +specified, WHOIS will display information from +the specified server, or the server that the +user is on. This is how to remotely see +idle time and away status. diff --git a/help/opers/whowas b/help/opers/whowas new file mode 100644 index 0000000..e034dd2 --- /dev/null +++ b/help/opers/whowas @@ -0,0 +1,8 @@ +WHOWAS <nick> + +WHOWAS will show you the last known host and whois +information for the specified nick. Depending on the +number of times they have connected to the network, there +may be more than one listing for a specific user. + +The WHOWAS data will expire after time. diff --git a/help/opers/xline b/help/opers/xline new file mode 100644 index 0000000..f94c673 --- /dev/null +++ b/help/opers/xline @@ -0,0 +1,15 @@ +# $Id$ +XLINE [time] <gecos> :[reason] + +[time] if present, gives number of minutes for XLINE + +Adds a XLINE to the xline.conf file which +will ban the specified gecos from that server. +The banned client will receive a message saying he/she +is banned with reason [reason] + +XLINE [time] <gecos> ON irc.server :[reason] +will xline the gecos on irc.server if irc.server accepts +remote xlines. + +- Requires Oper Priv: X diff --git a/help/users/Makefile.am b/help/users/Makefile.am new file mode 100644 index 0000000..4eb7a19 --- /dev/null +++ b/help/users/Makefile.am @@ -0,0 +1,7 @@ +AUTOMAKE_OPTIONS = foreign + +helpdir = $(pkgdatadir)/help/users + +dist_help_DATA = index info notice privmsg stats umode + +help: $(dist_help_DATA) diff --git a/help/users/Makefile.in b/help/users/Makefile.in new file mode 100644 index 0000000..d76503e --- /dev/null +++ b/help/users/Makefile.in @@ -0,0 +1,466 @@ +# Makefile.in generated by automake 1.12.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = help/users +DIST_COMMON = $(dist_help_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(helpdir)" +DATA = $(dist_help_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBDIR = @LIBDIR@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PREFIX = @PREFIX@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +helpdir = $(pkgdatadir)/help/users +dist_help_DATA = index info notice privmsg stats umode +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign help/users/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign help/users/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-dist_helpDATA: $(dist_help_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_help_DATA)'; test -n "$(helpdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(helpdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(helpdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(helpdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(helpdir)" || exit $$?; \ + done + +uninstall-dist_helpDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_help_DATA)'; test -n "$(helpdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(helpdir)'; $(am__uninstall_files_from_dir) +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(helpdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-dist_helpDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_helpDATA + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_helpDATA install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + uninstall uninstall-am uninstall-dist_helpDATA + + +help: $(dist_help_DATA) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/help/users/index b/help/users/index new file mode 100644 index 0000000..6c076b5 --- /dev/null +++ b/help/users/index @@ -0,0 +1,13 @@ +# $Id$ +Help topics available to users: + +ACCEPT ADMIN AWAY CHALLENGE +CMODE ERROR HELP INFO +INVITE ISON JOIN KICK +KNOCK LINKS LIST LUSERS +MAP MOTD NAMES NICK +NOTICE OPER PART PASS +PING PONG PRIVMSG QUIT +STATS TIME TOPIC UMODE +USER USERHOST USERS VERSION +WHO WHOIS WHOWAS diff --git a/help/users/info b/help/users/info new file mode 100644 index 0000000..d76ed0a --- /dev/null +++ b/help/users/info @@ -0,0 +1,4 @@ +INFO + +INFO displays the copyright, authors and contributors list +for ircd. diff --git a/help/users/notice b/help/users/notice new file mode 100644 index 0000000..7f011a0 --- /dev/null +++ b/help/users/notice @@ -0,0 +1,19 @@ +NOTICE <nick|channel> :message + +NOTICE will send a notice message to the +user or channel specified. + +NOTICE supports the following prefixes for sending +messages to specific clients in a channel: + +@ - channel operators only +% - channel operators and half-ops ++ - operators, half-ops, and voiced users + +The nick can be extended to fit into the following +syntax: + +username@servername + +This syntax is used to securely send a notice to a +service or a bot. diff --git a/help/users/privmsg b/help/users/privmsg new file mode 100644 index 0000000..076f1aa --- /dev/null +++ b/help/users/privmsg @@ -0,0 +1,19 @@ +PRIVMSG <nick|channel> :message + +PRIVMSG will send a standard message to the +user or channel specified. + +PRIVMSG supports the following prefixes for sending +messages to specific clients in a channel: + +@ - channel operators only +% - channel operators and half-ops ++ - operators, half-ops, and voiced users + +The nick can be extended to fit into the following +syntax: + +username@servername + +This syntax is used to securely send a message to a +service or a bot. diff --git a/help/users/stats b/help/users/stats new file mode 100644 index 0000000..4a48098 --- /dev/null +++ b/help/users/stats @@ -0,0 +1,15 @@ +STATS <letter> [server|nick] + +Queries server [server] (or your own server if no +server parameter is given) for info corresponding to +<letter>. + +LETTER +------ (^ = Can be configured to be oper only.) +^ i - Shows I lines +^ K - Shows K lines (or matched klines) +^ k - Shows temporary K lines (or matched temp klines) + m - Shows commands and their usage +^ o - Shows O/o lines + p - Shows opers connected and their idle times + u - Shows server uptime diff --git a/help/users/umode b/help/users/umode new file mode 100644 index 0000000..be515e6 --- /dev/null +++ b/help/users/umode @@ -0,0 +1,14 @@ +# $Id$ +MODE <nick> <+|-><modes> + +Usermodes: + + USERMODE DESCRIPTION +----------------------------------------------------------------- + +o - Designates this client is an IRC Operator. + Use the /oper command to attain this. + +i - Designates this client 'invisible'. + +D - "deaf": don't receive channel messages + +G - "soft caller id": block private messages from people not on + any common channels with you (unless they are /accept'ed) + +g - "caller id" mode: only allow /accept clients to message you diff --git a/include/balloc.h b/include/balloc.h new file mode 100644 index 0000000..7e99788 --- /dev/null +++ b/include/balloc.h @@ -0,0 +1,82 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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 + */ + +/*! \file balloc.h + * \brief A block allocator + * \version $Id$ + * \todo Get rid of all typedefs in this file + */ + +#ifndef INCLUDED_balloc_h +#define INCLUDED_balloc_h + +#include "config.h" +#include "client.h" +#include "ircd_defs.h" + + +/*! \brief Block contains status information for + * an allocated block in our heap. + */ +struct Block +{ + int freeElems; /*!< Number of available elems */ + size_t alloc_size; /*!< Size of data space for each block */ + struct Block* next; /*!< Next in our chain of blocks */ + void* elems; /*!< Points to allocated memory */ + dlink_list free_list; /*!< Chain of free memory blocks */ +}; + +typedef struct Block Block; + +struct MemBlock +{ + dlink_node self; /*!< Node for linking into free_list */ + Block *block; /*!< Which block we belong to */ +}; + +typedef struct MemBlock MemBlock; + +/*! \brief BlockHeap contains the information for the root node of the + * memory heap. + */ +struct BlockHeap +{ + size_t elemSize; /*!< Size of each element to be stored */ + int elemsPerBlock; /*!< Number of elements per block */ + int blocksAllocated; /*!< Number of blocks allocated */ + int freeElems; /*!< Number of free elements */ + Block* base; /*!< Pointer to first block */ + const char *name; /*!< Name of the heap */ + struct BlockHeap *next; /*!< Pointer to next heap */ +}; + +typedef struct BlockHeap BlockHeap; + + +extern int BlockHeapFree(BlockHeap *, void *); +extern void * BlockHeapAlloc(BlockHeap *); + +extern BlockHeap* BlockHeapCreate(const char *const, size_t, int); +extern int BlockHeapDestroy(BlockHeap *); +extern void initBlockHeap(void); +extern void block_heap_report_stats(struct Client *); +#endif /* INCLUDED_balloc_h */ diff --git a/include/channel.h b/include/channel.h new file mode 100644 index 0000000..dca2ff5 --- /dev/null +++ b/include/channel.h @@ -0,0 +1,144 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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 + */ + +/*! \file channel.h + * \brief Responsible for managing channels, members, bans and topics + * \version $Id$ + */ + +#ifndef INCLUDED_channel_h +#define INCLUDED_channel_h + +#include "ircd_defs.h" /* KEYLEN, CHANNELLEN */ + +struct Client; + +/*! \brief Mode structure for channels */ +struct Mode +{ + unsigned int mode; /*!< simple modes */ + unsigned int limit; /*!< +l userlimit */ + char key[KEYLEN + 1]; /*!< +k key */ +}; + +/*! \brief Channel structure */ +struct Channel +{ + dlink_node node; + + struct Channel *hnextch; + struct Mode mode; + + char topic[TOPICLEN + 1]; + char topic_info[USERHOST_REPLYLEN]; + + time_t channelts; + time_t topic_time; + time_t last_knock; /*!< don't allow knock to flood */ + time_t last_join_time; + time_t first_received_message_time; /*!< channel flood control */ + unsigned int flags; + int received_number_of_privmsgs; + + dlink_list members; + dlink_list invites; + dlink_list banlist; + dlink_list exceptlist; + dlink_list invexlist; + + float number_joined; + + char chname[CHANNELLEN + 1]; +}; + +/*! \brief Membership structure */ +struct Membership +{ + dlink_node channode; /*!< link to chptr->members */ + dlink_node usernode; /*!< link to source_p->channel */ + struct Channel *chptr; /*!< Channel pointer */ + struct Client *client_p; /*!< Client pointer */ + unsigned int flags; /*!< user/channel flags, e.g. CHFL_CHANOP */ +}; + +/*! \brief Ban structure. Used for b/e/I n!u\@h masks */ +struct Ban +{ + dlink_node node; + char *name; + char *username; + char *host; + char *who; + size_t len; + time_t when; + struct irc_ssaddr addr; + int bits; + char type; +}; + +extern dlink_list global_channel_list; + +extern int check_channel_name(const char *, int); +extern int can_send(struct Channel *, struct Client *, struct Membership *); +extern int is_banned(const struct Channel *, const struct Client *); +extern int can_join(struct Client *, struct Channel *, const char *); +extern int has_member_flags(struct Membership *, unsigned int); + +extern void remove_ban(struct Ban *, dlink_list *); +extern void init_channels(void); +extern void add_user_to_channel(struct Channel *, struct Client *, + unsigned int, int); +extern void remove_user_from_channel(struct Membership *); +extern void channel_member_names(struct Client *, struct Channel *, int); +extern void add_invite(struct Channel *, struct Client *); +extern void del_invite(struct Channel *, struct Client *); +extern void send_channel_modes(struct Client *, struct Channel *); +extern void channel_modes(struct Channel *, struct Client *, char *, char *); +extern void check_spambot_warning(struct Client *, const char *); +extern void check_splitmode(void *); +extern void free_channel_list(dlink_list *); +extern void destroy_channel(struct Channel *); +extern void set_channel_topic(struct Channel *, const char *, const char *, time_t); + +extern const char *get_member_status(const struct Membership *, int); + +extern struct Channel *make_channel(const char *); +extern struct Membership *find_channel_link(struct Client *, struct Channel *); + +/* channel visible */ +#define ShowChannel(v,c) (PubChannel(c) || IsMember((v),(c))) + +#define IsMember(who, chan) ((find_channel_link(who, chan)) ? 1 : 0) +#define AddMemberFlag(x, y) ((x)->flags |= (y)) +#define DelMemberFlag(x, y) ((x)->flags &= ~(y)) + +#define FLOOD_NOTICED 1 +#define JOIN_FLOOD_NOTICED 2 + +#define SetFloodNoticed(x) ((x)->flags |= FLOOD_NOTICED) +#define IsSetFloodNoticed(x) ((x)->flags & FLOOD_NOTICED) +#define ClearFloodNoticed(x) ((x)->flags &= ~FLOOD_NOTICED) + +#define SetJoinFloodNoticed(x) ((x)->flags |= JOIN_FLOOD_NOTICED) +#define IsSetJoinFloodNoticed(x) ((x)->flags & JOIN_FLOOD_NOTICED) +#define ClearJoinFloodNoticed(x) ((x)->flags &= ~JOIN_FLOOD_NOTICED) + +#endif /* INCLUDED_channel_h */ diff --git a/include/channel_mode.h b/include/channel_mode.h new file mode 100644 index 0000000..2bd8ce6 --- /dev/null +++ b/include/channel_mode.h @@ -0,0 +1,117 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * channel_mode.h: The ircd channel mode header. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + + +#ifndef INCLUDED_channel_mode_h +#define INCLUDED_channel_mode_h + +#include "ircd_defs.h" /* buffer sizes */ + +#define MODEBUFLEN 200 + +/* Maximum mode changes allowed per client, per server is different */ +#define MAXMODEPARAMS 4 + +/* can_send results */ +#define CAN_SEND_NO 0 +#define CAN_SEND_NONOP -1 +#define CAN_SEND_OPV -2 + + +/* Channel related flags */ +#define CHFL_CHANOP 0x0001 /* Channel operator */ +#define CHFL_HALFOP 0x0002 /* Channel half op */ +#define CHFL_VOICE 0x0004 /* the power to speak */ +#define CHFL_DEOPPED 0x0008 /* deopped by us, modes need to be bounced */ +#define CHFL_BAN 0x0010 /* ban channel flag */ +#define CHFL_EXCEPTION 0x0020 /* exception to ban channel flag */ +#define CHFL_INVEX 0x0040 + +/* channel modes ONLY */ +#define MODE_PRIVATE 0x0001 +#define MODE_SECRET 0x0002 +#define MODE_MODERATED 0x0004 +#define MODE_TOPICLIMIT 0x0008 +#define MODE_INVITEONLY 0x0010 +#define MODE_NOPRIVMSGS 0x0020 +#define MODE_SSLONLY 0x0040 +#define MODE_OPERONLY 0x0080 +#define MODE_REGISTERED 0x0100 /* Channel has been registered with ChanServ */ +#define MODE_REGONLY 0x0200 + +/* cache flags for silence on ban */ +#define CHFL_BAN_CHECKED 0x0080 +#define CHFL_BAN_SILENCED 0x0100 + +#define MODE_QUERY 0 +#define MODE_ADD 1 +#define MODE_DEL -1 + +#define CHACCESS_NOTONCHAN -1 +#define CHACCESS_PEON 0 +#define CHACCESS_HALFOP 1 +#define CHACCESS_CHANOP 2 + +/* name invisible */ +#define SecretChannel(x) (((x)->mode.mode & MODE_SECRET)) +#define PubChannel(x) (!SecretChannel(x)) +/* knock is forbidden, halfops can't kick/deop other halfops. + * +pi means paranoid and will generate notices on each invite */ +#define PrivateChannel(x) (((x)->mode.mode & MODE_PRIVATE)) + +struct ChModeChange +{ + char letter; + const char *arg; + const char *id; + int dir; + unsigned int caps; + unsigned int nocaps; + int mems; + struct Client *client; +}; + +struct ChCapCombo +{ + int count; + unsigned int cap_yes; + unsigned int cap_no; +}; + +struct mode_letter +{ + const unsigned int mode; + const unsigned char letter; +}; + +extern const struct mode_letter chan_modes[]; +extern int add_id(struct Client *, struct Channel *, char *, int); +extern void set_channel_mode(struct Client *, struct Client *, struct Channel *, + struct Membership *, int, char **, char *); +extern void clear_ban_cache(struct Channel *); +extern void clear_ban_cache_client(struct Client *); +extern void init_chcap_usage_counts(void); +extern void set_chcap_usage_counts(struct Client *); +extern void unset_chcap_usage_counts(struct Client *); +#endif /* INCLUDED_channel_mode_h */ diff --git a/include/client.h b/include/client.h new file mode 100644 index 0000000..7ac400b --- /dev/null +++ b/include/client.h @@ -0,0 +1,462 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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 + */ + +/*! \file client.h + * \brief Header including structures, macros and prototypes for client handling + * \version $Id$ + */ + + +#ifndef INCLUDED_client_h +#define INCLUDED_client_h + +#include "list.h" +#include "fdlist.h" +#include "config.h" +#include "ircd_defs.h" +#include "dbuf.h" +#include "channel.h" + + +/*! \brief addr_mask_type enumeration */ +enum addr_mask_type +{ + HIDE_IP, /**< IP is hidden. Resolved hostname is shown instead */ + SHOW_IP, /**< IP is shown. No parts of it are hidden or masked */ + MASK_IP /**< IP is masked. 255.255.255.255 is shown instead */ +}; + +/*! \brief Server structure */ +struct Server +{ + dlink_list server_list; /**< Servers on this server */ + dlink_list client_list; /**< Clients on this server */ + char by[NICKLEN + 1]; /**< who activated this connection */ +}; + +/*! \brief ListTask structure */ +struct ListTask +{ + dlink_list show_mask; /**< show these channels.. */ + dlink_list hide_mask; /**< ..and hide these ones */ + + unsigned int hash_index; /**< the bucket we are currently in */ + unsigned int users_min; + unsigned int users_max; + unsigned int created_min; + unsigned int created_max; + unsigned int topicts_min; + unsigned int topicts_max; +}; + +/*! \brief LocalUser structure + * + * Allocated only for local clients, that are directly connected + * to \b this server with a socket. + */ +struct LocalUser +{ + dlink_node lclient_node; + + char client_host[HOSTLEN + 1]; + char client_server[HOSTLEN + 1]; + + unsigned int registration; + unsigned int cap_client; /**< Client capabilities (from us) */ + unsigned int cap_active; /**< Active capabilities (to us) */ + unsigned int caps; /**< capabilities bit-field */ + + unsigned int operflags; /**< IRC Operator privilege flags */ + unsigned int random_ping; /**< Holding a 32bit value used for PING cookies */ + + unsigned int serial; /**< used to enforce 1 send per nick */ + + time_t lasttime; /**< ...should be only LOCAL clients? --msa */ + time_t firsttime; /**< time client was created */ + time_t since; /**< last time we parsed something */ + time_t last_knock; /**< time of last knock */ + time_t last_join_time; /**< when this client last + joined a channel */ + time_t last_leave_time; /**< when this client last + * left a channel */ + int join_leave_count; /**< count of JOIN/LEAVE in less than + MIN_JOIN_LEAVE_TIME seconds */ + int oper_warn_count_down; /**< warn opers of this possible + spambot every time this gets to 0 */ + time_t last_caller_id_time; + time_t first_received_message_time; + time_t last_nick_change; + time_t last_privmsg; /**< Last time we got a PRIVMSG */ + time_t last_away; /**< Away since... */ + + int received_number_of_privmsgs; + unsigned int number_of_nick_changes; + + struct ListTask *list_task; + + struct dbuf_queue buf_sendq; + struct dbuf_queue buf_recvq; + + struct { + unsigned int messages; /**< Statistics: protocol messages sent/received */ + uint64_t bytes; /**< Statistics: total bytes sent/received */ + } recv, send; + + struct AuthRequest *auth; + struct Listener *listener; /**< listener accepted from */ + dlink_list acceptlist; /**< clients I'll allow to talk to me */ + dlink_list watches; /**< chain of Watch pointer blocks */ + dlink_list confs; /**< Configuration record associated */ + dlink_list invited; /**< chain of invite pointer blocks */ + struct irc_ssaddr ip; + int aftype; /**< Makes life easier for DNS res in IPV6 */ + + char *passwd; + fde_t fd; + + /* Anti-flood stuff. We track how many messages were parsed and how + * many we were allowed in the current second, and apply a simple + * decay to avoid flooding. + * -- adrian + */ + int allow_read; /**< how many we're allowed to read in this second */ + int sent_parsed; /**< how many messages we've parsed in this second */ + + char* response; /**< expected response from client */ + char* auth_oper; /**< Operator to become if they supply the response.*/ +}; + +/*! \brief Client structure */ +struct Client +{ + dlink_node node; + dlink_node lnode; /**< Used for Server->servers/users */ + + struct LocalUser *localClient; + struct Client *hnext; /**< For client hash table lookups by name */ + struct Client *idhnext; /**< For SID hash table lookups by sid */ + struct Server *serv; /**< ...defined, if this is a server */ + struct Client *servptr; /**< Points to server this Client is on */ + struct Client *from; /**< == self, if Local Client, *NEVER* NULL! */ + + time_t tsinfo; /**< TS on the nick, SVINFO on server */ + + unsigned int flags; /**< client flags */ + unsigned int umodes; /**< opers, normal users subset */ + unsigned int hopcount; /**< number of servers to this 0 = local */ + unsigned int status; /**< Client type */ + unsigned int handler; /**< Handler index */ + + dlink_list whowas; + dlink_list channel; /**< chain of channel pointer blocks */ + + char away[AWAYLEN + 1]; /**< Client's AWAY message. Can be set/unset via AWAY command */ + char name[HOSTLEN + 1]; /**< unique name for a client nick or host */ + char svid[HOSTLEN + 1]; /**< Services ID. XXX: Going with HOSTLEN for now. NICKLEN might be too small + if dealing with timestamps */ + char id[IDLEN + 1]; /**< client ID, unique ID per client */ + /* + * client->username is the username from ident or the USER message, + * If the client is idented the USER message is ignored, otherwise + * the username part of the USER message is put here prefixed with a + * tilde depending on the auth{} block. Once a client has registered, + * this field should be considered read-only. + */ + char username[USERLEN + 1]; /* client's username */ + + /* + * client->host contains the resolved name or ip address + * as a string for the user, it may be fiddled with for oper spoofing etc. + * once it's changed the *real* address goes away. This should be + * considered a read-only field after the client has registered. + */ + char host[HOSTLEN + 1]; /* client's hostname */ + + /* + * client->info for unix clients will normally contain the info from the + * gcos field in /etc/passwd but anything can go here. + */ + char info[REALLEN + 1]; /* Free form additional client info */ + + /* + * client->sockhost contains the ip address gotten from the socket as a + * string, this field should be considered read-only once the connection + * has been made. (set in s_bsd.c only) + */ + char sockhost[HOSTIPLEN + 1]; /* This is the host name from the + socket ip address as string */ +}; + +/* + * status macros. + */ +#define STAT_CONNECTING 0x01 +#define STAT_HANDSHAKE 0x02 +#define STAT_ME 0x04 +#define STAT_UNKNOWN 0x08 +#define STAT_SERVER 0x10 +#define STAT_CLIENT 0x20 + +#define REG_NEED_USER 0x1 +#define REG_NEED_NICK 0x2 +#define REG_NEED_CAP 0x4 +#define REG_INIT (REG_NEED_USER|REG_NEED_NICK) + +#define HasID(x) ((x)->id[0] != '\0') +#define ID(x) (HasID(x) ? (x)->id : (x)->name) +#define ID_or_name(x,client_p) ((IsCapable(client_p, CAP_TS6) && HasID(x)) ? (x)->id : (x)->name) + +#define IsRegistered(x) ((x)->status > STAT_UNKNOWN) +#define IsConnecting(x) ((x)->status == STAT_CONNECTING) +#define IsHandshake(x) ((x)->status == STAT_HANDSHAKE) +#define IsMe(x) ((x)->status == STAT_ME) +#define IsUnknown(x) ((x)->status == STAT_UNKNOWN) +#define IsServer(x) ((x)->status == STAT_SERVER) +#define IsClient(x) ((x)->status == STAT_CLIENT) + +#define SetConnecting(x) {(x)->status = STAT_CONNECTING; \ + (x)->handler = UNREGISTERED_HANDLER; } + +#define SetHandshake(x) {(x)->status = STAT_HANDSHAKE; \ + (x)->handler = UNREGISTERED_HANDLER; } + +#define SetMe(x) {(x)->status = STAT_ME; \ + (x)->handler = UNREGISTERED_HANDLER; } + +#define SetUnknown(x) {(x)->status = STAT_UNKNOWN; \ + (x)->handler = UNREGISTERED_HANDLER; } + +#define SetServer(x) {(x)->status = STAT_SERVER; \ + (x)->handler = SERVER_HANDLER; } + +#define SetClient(x) {(x)->status = STAT_CLIENT; \ + (x)->handler = HasUMode(x, UMODE_OPER) ? \ + OPER_HANDLER : CLIENT_HANDLER; } + +#define MyConnect(x) ((x)->localClient != NULL) +#define MyClient(x) (MyConnect(x) && IsClient(x)) + +/* + * ts stuff + */ +#define TS_CURRENT 6 /**< current TS protocol version */ +#define TS_MIN 5 /**< minimum supported TS protocol version */ +#define TS_DOESTS 0x20000000 +#define DoesTS(x) ((x)->tsinfo == TS_DOESTS) + + + +#define CAP_MULTI_PREFIX 0x00000001 + +#define HasCap(x, y) ((x)->localClient->cap_active & (y)) + +/* housekeeping flags */ +#define FLAGS_PINGSENT 0x00000001 /**< Unreplied ping sent */ +#define FLAGS_DEADSOCKET 0x00000002 /**< Local socket is dead--Exiting soon */ +#define FLAGS_KILLED 0x00000004 /**< Prevents "QUIT" from being sent for this */ +#define FLAGS_CLOSING 0x00000008 /**< set when closing to suppress errors */ +#define FLAGS_GOTID 0x00000010 /**< successful ident lookup achieved */ +#define FLAGS_NEEDID 0x00000020 /**< auth{} block say must use ident return */ +#define FLAGS_SENDQEX 0x00000040 /**< Sendq exceeded */ +#define FLAGS_IPHASH 0x00000080 /**< iphashed this client */ +#define FLAGS_MARK 0x00000100 /**< marked client */ +#define FLAGS_CANFLOOD 0x00000200 /**< client has the ability to flood */ +#define FLAGS_EXEMPTGLINE 0x00000400 /**< client can't be G-lined */ +#define FLAGS_EXEMPTKLINE 0x00000800 /**< client is exempt from kline */ +#define FLAGS_NOLIMIT 0x00001000 /**< client is exempt from limits */ +#define FLAGS_PING_COOKIE 0x00002000 /**< PING Cookie */ +#define FLAGS_IP_SPOOFING 0x00004000 /**< client IP is spoofed */ +#define FLAGS_FLOODDONE 0x00008000 /**< Flood grace period has been ended. */ +#define FLAGS_EOB 0x00010000 /**< server has sent us an EOB */ +#define FLAGS_HIDDEN 0x00020000 /**< a hidden server. not shown in /links */ +#define FLAGS_BLOCKED 0x00040000 /**< must wait for COMM_SELECT_WRITE */ +#define FLAGS_USERHOST 0x00080000 /**< client is in userhost hash */ +#define FLAGS_BURSTED 0x00100000 /**< user was already bursted */ +#define FLAGS_EXEMPTRESV 0x00200000 /**< client is exempt from RESV */ +#define FLAGS_GOTUSER 0x00400000 /**< if we received a USER command */ +#define FLAGS_PINGWARNING 0x00800000 /**< unreplied ping warning already sent */ +#define FLAGS_FINISHED_AUTH 0x01000000 /**< Client has been released from auth */ +#define FLAGS_FLOOD_NOTICED 0x02000000 /**< Notice to opers about this flooder has been sent */ +#define FLAGS_SERVICE 0x04000000 /**< Client/server is a network service */ + +#define HasFlag(x, y) ((x)->flags & (y)) +#define AddFlag(x, y) ((x)->flags |= (y)) +#define DelFlag(x, y) ((x)->flags &= ~(y)) + + + +/* umodes, settable flags */ +#define UMODE_SERVNOTICE 0x00000001 /**< server notices such as kill */ +#define UMODE_CCONN 0x00000002 /**< Client Connections */ +#define UMODE_REJ 0x00000004 /**< Bot Rejections */ +#define UMODE_SKILL 0x00000008 /**< Server Killed */ +#define UMODE_FULL 0x00000010 /**< Full messages */ +#define UMODE_SPY 0x00000020 /**< see STATS / LINKS */ +#define UMODE_DEBUG 0x00000040 /**< 'debugging' info */ +#define UMODE_NCHANGE 0x00000080 /**< Nick change notice */ +#define UMODE_WALLOP 0x00000100 /**< send wallops to them */ +#define UMODE_OPERWALL 0x00000200 /**< Operwalls */ +#define UMODE_INVISIBLE 0x00000400 /**< makes user invisible */ +#define UMODE_BOTS 0x00000800 /**< shows bots */ +#define UMODE_EXTERNAL 0x00001000 /**< show servers introduced and splitting */ +#define UMODE_CALLERID 0x00002000 /**< block unless caller id's */ +#define UMODE_SOFTCALLERID 0x00004000 /**< block unless on common channel */ +#define UMODE_UNAUTH 0x00008000 /**< show unauth connects here */ +#define UMODE_LOCOPS 0x00010000 /**< show locops */ +#define UMODE_DEAF 0x00020000 /**< don't receive channel messages */ +#define UMODE_CCONN_FULL 0x00040000 /**< add unused fields to connection monitoring */ +#define UMODE_REGISTERED 0x00080000 /**< User has identified for that nick. */ +#define UMODE_REGONLY 0x00100000 /**< Only registered nicks may PM */ +#define UMODE_HIDDEN 0x00200000 /**< Operator status is hidden */ +#define UMODE_OPER 0x00400000 /**< Operator */ +#define UMODE_ADMIN 0x00800000 /**< Admin on server */ + +#define UMODE_ALL UMODE_SERVNOTICE + +#define HasUMode(x, y) ((x)->umodes & (y)) +#define AddUMode(x, y) ((x)->umodes |= (y)) +#define DelUMode(x, y) ((x)->umodes &= ~(y)) + +#define SEND_UMODES (UMODE_INVISIBLE | UMODE_OPER | UMODE_WALLOP |\ + UMODE_REGONLY | UMODE_REGISTERED | UMODE_ADMIN |\ + UMODE_HIDDEN) + + + +/* oper priv flags */ +#define OPER_FLAG_GLOBAL_KILL 0x00000001 /**< Oper can global kill */ +#define OPER_FLAG_REMOTE 0x00000002 /**> Oper can do squits/connects */ +#define OPER_FLAG_UNKLINE 0x00000004 /**< Oper can use unkline */ +#define OPER_FLAG_GLINE 0x00000008 /**< Oper can use gline */ +#define OPER_FLAG_N 0x00000010 /**< Oper can umode n */ +#define OPER_FLAG_K 0x00000020 /**< Oper can kill/kline */ +#define OPER_FLAG_X 0x00000040 /**< Oper can xline */ +#define OPER_FLAG_DIE 0x00000080 /**< Oper can die */ +#define OPER_FLAG_REHASH 0x00000100 /**< Oper can rehash */ +#define OPER_FLAG_ADMIN 0x00000200 /**< Oper can set umode +a */ +#define OPER_FLAG_OPERWALL 0x00000400 /**< Oper can use OPERWALL command */ +#define OPER_FLAG_OPER_SPY 0x00000800 /* */ +#define OPER_FLAG_REMOTEBAN 0x00001000 /**< Oper can set remote bans */ +#define OPER_FLAG_GLOBOPS 0x00002000 /**< Oper can use GLOBOPS command */ +#define OPER_FLAG_MODULE 0x00004000 /**< Oper can use MODULE commands */ +#define OPER_FLAG_RESTART 0x00008000 /**< Oper can use RESTART command */ +#define OPER_FLAG_DLINE 0x00010000 /**< Oper can use DLINE command */ +#define OPER_FLAG_UNDLINE 0x00020000 /**< Oper can use UNDLINE command */ +#define OPER_FLAG_SET 0x00040000 /**< Oper can use SET command */ + +#define HasOFlag(x, y) (MyConnect(x) ? (x)->localClient->operflags & (y) : 0) +#define AddOFlag(x, y) ((x)->localClient->operflags |= (y)) +#define DelOFlag(x, y) ((x)->localClient->operflags &= ~(y)) +#define ClrOFlag(x) ((x)->localClient->operflags = 0) + + + +/* flags macros. */ +#define IsAuthFinished(x) ((x)->flags & FLAGS_FINISHED_AUTH) +#define IsDead(x) ((x)->flags & FLAGS_DEADSOCKET) +#define SetDead(x) ((x)->flags |= FLAGS_DEADSOCKET) +#define IsClosing(x) ((x)->flags & FLAGS_CLOSING) +#define SetClosing(x) ((x)->flags |= FLAGS_CLOSING) +#define SetCanFlood(x) ((x)->flags |= FLAGS_CANFLOOD) +#define IsCanFlood(x) ((x)->flags & FLAGS_CANFLOOD) +#define IsDefunct(x) ((x)->flags & (FLAGS_DEADSOCKET|FLAGS_CLOSING| \ + FLAGS_KILLED)) + +/* oper flags */ +#define MyOper(x) (MyConnect(x) && HasUMode(x, UMODE_OPER)) + +#define SetOper(x) {(x)->umodes |= UMODE_OPER; \ + if (!IsServer((x))) (x)->handler = OPER_HANDLER;} + +#define ClearOper(x) {(x)->umodes &= ~(UMODE_OPER|UMODE_ADMIN); \ + if (!HasUMode(x, UMODE_OPER) && !IsServer((x))) \ + (x)->handler = CLIENT_HANDLER; } + +#define SetSendQExceeded(x) ((x)->flags |= FLAGS_SENDQEX) +#define IsSendQExceeded(x) ((x)->flags & FLAGS_SENDQEX) + +#define SetIpHash(x) ((x)->flags |= FLAGS_IPHASH) +#define ClearIpHash(x) ((x)->flags &= ~FLAGS_IPHASH) +#define IsIpHash(x) ((x)->flags & FLAGS_IPHASH) + +#define SetUserHost(x) ((x)->flags |= FLAGS_USERHOST) +#define ClearUserHost(x) ((x)->flags &= ~FLAGS_USERHOST) +#define IsUserHostIp(x) ((x)->flags & FLAGS_USERHOST) + +#define SetPingSent(x) ((x)->flags |= FLAGS_PINGSENT) +#define IsPingSent(x) ((x)->flags & FLAGS_PINGSENT) +#define ClearPingSent(x) ((x)->flags &= ~FLAGS_PINGSENT) + +#define SetPingWarning(x) ((x)->flags |= FLAGS_PINGWARNING) +#define IsPingWarning(x) ((x)->flags & FLAGS_PINGWARNING) +#define ClearPingWarning(x) ((x)->flags &= ~FLAGS_PINGWARNING) + +#define SetNeedId(x) ((x)->flags |= FLAGS_NEEDID) +#define IsNeedId(x) ((x)->flags & FLAGS_NEEDID) + +#define SetGotId(x) ((x)->flags |= FLAGS_GOTID) +#define IsGotId(x) ((x)->flags & FLAGS_GOTID) + +#define IsExemptKline(x) ((x)->flags & FLAGS_EXEMPTKLINE) +#define SetExemptKline(x) ((x)->flags |= FLAGS_EXEMPTKLINE) +#define IsExemptLimits(x) ((x)->flags & FLAGS_NOLIMIT) +#define SetExemptLimits(x) ((x)->flags |= FLAGS_NOLIMIT) +#define IsExemptGline(x) ((x)->flags & FLAGS_EXEMPTGLINE) +#define SetExemptGline(x) ((x)->flags |= FLAGS_EXEMPTGLINE) +#define IsExemptResv(x) ((x)->flags & FLAGS_EXEMPTRESV) +#define SetExemptResv(x) ((x)->flags |= FLAGS_EXEMPTRESV) +#define SetIPSpoof(x) ((x)->flags |= FLAGS_IP_SPOOFING) +#define IsIPSpoof(x) ((x)->flags & FLAGS_IP_SPOOFING) + +#define IsFloodDone(x) ((x)->flags & FLAGS_FLOODDONE) +#define SetFloodDone(x) ((x)->flags |= FLAGS_FLOODDONE) +#define HasPingCookie(x) ((x)->flags & FLAGS_PING_COOKIE) +#define SetPingCookie(x) ((x)->flags |= FLAGS_PING_COOKIE) +#define IsHidden(x) ((x)->flags & FLAGS_HIDDEN) +#define SetHidden(x) ((x)->flags |= FLAGS_HIDDEN) + +#define IsSendqBlocked(x) ((x)->flags & FLAGS_BLOCKED) +#define SetSendqBlocked(x) ((x)->flags |= FLAGS_BLOCKED) +#define ClearSendqBlocked(x) ((x)->flags &= ~FLAGS_BLOCKED) + + +extern struct Client me; +extern dlink_list listing_client_list; +extern dlink_list global_client_list; + +extern int accept_message(struct Client *, struct Client *); +extern struct split_nuh_item *find_accept(const char *, const char *, + const char *, struct Client *, int); +extern void del_accept(struct split_nuh_item *, struct Client *); +extern void del_all_accepts(struct Client *); +extern void exit_client(struct Client *, struct Client *, const char *); +extern void check_conf_klines(void); +extern void init_client(void); +extern void dead_link_on_write(struct Client *, int); +extern void dead_link_on_read(struct Client *, int); +extern void exit_aborted_clients(void); +extern void free_exited_clients(void); +extern struct Client *make_client(struct Client *); +extern struct Client *find_chasing(struct Client *, struct Client *, const char *, int *); +extern struct Client *find_person(const struct Client *const, const char *); +extern const char *get_client_name(const struct Client *, enum addr_mask_type); + +#endif /* INCLUDED_client_h */ diff --git a/include/conf.h b/include/conf.h new file mode 100644 index 0000000..4cb80e7 --- /dev/null +++ b/include/conf.h @@ -0,0 +1,494 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * conf.h: A header for the configuration functions. + * + * Copyright (C) 2005 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_s_conf_h +#define INCLUDED_s_conf_h +#include "config.h" +#ifdef HAVE_LIBCRYPTO +#include <openssl/rsa.h> +#endif +#include "ircd_defs.h" +#include "motd.h" /* MessageFile */ +#include "client.h" +#include "hook.h" + + +struct Client; + +extern struct Callback *client_check_cb; + +struct conf_parser_context +{ + unsigned int boot; + unsigned int pass; + FILE *conf_file; +}; + +extern struct conf_parser_context conf_parser_ctx; + +typedef enum +{ + CONF_TYPE, + CLASS_TYPE, + OPER_TYPE, + CLIENT_TYPE, + SERVER_TYPE, + HUB_TYPE, + LEAF_TYPE, + KLINE_TYPE, + DLINE_TYPE, + EXEMPTDLINE_TYPE, + CLUSTER_TYPE, + RKLINE_TYPE, + RXLINE_TYPE, + XLINE_TYPE, + ULINE_TYPE, + GLINE_TYPE, + CRESV_TYPE, + NRESV_TYPE, + SERVICE_TYPE +} ConfType; + +struct split_nuh_item +{ + dlink_node node; + + char *nuhmask; + char *nickptr; + char *userptr; + char *hostptr; + + size_t nicksize; + size_t usersize; + size_t hostsize; +}; + +struct ConfItem +{ + dlink_node node; /* link into known ConfItems of this type */ + + char *name; /* Primary key */ + void *regexpname; + unsigned int flags; + ConfType type; +}; + +/* + * MatchItem - used for XLINE and ULINE types + */ +struct MatchItem +{ + char *user; /* Used for ULINE only */ + char *host; /* Used for ULINE only */ + char *reason; + char *oper_reason; + int action; /* used for uline */ + int count; /* How many times this matchitem has been matched */ + int ref_count; /* How many times is this matchitem in use */ + int illegal; /* Should it be deleted when possible? */ + time_t hold; /* Hold action until this time (calendar time) */ +}; + +struct AccessItem +{ + dlink_node node; + unsigned int dns_failed; + unsigned int dns_pending; + unsigned int status; /* If CONF_ILLEGAL, delete when no clients */ + unsigned int flags; + unsigned int modes; + unsigned int port; + int clients; /* Number of *LOCAL* clients using this */ + int bits; + int type; + struct irc_ssaddr bind; /* ip to bind to for outgoing connect */ + struct irc_ssaddr addr; /* ip to connect to */ + char * host; /* host part of user@host */ + char * passwd; + char * spasswd; /* Password to send. */ + char * reason; + char * oper_reason; + char * user; /* user part of user@host */ + time_t hold; /* Hold action until this time (calendar time) */ + struct ConfItem *class_ptr; /* Class of connection */ + int aftype; +#ifdef HAVE_LIBCRYPTO + /* certs */ + char *cipher_list; + char * rsa_public_key_file; + RSA * rsa_public_key; +#endif + void *regexuser; + void *regexhost; + dlink_list leaf_list; + dlink_list hub_list; +}; + +struct ClassItem +{ + dlink_list list_ipv4; /* base of per cidr ipv4 client link list */ + dlink_list list_ipv6; /* base of per cidr ipv6 client link list */ + unsigned int max_sendq; + unsigned int max_recvq; + int con_freq; + int ping_freq; + int ping_warning; + int max_total; + int max_local; + int max_global; + int max_ident; + int max_perip; + int curr_user_count; + int cidr_bitlen_ipv4; + int cidr_bitlen_ipv6; + int number_per_cidr; + int active; +}; + +struct CidrItem +{ + dlink_node node; + struct irc_ssaddr mask; + int number_on_this_cidr; +}; + + +#define CONF_ILLEGAL 0x80000000 +#define CONF_RESERVED 0x00000001 +#define CONF_CLIENT 0x00000002 +#define CONF_SERVER 0x00000004 +#define CONF_OPERATOR 0x00000008 +#define CONF_KLINE 0x00000010 +#define CONF_CLASS 0x00000020 +#define CONF_DLINE 0x00000040 +#define CONF_XLINE 0x00000080 +#define CONF_ULINE 0x00000100 +#define CONF_EXEMPTDLINE 0x00000200 +#define CONF_GLINE 0x00000400 +#define CONF_SERVICE 0x00000800 + +#define CONF_SERVER_MASK CONF_SERVER +#define CONF_CLIENT_MASK (CONF_CLIENT | CONF_OPERATOR | CONF_SERVER_MASK) + +/* XXX temporary hack */ +#define CONF_CRESV 0x80000001 +#define CONF_NRESV 0x80000002 + +#define IsConfIllegal(x) ((x)->status & CONF_ILLEGAL) +#define SetConfIllegal(x) ((x)->status |= CONF_ILLEGAL) +#define IsConfServer(x) ((x)->status == CONF_SERVER) +#define SetConfServer(x) ((x)->status = CONF_SERVER) +#define IsConfOperator(x) ((x)->status & CONF_OPERATOR) +#define IsConfKill(x) ((x)->status == CONF_KLINE) +#define IsConfClient(x) ((x)->status & CONF_CLIENT) +#define IsConfUline(x) ((x)->status & CONF_ULINE) +#define IsConfXline(x) ((x)->status & CONF_XLINE) +#define IsConfGline(x) ((x)->status == CONF_GLINE) + +/* AccessItem->flags */ + +/* Generic flags... */ +/* access flags... */ +#define CONF_FLAGS_DO_IDENTD 0x00000001 +#define CONF_FLAGS_LIMIT_IP 0x00000002 +#define CONF_FLAGS_NO_TILDE 0x00000004 +#define CONF_FLAGS_NEED_IDENTD 0x00000008 +#define CONF_FLAGS_NOMATCH_IP 0x00000010 +#define CONF_FLAGS_EXEMPTKLINE 0x00000020 +#define CONF_FLAGS_NOLIMIT 0x00000040 +#define CONF_FLAGS_SPOOF_IP 0x00000080 +#define CONF_FLAGS_SPOOF_NOTICE 0x00000100 +#define CONF_FLAGS_REDIR 0x00000200 +#define CONF_FLAGS_EXEMPTGLINE 0x00000400 +#define CONF_FLAGS_CAN_FLOOD 0x00000800 +#define CONF_FLAGS_NEED_PASSWORD 0x00001000 +/* server flags */ +#define CONF_FLAGS_ALLOW_AUTO_CONN 0x00002000 +#define CONF_FLAGS_ENCRYPTED 0x00004000 +#define CONF_FLAGS_TEMPORARY 0x00008000 +#define CONF_FLAGS_EXEMPTRESV 0x00010000 +#define CONF_FLAGS_SSL 0x00020000 + +/* Macros for struct AccessItem */ +#define IsLimitIp(x) ((x)->flags & CONF_FLAGS_LIMIT_IP) +#define IsNoTilde(x) ((x)->flags & CONF_FLAGS_NO_TILDE) +#define IsConfCanFlood(x) ((x)->flags & CONF_FLAGS_CAN_FLOOD) +#define IsNeedPassword(x) ((x)->flags & CONF_FLAGS_NEED_PASSWORD) +#define IsNeedIdentd(x) ((x)->flags & CONF_FLAGS_NEED_IDENTD) +#define IsNoMatchIp(x) ((x)->flags & CONF_FLAGS_NOMATCH_IP) +#define IsConfExemptKline(x) ((x)->flags & CONF_FLAGS_EXEMPTKLINE) +#define IsConfExemptLimits(x) ((x)->flags & CONF_FLAGS_NOLIMIT) +#define IsConfExemptGline(x) ((x)->flags & CONF_FLAGS_EXEMPTGLINE) +#define IsConfExemptResv(x) ((x)->flags & CONF_FLAGS_EXEMPTRESV) +#define IsConfDoIdentd(x) ((x)->flags & CONF_FLAGS_DO_IDENTD) +#define IsConfDoSpoofIp(x) ((x)->flags & CONF_FLAGS_SPOOF_IP) +#define IsConfSpoofNotice(x) ((x)->flags & CONF_FLAGS_SPOOF_NOTICE) +#define IsConfEncrypted(x) ((x)->flags & CONF_FLAGS_ENCRYPTED) +#define SetConfEncrypted(x) ((x)->flags |= CONF_FLAGS_ENCRYPTED) +#define ClearConfEncrypted(x) ((x)->flags &= ~CONF_FLAGS_ENCRYPTED) +#define IsConfAllowAutoConn(x) ((x)->flags & CONF_FLAGS_ALLOW_AUTO_CONN) +#define SetConfAllowAutoConn(x) ((x)->flags |= CONF_FLAGS_ALLOW_AUTO_CONN) +#define ClearConfAllowAutoConn(x) ((x)->flags &= ~CONF_FLAGS_ALLOW_AUTO_CONN) +#define IsConfTemporary(x) ((x)->flags & CONF_FLAGS_TEMPORARY) +#define SetConfTemporary(x) ((x)->flags |= CONF_FLAGS_TEMPORARY) +#define IsConfRedir(x) ((x)->flags & CONF_FLAGS_REDIR) +#define IsConfSSL(x) ((x)->flags & CONF_FLAGS_SSL) +#define SetConfSSL(x) ((x)->flags |= CONF_FLAGS_SSL) +#define ClearConfSSL(x) ((x)->flags &= ~CONF_FLAGS_SSL) + +/* shared/cluster server entry types + * These defines are used for both shared and cluster. + */ +#define SHARED_KLINE 0x0001 +#define SHARED_UNKLINE 0x0002 +#define SHARED_XLINE 0x0004 +#define SHARED_UNXLINE 0x0008 +#define SHARED_RESV 0x0010 +#define SHARED_UNRESV 0x0020 +#define SHARED_LOCOPS 0x0040 +#define SHARED_DLINE 0x0080 +#define SHARED_UNDLINE 0x0100 +#define SHARED_ALL (SHARED_KLINE | SHARED_UNKLINE |\ + SHARED_XLINE | SHARED_UNXLINE |\ + SHARED_RESV | SHARED_UNRESV |\ + SHARED_LOCOPS | SHARED_DLINE | SHARED_UNDLINE) + +struct config_file_entry +{ + const char *dpath; /* DPATH if set from command line */ + const char *configfile; + const char *klinefile; + const char *xlinefile; + const char *dlinefile; + const char *cresvfile; + const char *nresvfile; + + char *egdpool_path; + char *service_name; + + MessageFile motd; + MessageFile linksfile; + + int gline_min_cidr; + int gline_min_cidr6; + int dots_in_ident; + int failed_oper_notice; + int anti_spam_exit_message_time; + unsigned int max_accept; + unsigned int max_watch; + int max_nick_time; + unsigned int max_nick_changes; + int ts_max_delta; + int ts_warn_delta; + int anti_nick_flood; + int warn_no_nline; + int invisible_on_connect; + int stats_e_disabled; + int stats_o_oper_only; + int stats_k_oper_only; + int stats_i_oper_only; + int stats_P_oper_only; + int short_motd; + int no_oper_flood; + int true_no_oper_flood; + int oper_pass_resv; + int glines; + int hide_spoof_ips; + int tkline_expire_notices; + int opers_bypass_callerid; + int ignore_bogus_ts; + int pace_wait; + int pace_wait_simple; + int gline_time; + int gline_request_time; + int oper_only_umodes; + int oper_umodes; + int max_targets; + int caller_id_wait; + int min_nonwildcard; + int min_nonwildcard_simple; + int kill_chase_time_limit; + int default_floodcount; + /* 0 == don't use throttle... */ + int throttle_time; + int use_egd; + int ping_cookie; + int disable_auth; + int disable_remote; +}; + +struct config_channel_entry +{ + int disable_fake_channels; + int restrict_channels; + int knock_delay; + int knock_delay_channel; + unsigned int max_bans; + unsigned int max_chans_per_user; + unsigned int max_chans_per_oper; + int no_create_on_split; + int no_join_on_split; + int quiet_on_ban; + int default_split_server_count; + int default_split_user_count; +}; + +struct config_server_hide +{ + char *hidden_name; + int flatten_links; + int hide_servers; + int links_delay; + int links_disabled; + int hidden; + int hide_server_ips; +}; + +struct server_info +{ + char *sid; + char *name; + char *description; + char *network_name; + char *network_desc; +#ifdef HAVE_LIBCRYPTO + char *rsa_private_key_file; + RSA *rsa_private_key; + SSL_CTX *server_ctx; + SSL_CTX *client_ctx; +#endif + int hub; + struct irc_ssaddr ip; + struct irc_ssaddr ip6; + unsigned int max_clients; + int specific_ipv4_vhost; + int specific_ipv6_vhost; + struct sockaddr_in dns_host; + int can_use_v6; +}; + +struct admin_info +{ + char *name; + char *description; + char *email; +}; + +struct logging_entry +{ + unsigned int use_logging; +}; + +extern dlink_list class_items; +extern dlink_list server_items; +extern dlink_list cluster_items; +extern dlink_list hub_items; +extern dlink_list rxconf_items; +extern dlink_list rkconf_items; +extern dlink_list leaf_items; +extern dlink_list service_items; +extern dlink_list temporary_xlines; +extern struct logging_entry ConfigLoggingEntry; +extern struct config_file_entry ConfigFileEntry;/* defined in ircd.c*/ +extern struct config_channel_entry ConfigChannel;/* defined in channel.c*/ +extern struct config_server_hide ConfigServerHide; /* defined in s_conf.c */ +extern struct server_info ServerInfo; /* defined in ircd.c */ +extern struct admin_info AdminInfo; /* defined in ircd.c */ +extern int valid_wild_card(struct Client *, int, int, ...); +/* End GLOBAL section */ + +extern unsigned int get_sendq(struct Client *); +extern unsigned int get_recvq(struct Client *); +extern const char *get_client_class(struct Client *); +extern int get_client_ping(struct Client *, int *); +extern void check_class(void); +extern void init_class(void); +extern struct ConfItem *find_class(const char *); +extern void init_ip_hash_table(void); +extern void count_ip_hash(unsigned int *, uint64_t *); +extern void remove_one_ip(struct irc_ssaddr *); +extern struct ConfItem *make_conf_item(ConfType type); +extern void free_access_item(struct AccessItem *); +extern void read_conf_files(int); +extern int attach_conf(struct Client *, struct ConfItem *); +extern int attach_connect_block(struct Client *, const char *, const char *); + +extern int detach_conf(struct Client *, ConfType); + +extern struct ConfItem *find_conf_name(dlink_list *, const char *, ConfType); +extern struct ConfItem *find_conf_exact(ConfType, const char *, const char *, const char *); +extern struct AccessItem *find_kill(struct Client *); +extern struct AccessItem *find_gline(struct Client *); +extern int conf_connect_allowed(struct irc_ssaddr *, int); +extern char *oper_privs_as_string(const unsigned int); +extern void split_nuh(struct split_nuh_item *); +extern struct ConfItem *find_matching_name_conf(ConfType, const char *, + const char *, const char *, int); +extern struct ConfItem *find_exact_name_conf(ConfType, const struct Client *, const char *, + const char *, const char *); +extern void delete_conf_item(struct ConfItem *); +extern void report_confitem_types(struct Client *, ConfType); +extern void yyerror(const char *); +extern void write_conf_line(struct Client *, struct ConfItem *, + const char *, time_t); +extern int remove_conf_line(ConfType, struct Client *, const char *, + const char *); +extern void add_temp_line(struct ConfItem *); +extern void cleanup_tklines(void *); +extern const char *get_conf_name(ConfType); +extern int rehash(int); +extern int conf_add_server(struct ConfItem *, const char *); +extern void conf_add_class_to_conf(struct ConfItem *, const char *); + +/* XXX consider moving these into csvlib.h */ +extern void parse_csv_file(FILE *, ConfType); +extern int find_and_delete_temporary(const char *, const char *, int); +extern const char *get_oper_name(const struct Client *); + +extern void *map_to_conf(struct ConfItem *); +extern struct ConfItem *unmap_conf_item(void *); +/* XXX should the parse_aline stuff go into another file ?? */ +#define AWILD 0x1 /* check wild cards */ +extern int parse_aline(const char *, struct Client *, int, char **, + int, char **, char **, time_t *, char **, char **); +extern int valid_comment(struct Client *, char *, int); + + +#define TK_SECONDS 0 +#define TK_MINUTES 1 +extern time_t valid_tkline(const char *, int); +extern int match_conf_password(const char *, const struct AccessItem *); + +#define NOT_AUTHORIZED (-1) +#define I_LINE_FULL (-2) +#define TOO_MANY (-3) +#define BANNED_CLIENT (-4) +#define TOO_FAST (-5) + +#define CLEANUP_TKLINES_TIME 60 + +extern void cluster_a_line(struct Client *, + const char *, int, int, const char *,...); +extern void rebuild_cidr_class(struct ConfItem *, struct ClassItem *); +#endif /* INCLUDED_s_conf_h */ diff --git a/include/dbuf.h b/include/dbuf.h new file mode 100644 index 0000000..6c580b9 --- /dev/null +++ b/include/dbuf.h @@ -0,0 +1,48 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * dbuf.h: A header for the dynamic buffers functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef __DBUF_H_INCLUDED +#define __DBUF_H_INCLUDED + +#define DBUF_BLOCK_SIZE 1024 /* this is also our MTU used for sending */ + +#define dbuf_length(x) ((x)->total_size) +#define dbuf_clear(x) dbuf_delete(x, dbuf_length(x)) + +struct dbuf_block +{ + size_t size; + char data[DBUF_BLOCK_SIZE]; +}; + +struct dbuf_queue +{ + dlink_list blocks; + size_t total_size; +}; + +extern void dbuf_init(void); +extern void dbuf_put(struct dbuf_queue *, char *, size_t); +extern void dbuf_delete(struct dbuf_queue *, size_t); +#endif diff --git a/include/defaults.h b/include/defaults.h new file mode 100644 index 0000000..038bc87 --- /dev/null +++ b/include/defaults.h @@ -0,0 +1,136 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * defaults.h: The ircd defaults header for values and paths. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_defaults_h +#define INCLUDED_defaults_h + +/* Here are some default paths. Most except DPATH are + * configurable at runtime. */ + +/* + * Directory paths and filenames for UNIX systems. + * PREFIX is set using ./configure --prefix, see INSTALL. + * The other defaults should be fine. + * + * NOTE: CHANGING THESE WILL NOT ALTER THE DIRECTORY THAT FILES WILL + * BE INSTALLED TO. IF YOU CHANGE THESE, DO NOT USE MAKE INSTALL, + * BUT COPY THE FILES MANUALLY TO WHERE YOU WANT THEM. + * + * PREFIX = prefix for all directories + * DPATH = root directory of installation + * BINPATH = directory for binary files + * MSGPATH = directory for language files + * ETCPATH = directory for configuration files + * LOGPATH = directory for logfiles + * MODPATH = directory for modules + * AUTOMODPATH = directory for autoloaded modules + */ + +/* dirs */ +#define DPATH PREFIX +#define SBINPATH PREFIX "/sbin/" +#define BINPATH PREFIX "/bin/" +#define MSGPATH DATADIR "/" PACKAGE "/messages" +#define MODPATH LIBDIR "/" PACKAGE "/modules/" +#define HPATH DATADIR "/" PACKAGE "/help/opers" +#define UHPATH DATADIR "/" PACKAGE "/help/users" +#define AUTOMODPATH MODPATH "/autoload/" +#define ETCPATH SYSCONFDIR +#define LOGPATH LOCALSTATEDIR "/log" + +/* files */ +#define SPATH SBINPATH "/ircd" /* ircd executable */ +#define CPATH ETCPATH "/ircd.conf" /* ircd.conf file */ +#define KPATH ETCPATH "/kline.conf" /* kline file */ +#define CRESVPATH ETCPATH "/cresv.conf" /* channel resvs file */ +#define NRESVPATH ETCPATH "/nresv.conf" /* nick resvs file */ +#define DLPATH ETCPATH "/dline.conf" /* dline file */ +#define XPATH ETCPATH "/xline.conf" /* xline file */ +#define MPATH ETCPATH "/ircd.motd" /* MOTD file */ +#define LPATH LOGPATH "/ircd.log" /* ircd logfile */ +#define PPATH LOCALSTATEDIR "/ircd.pid" /* pid file */ +#define LIPATH ETCPATH "/links.txt" /* cached links file */ + +/* + * This file is included to supply default values for things which + * are now configurable at runtime. + */ + +#define HYBRID_SOMAXCONN 25 +#define MAX_TDKLINE_TIME (24*60*360) + +/* tests show that about 7 fds are not registered by fdlist.c, these + * include std* descriptors + some others (by OpenSSL etc.). Note this is + * intentionally too high, we don't want to eat fds up to the last one */ +#define LEAKED_FDS 10 +/* how many (privileged) clients can exceed max_clients */ +#define MAX_BUFFER 60 + +#define MAXCLIENTS_MAX (hard_fdlimit - LEAKED_FDS - MAX_BUFFER) +#define MAXCLIENTS_MIN 32 + +/* class {} default values */ +#define DEFAULT_SENDQ 9000000 /* default max SendQ */ +#define DEFAULT_RECVQ 2560 /* default max RecvQ */ +#define PORTNUM 6667 /* default outgoing portnum */ +#define DEFAULT_PINGFREQUENCY 120 /* Default ping frequency */ +#define DEFAULT_CONNECTFREQUENCY 600 /* Default connect frequency */ +#define CLIENT_FLOOD_MAX 8000 +#define CLIENT_FLOOD_MIN 512 + +#define WATCHSIZE_MIN 1 +#define WATCHSIZE_DEFAULT 32 +#define TS_MAX_DELTA_MIN 10 /* min value for ts_max_delta */ +#define TS_MAX_DELTA_DEFAULT 600 /* default for ts_max_delta */ +#define TS_WARN_DELTA_MIN 10 /* min value for ts_warn_delta */ +#define TS_WARN_DELTA_DEFAULT 30 /* default for ts_warn_delta */ + +/* ServerInfo default values */ +#define NETWORK_NAME_DEFAULT "EFnet" /* default for network_name */ +#define NETWORK_DESC_DEFAULT "Eris Free Network" /* default for network_desc */ +#define SERVICE_NAME_DEFAULT "service.someserver" + +#define GLINE_REQUEST_EXPIRE_DEFAULT 600 + +/* General defaults */ +#define MAXIMUM_LINKS_DEFAULT 0 /* default for maximum_links */ + +#define LINKS_DELAY_DEFAULT 300 + +#define MAX_TARGETS_DEFAULT 4 /* default for max_targets */ + +#define INIT_LOG_LEVEL L_NOTICE /* default for log_level */ + +#define CONNECTTIMEOUT 30 /* Recommended value: 30 */ +#define IDENT_TIMEOUT 10 + +#define MIN_JOIN_LEAVE_TIME 60 +#define MAX_JOIN_LEAVE_COUNT 25 +#define OPER_SPAM_COUNTDOWN 5 +#define JOIN_LEAVE_COUNT_EXPIRE_TIME 120 + +#define MIN_SPAM_NUM 5 +#define MIN_SPAM_TIME 60 + +#endif /* INCLUDED_defaults_h */ diff --git a/include/event.h b/include/event.h new file mode 100644 index 0000000..f9b6ab0 --- /dev/null +++ b/include/event.h @@ -0,0 +1,57 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * event.h: The ircd event header. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_event_h +#define INCLUDED_event_h + +/* + * How many event entries we need to allocate at a time in the block + * allocator. 16 should be plenty at a time. + */ +#define MAX_EVENTS 50 + + +typedef void EVH(void *); + +/* The list of event processes */ +struct ev_entry +{ + EVH *func; + void *arg; + const char *name; + time_t frequency; + time_t when; + int active; +}; + +extern void eventAdd(const char *, EVH *, void *, time_t); +extern void eventAddIsh(const char *, EVH *, void *, time_t); +extern void eventRun(void); +extern time_t eventNextTime(void); +extern void eventInit(void); +extern void eventDelete(EVH *, void *); +extern void set_back_events(time_t); +extern void show_events(struct Client *); + +#endif /* INCLUDED_event_h */ diff --git a/include/fdlist.h b/include/fdlist.h new file mode 100644 index 0000000..06313ec --- /dev/null +++ b/include/fdlist.h @@ -0,0 +1,113 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * fdlist.h: The file descriptor list header. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_fdlist_h +#define INCLUDED_fdlist_h +#define FILEIO_V2 + +#include "ircd_defs.h" +#define FD_DESC_SZ 128 /* hostlen + comment */ + +enum { + COMM_OK, + COMM_ERR_BIND, + COMM_ERR_DNS, + COMM_ERR_TIMEOUT, + COMM_ERR_CONNECT, + COMM_ERROR, + COMM_ERR_MAX +}; + +struct _fde; +struct Client; + +/* Callback for completed IO events */ +typedef void PF(struct _fde *, void *); + +/* Callback for completed connections */ +/* int fd, int status, void * */ +typedef void CNCB(struct _fde *, int, void *); + +typedef struct _fde { + /* New-school stuff, again pretty much ripped from squid */ + /* + * Yes, this gives us only one pending read and one pending write per + * filedescriptor. Think though: when do you think we'll need more? + */ + int fd; /* So we can use the fde_t as a callback ptr */ + int comm_index; /* where in the poll list we live */ + int evcache; /* current fd events as set up by the underlying I/O */ + char desc[FD_DESC_SZ]; + PF *read_handler; + void *read_data; + PF *write_handler; + void *write_data; + PF *timeout_handler; + void *timeout_data; + time_t timeout; + PF *flush_handler; + void *flush_data; + time_t flush_timeout; + + struct { + unsigned int open:1; + unsigned int is_socket:1; +#ifdef HAVE_LIBCRYPTO + unsigned int pending_read:1; +#endif + } flags; + + struct { + /* We don't need the host here ? */ + struct irc_ssaddr S; + struct irc_ssaddr hostaddr; + CNCB *callback; + void *data; + /* We'd also add the retry count here when we get to that -- adrian */ + } connect; +#ifdef HAVE_LIBCRYPTO + SSL *ssl; +#endif + struct _fde *hnext; +} fde_t; + +#define FD_HASH_SIZE CLIENT_HEAP_SIZE + +extern int number_fd; +extern int hard_fdlimit; +extern fde_t *fd_hash[]; +extern fde_t *fd_next_in_loop; +extern struct Callback *fdlimit_cb; + +extern void fdlist_init(void); +extern fde_t *lookup_fd(int); +extern void fd_open(fde_t *, int, int, const char *); +extern void fd_close(fde_t *); +extern void fd_dump(struct Client *); +extern void fd_note(fde_t *, const char *, ...); +extern void close_standard_fds(void); +extern void close_fds(fde_t *); +extern void recalc_fdlimit(void *); + +#endif /* INCLUDED_fdlist_h */ diff --git a/include/hash.h b/include/hash.h new file mode 100644 index 0000000..a75815f --- /dev/null +++ b/include/hash.h @@ -0,0 +1,70 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * hash.h: A header for the ircd hashtable code. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_hash_h +#define INCLUDED_hash_h + +#define FNV1_32_INIT 0x811c9dc5 +#define FNV1_32_BITS 16 +#define FNV1_32_SIZE (1 << FNV1_32_BITS) /* 2^16 = 65536 */ +#define HASHSIZE FNV1_32_SIZE + +struct Client; +struct Channel; +struct ResvChannel; +struct UserHost; + +enum { + HASH_TYPE_ID, + HASH_TYPE_CLIENT, + HASH_TYPE_CHANNEL, + HASH_TYPE_USERHOST, + HASH_TYPE_RESERVED +}; + +extern void init_hash(void); +extern void hash_add_client(struct Client *); +extern void hash_del_client(struct Client *); +extern void hash_add_channel(struct Channel *); +extern void hash_del_channel(struct Channel *); +extern void hash_add_resv(struct ResvChannel *); +extern void hash_del_resv(struct ResvChannel *); +extern void hash_add_id(struct Client *); +extern void hash_del_id(struct Client *); +extern void hash_add_userhost(struct UserHost *); +extern void hash_del_userhost(struct UserHost *); + +extern struct UserHost *hash_find_userhost(const char *); +extern struct Client *hash_find_id(const char *); +extern struct Client *hash_find_client(const char *); +extern struct Client *hash_find_server(const char *); +extern struct Channel *hash_find_channel(const char *); +extern void *hash_get_bucket(int, unsigned int); +extern struct ResvChannel *hash_find_resv(const char *); + +extern void free_list_task(struct ListTask *, struct Client *); +extern void safe_list_channels(struct Client *, struct ListTask *, int); + +extern unsigned int strhash(const char *); +#endif /* INCLUDED_hash_h */ diff --git a/include/hook.h b/include/hook.h new file mode 100644 index 0000000..93ecfb6 --- /dev/null +++ b/include/hook.h @@ -0,0 +1,53 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * hook.h: A header for the hooks into parts of ircd. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef __HOOK_H_INCLUDED +#define __HOOK_H_INCLUDED + +#define HOOK_V2 + +typedef void *CBFUNC(va_list); + +struct Callback +{ + char *name; + dlink_list chain; + dlink_node node; + unsigned int called; + time_t last; +}; + +struct Client; + +extern struct Callback *register_callback(const char *, CBFUNC *); +extern void *execute_callback(struct Callback *, ...); +extern struct Callback *find_callback(const char *); +extern dlink_node *install_hook(struct Callback *, CBFUNC *); +extern void uninstall_hook(struct Callback *, CBFUNC *); +extern void *pass_callback(dlink_node *, ...); +extern void stats_hooks(struct Client *); + +#define is_callback_present(c) (!!dlink_list_length(&c->chain)) + +#endif diff --git a/include/hostmask.h b/include/hostmask.h new file mode 100644 index 0000000..63abb88 --- /dev/null +++ b/include/hostmask.h @@ -0,0 +1,86 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * hostmask.h: A header for the hostmask code. + * + * Copyright (C) 2005 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDE_hostmask_h +#define INCLUDE_hostmask_h 1 + +#define ATABLE_SIZE 0x1000 + + +enum hostmask_type +{ + HM_HOST, + HM_IPV4, + HM_IPV6 +}; + +struct AddressRec +{ + /* masktype: HM_HOST, HM_IPV4, HM_IPV6 -A1kmm */ + enum hostmask_type masktype; + + union + { + struct + { + /* Pointer into AccessItem... -A1kmm */ + struct irc_ssaddr addr; + int bits; + } ipa; + + /* Pointer into AccessItem... -A1kmm */ + const char *hostname; + } Mask; + + /* type: CONF_CLIENT, CONF_DLINE, CONF_KLINE etc... -A1kmm */ + unsigned int type; + + /* Higher precedences overrule lower ones... */ + unsigned int precedence; + + /* Only checked if !(type & 1)... */ + const char *username; + struct AccessItem *aconf; + + dlink_node node; +}; + +extern dlink_list atable[ATABLE_SIZE]; +extern int parse_netmask(const char *, struct irc_ssaddr *, int *); +extern int match_ipv6(const struct irc_ssaddr *, const struct irc_ssaddr *, int); +extern int match_ipv4(const struct irc_ssaddr *, const struct irc_ssaddr *, int); + +extern void mask_addr(struct irc_ssaddr *, int); +extern void init_host_hash(void); +extern void add_conf_by_address(const unsigned int, struct AccessItem *); +extern void delete_one_address_conf(const char *, struct AccessItem *); +extern void clear_out_address_conf(void); +extern void hostmask_expire_temporary(void); + +extern struct AccessItem *find_address_conf(const char *, const char *, + struct irc_ssaddr *, int, char *); +extern struct AccessItem *find_dline_conf(struct irc_ssaddr *, int); +extern struct AccessItem *find_conf_by_address(const char *, struct irc_ssaddr *, + unsigned int, int, const char *, const char *, int); +#endif /* INCLUDE_hostmask_h */ diff --git a/include/irc_res.h b/include/irc_res.h new file mode 100644 index 0000000..cddd955 --- /dev/null +++ b/include/irc_res.h @@ -0,0 +1,85 @@ +/* + * include/irc_res.h for referencing functions in src/irc_res.c + * + * $Id$ + */ + +#ifndef INCLUDED_irc_res_h +#define INCLUDED_irc_res_h + +#include "config.h" + +struct Client; /* XXX */ + +/* Here we define some values lifted from nameser.h */ +#define NS_NOTIFY_OP 4 +#define NS_INT16SZ 2 +#define NS_IN6ADDRSZ 16 +#define NS_INADDRSZ 4 +#define NS_INT32SZ 4 +#define NS_CMPRSFLGS 0xc0 +#define NS_MAXCDNAME 255 +#define QUERY 0 +#define IQUERY 1 +#define NO_ERRORS 0 +#define SERVFAIL 2 +#define NXDOMAIN 3 +#define T_A 1 +#define T_AAAA 28 +#define T_PTR 12 +#define T_CNAME 5 +#define T_NULL 10 +#define C_IN 1 +#define QFIXEDSZ 4 +#define RRFIXEDSZ 10 +#define HFIXEDSZ 12 + + + +typedef struct +{ + unsigned id :16; /* query identification number */ +#ifdef WORDS_BIGENDIAN + /* fields in third byte */ + unsigned qr: 1; /* response flag */ + unsigned opcode: 4; /* purpose of message */ + unsigned aa: 1; /* authoritive answer */ + unsigned tc: 1; /* truncated message */ + unsigned rd: 1; /* recursion desired */ + /* fields in fourth byte */ + unsigned ra: 1; /* recursion available */ + unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned ad: 1; /* authentic data from named */ + unsigned cd: 1; /* checking disabled by resolver */ + unsigned rcode :4; /* response code */ +#else + /* fields in third byte */ + unsigned rd :1; /* recursion desired */ + unsigned tc :1; /* truncated message */ + unsigned aa :1; /* authoritive answer */ + unsigned opcode :4; /* purpose of message */ + unsigned qr :1; /* response flag */ + /* fields in fourth byte */ + unsigned rcode :4; /* response code */ + unsigned cd: 1; /* checking disabled by resolver */ + unsigned ad: 1; /* authentic data from named */ + unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned ra :1; /* recursion available */ +#endif + /* remaining bytes */ + unsigned qdcount :16; /* number of question entries */ + unsigned ancount :16; /* number of answer entries */ + unsigned nscount :16; /* number of authority entries */ + unsigned arcount :16; /* number of resource entries */ +} HEADER; + +typedef void (*dns_callback_fnc)(void *, const struct irc_ssaddr *, const char *); + +extern void init_resolver(void); +extern void restart_resolver(void); +extern void delete_resolver_queries(const void *); +extern void report_dns_servers(struct Client *); +extern void gethost_byname_type(dns_callback_fnc , void *, const char *, int); +extern void gethost_byname(dns_callback_fnc, void *, const char *); +extern void gethost_byaddr(dns_callback_fnc, void *, const struct irc_ssaddr *); +#endif diff --git a/include/irc_reslib.h b/include/irc_reslib.h new file mode 100644 index 0000000..cd3e923 --- /dev/null +++ b/include/irc_reslib.h @@ -0,0 +1,59 @@ +/* + * include/irc_reslib.h (C)opyright 1992 Darren Reed. + * + * $Id$ + */ +#ifndef INCLUDED_ircdreslib_h +#define INCLUDED_ircdreslib_h + +/* + * Inline versions of get/put short/long. Pointer is advanced. + */ +#define IRC_NS_GET16(s, cp) { \ + const unsigned char *t_cp = (const unsigned char *)(cp); \ + (s) = ((uint16_t)t_cp[0] << 8) \ + | ((uint16_t)t_cp[1]) \ + ; \ + (cp) += NS_INT16SZ; \ +} + +#define IRC_NS_GET32(l, cp) { \ + const unsigned char *t_cp = (const unsigned char *)(cp); \ + (l) = ((uint32_t)t_cp[0] << 24) \ + | ((uint32_t)t_cp[1] << 16) \ + | ((uint32_t)t_cp[2] << 8) \ + | ((uint32_t)t_cp[3]) \ + ; \ + (cp) += NS_INT32SZ; \ +} + +#define IRC_NS_PUT16(s, cp) { \ + uint16_t t_s = (uint16_t)(s); \ + unsigned char *t_cp = (unsigned char *)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp = t_s; \ + (cp) += NS_INT16SZ; \ +} + +#define IRC_NS_PUT32(l, cp) { \ + uint32_t t_l = (uint32_t)(l); \ + unsigned char *t_cp = (unsigned char *)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ + *t_cp = t_l; \ + (cp) += NS_INT32SZ; \ +} + +extern struct irc_ssaddr irc_nsaddr_list[]; +extern int irc_nscount; +extern void irc_res_init(void); +extern int irc_dn_expand(const unsigned char *msg, const unsigned char *eom, const unsigned char *src, char *dst, int dstsiz); +extern int irc_dn_skipname(const unsigned char *ptr, const unsigned char *eom); +extern unsigned int irc_ns_get16(const unsigned char *src); +extern unsigned long irc_ns_get32(const unsigned char *src); +extern void irc_ns_put16(unsigned int src, unsigned char *dst); +extern void irc_ns_put32(unsigned long src, unsigned char *dst); +extern int irc_res_mkquery(const char *dname, int class, int type, unsigned char *buf, int buflen); +#endif /* INCLUDED_res_h */ + diff --git a/include/irc_string.h b/include/irc_string.h new file mode 100644 index 0000000..13a57c9 --- /dev/null +++ b/include/irc_string.h @@ -0,0 +1,150 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * irc_string.h: A header for the ircd string functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_irc_string_h +#define INCLUDED_irc_string_h + +#include "config.h" + + +extern int has_wildcards(const char *); +extern int ircd_pcre_exec(const void *, const char *); +extern void *ircd_pcre_compile(const char *, const char **); + +/* + * match - compare name with mask, mask may contain * and ? as wildcards + * match - returns 1 on successful match, 0 otherwise + * + * match_esc - compare with support for escaping chars + * match_chan - like match_esc with first character auto-escaped + */ +extern int match(const char *, const char *); +extern int match_esc(const char *, const char *); +extern int match_chan(const char *, const char *); + +/* + * collapse - collapse a string in place, converts multiple adjacent *'s + * into a single *. + * collapse - modifies the contents of pattern + * + * collapse_esc() - collapse with support for escaping chars + */ +extern char *collapse(char *); +extern char *collapse_esc(char *); + +/* + * NOTE: The following functions are NOT the same as strcasecmp + * and strncasecmp! These functions use the Finnish (RFC1459) + * character set. Do not replace! + * + * irccmp - case insensitive comparison of s1 and s2 + */ +extern int irccmp(const char *, const char *); + +/* + * ircncmp - counted case insensitive comparison of s1 and s2 + */ +extern int ircncmp(const char *, const char *, size_t); + +#ifndef HAVE_STRLCPY +extern size_t strlcpy(char *, const char *, size_t); +#endif + +#ifndef HAVE_STRLCAT +extern size_t strlcat(char *, const char *, size_t); +#endif + +extern const char *libio_basename(const char *); + +/* + * strip_tabs - convert tabs to spaces + * - jdc + */ +extern void strip_tabs(char *, const char *, size_t); + +const char *myctime(time_t); + +#define EmptyString(x) (!(x) || (*(x) == '\0')) + +#ifndef HAVE_STRTOK_R +extern char *strtoken(char **, char *, const char *); +#endif + +/* + * character macros + */ +extern const unsigned char ToLowerTab[]; +#define ToLower(c) (ToLowerTab[(unsigned char)(c)]) + +extern const unsigned char ToUpperTab[]; +#define ToUpper(c) (ToUpperTab[(unsigned char)(c)]) + +extern const unsigned int CharAttrs[]; + +#define PRINT_C 0x00001 +#define CNTRL_C 0x00002 +#define ALPHA_C 0x00004 +#define PUNCT_C 0x00008 +#define DIGIT_C 0x00010 +#define SPACE_C 0x00020 +#define NICK_C 0x00040 +#define CHAN_C 0x00080 +#define KWILD_C 0x00100 +#define CHANPFX_C 0x00200 +#define USER_C 0x00400 +#define HOST_C 0x00800 +#define NONEOS_C 0x01000 +#define SERV_C 0x02000 +#define EOL_C 0x04000 +#define MWILD_C 0x08000 +#define VCHAN_C 0x10000 + +#define IsVisibleChanChar(c) (CharAttrs[(unsigned char)(c)] & VCHAN_C) +#define IsHostChar(c) (CharAttrs[(unsigned char)(c)] & HOST_C) +#define IsUserChar(c) (CharAttrs[(unsigned char)(c)] & USER_C) +#define IsChanPrefix(c) (CharAttrs[(unsigned char)(c)] & CHANPFX_C) +#define IsChanChar(c) (CharAttrs[(unsigned char)(c)] & CHAN_C) +#define IsKWildChar(c) (CharAttrs[(unsigned char)(c)] & KWILD_C) +#define IsMWildChar(c) (CharAttrs[(unsigned char)(c)] & MWILD_C) +#define IsNickChar(c) (CharAttrs[(unsigned char)(c)] & NICK_C) +#define IsServChar(c) (CharAttrs[(unsigned char)(c)] & (NICK_C | SERV_C)) +#define IsCntrl(c) (CharAttrs[(unsigned char)(c)] & CNTRL_C) +#define IsAlpha(c) (CharAttrs[(unsigned char)(c)] & ALPHA_C) +#define IsSpace(c) (CharAttrs[(unsigned char)(c)] & SPACE_C) +#define IsLower(c) (IsAlpha((c)) && ((unsigned char)(c) > 0x5f)) +#define IsUpper(c) (IsAlpha((c)) && ((unsigned char)(c) < 0x60)) +#define IsDigit(c) (CharAttrs[(unsigned char)(c)] & DIGIT_C) +#define IsXDigit(c) (IsDigit(c) || ('a' <= (c) && (c) <= 'f') || \ + ('A' <= (c) && (c) <= 'F')) +#define IsAlNum(c) (CharAttrs[(unsigned char)(c)] & (DIGIT_C | ALPHA_C)) +#define IsPrint(c) (CharAttrs[(unsigned char)(c)] & PRINT_C) +#define IsAscii(c) ((unsigned char)(c) < 0x80) +#define IsGraph(c) (IsPrint((c)) && ((unsigned char)(c) != 0x32)) +#define IsPunct(c) (!(CharAttrs[(unsigned char)(c)] & \ + (CNTRL_C | ALPHA_C | DIGIT_C))) + +#define IsNonEOS(c) (CharAttrs[(unsigned char)(c)] & NONEOS_C) +#define IsEol(c) (CharAttrs[(unsigned char)(c)] & EOL_C) + +#endif /* INCLUDED_irc_string_h */ diff --git a/include/ircd.h b/include/ircd.h new file mode 100644 index 0000000..e55db3f --- /dev/null +++ b/include/ircd.h @@ -0,0 +1,124 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * ircd.h: A header for the ircd startup routines. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_ircd_h +#define INCLUDED_ircd_h + +#include "ircd_defs.h" +#include "config.h" +#include "memory.h" +#include "list.h" + +struct Client; + +struct SetOptions +{ + int autoconn; /* autoconn enabled for all servers? */ + int floodcount; /* Number of messages in 1 second */ + int joinfloodtime; + int joinfloodcount; + int ident_timeout; /* timeout for identd lookups */ + int spam_num; + int spam_time; +}; + +/* + * statistics structures + */ +struct ServerStatistics +{ + uint64_t is_cbs; /* bytes sent to clients */ + uint64_t is_cbr; /* bytes received from clients */ + uint64_t is_sbs; /* bytes sent to servers */ + uint64_t is_sbr; /* bytes received from servers */ + + time_t is_cti; /* time spent connected by clients */ + time_t is_sti; /* time spent connected by servers */ + + unsigned int is_cl; /* number of client connections */ + unsigned int is_sv; /* number of server connections */ + unsigned int is_ni; /* connection but no idea who it was */ + unsigned int is_ac; /* connections accepted */ + unsigned int is_ref; /* accepts refused */ + unsigned int is_unco; /* unknown commands */ + unsigned int is_wrdi; /* command going in wrong direction */ + unsigned int is_unpf; /* unknown prefix */ + unsigned int is_empt; /* empty message */ + unsigned int is_num; /* numeric message */ + unsigned int is_kill; /* number of kills generated on collisions */ + unsigned int is_asuc; /* successful auth requests */ + unsigned int is_abad; /* bad auth requests */ +}; + +extern struct ServerStatistics ServerStats; + + +struct Counter +{ + uint64_t totalrestartcount; /* Total client count ever */ + unsigned int myserver; /* my servers */ + unsigned int oper; /* Opers */ + unsigned int local; /* Local Clients */ + unsigned int total; /* total clients */ + unsigned int invisi; /* invisible clients */ + unsigned int max_loc; /* MAX local clients */ + unsigned int max_tot; /* MAX global clients */ + unsigned int max_loc_con; /* MAX local connection count (clients + server) */ + unsigned int max_loc_cli; /* XXX This is redundant - Max local client count */ +}; + +extern struct SetOptions GlobalSetOptions; /* defined in ircd.c */ + +struct ServerState_t +{ + int foreground; +}; + +extern struct ServerState_t server_state; + +extern char **myargv; +extern const char *infotext[]; +extern const char *serno; +extern const char *ircd_version; +extern const char *logFileName; +extern const char *pidFileName; +extern int dorehash; +extern int doremotd; +extern struct Counter Count; +extern struct timeval SystemTime; +#define CurrentTime SystemTime.tv_sec +extern int default_server_capabs; +extern unsigned int splitmode; +extern unsigned int splitchecking; +extern unsigned int split_users; +extern unsigned int split_servers; + +extern dlink_list unknown_list; /* unknown clients ON this server only */ +extern dlink_list local_client_list; /* local clients only ON this server */ +extern dlink_list serv_list; /* local servers to this server ONLY */ +extern dlink_list global_serv_list; /* global servers on the network */ +extern dlink_list oper_list; /* our opers, duplicated in local_client_list */ +extern int rehashed_klines; +extern void set_time(void); +#endif diff --git a/include/ircd_defs.h b/include/ircd_defs.h new file mode 100644 index 0000000..55215eb --- /dev/null +++ b/include/ircd_defs.h @@ -0,0 +1,73 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * ircd_defs.h: A header for ircd global definitions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +/* + * NOTE: NICKLEN and TOPICLEN do not live here anymore. Set it with configure + * Otherwise there are no user servicable part here. + * + */ + /* ircd_defs.h - Global size definitions for record entries used + * througout ircd. Please think 3 times before adding anything to this + * file. + */ +#ifndef INCLUDED_ircd_defs_h +#define INCLUDED_ircd_defs_h +#include "stdinc.h" +/* Right out of the RFC */ +#define IRCD_BUFSIZE 512 /* WARNING: *DONT* CHANGE THIS!!!! */ +#define HOSTLEN 63 /* Length of hostname. Updated to comply + with RFC 1123 */ +#define USERLEN 10 +#define PORTNAMELEN 6 /* ":31337" */ + +#define HOSTIPLEN 45 /* sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") */ +#define PASSWDLEN 20 +#define IDLEN 12 /* this is the maximum length, not the actual + generated length; DO NOT CHANGE! */ +#define REALLEN 50 +#define KILLLEN 90 +#define LOCAL_CHANNELLEN 50 +#define CHANNELLEN 200 +#define REASONLEN 120 +#define KICKLEN 160 +#define AWAYLEN 160 +#define KEYLEN 23 + +#define USERHOST_REPLYLEN (NICKLEN+HOSTLEN+USERLEN+5) +#define MAX_DATE_STRING 32 /* maximum string length for a date string */ +#define IRCD_MAXNS 3 /* Maximum number of nameservers in + /etc/resolv.conf we care about */ + +#define LOWEST_SAFE_FD 4 /* skip stdin, stdout, stderr, and profiler */ + +/* This is to get around the fact that some implementations have ss_len and + * others do not + */ +struct irc_ssaddr +{ + struct sockaddr_storage ss; + unsigned char ss_len; + in_port_t ss_port; +}; +#endif /* INCLUDED_ircd_defs_h */ diff --git a/include/ircd_getopt.h b/include/ircd_getopt.h new file mode 100644 index 0000000..3a680ba --- /dev/null +++ b/include/ircd_getopt.h @@ -0,0 +1,36 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * ircd_getopt.h: A header for the getopt() command line option calls. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef __GETOPT_H_INCLUDED__ +#define __GETOPT_H_INCLUDED__ + +struct lgetopt { + const char *opt; /* name of the argument */ + void *argloc; /* where we store the argument to it (-option argument) */ + enum { INTEGER, YESNO, STRING, USAGE, ENDEBUG } argtype; + const char *desc; /* description of the argument, usage for printing help */ +}; + +extern void parseargs(int *, char ***, struct lgetopt *); +#endif /* __GETOPT_H_INCLUDED__ */ diff --git a/include/ircd_signal.h b/include/ircd_signal.h new file mode 100644 index 0000000..3871e98 --- /dev/null +++ b/include/ircd_signal.h @@ -0,0 +1,31 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * ircd_signal.h: A header for ircd signals. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_ircd_signal_h +#define INCLUDED_ircd_signal_h + +extern void setup_signals(void); + +#endif /* INCLUDED_ircd_signal_h */ + diff --git a/include/list.h b/include/list.h new file mode 100644 index 0000000..9101f32 --- /dev/null +++ b/include/list.h @@ -0,0 +1,83 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * list.h: A header for the code in list.c. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_list_h +#define INCLUDED_list_h + +/* These macros are basically swiped from the linux kernel + * they are simple yet effective + */ + +/* + * Walks forward of a list. + * pos is your node + * head is your list head + */ +#define DLINK_FOREACH(pos, head) for (pos = (head); pos != NULL; pos = pos->next) + +/* + * Walks forward of a list safely while removing nodes + * pos is your node + * n is another list head for temporary storage + * head is your list head + */ +#define DLINK_FOREACH_SAFE(pos, n, head) for (pos = (head), n = pos ? pos->next : NULL; pos != NULL; pos = n, n = pos ? pos->next : NULL) +#define DLINK_FOREACH_PREV(pos, head) for (pos = (head); pos != NULL; pos = pos->prev) + +/* Returns the list length */ +#define dlink_list_length(list) (list)->length + +/* + * double-linked-list stuff + */ +typedef struct _dlink_node dlink_node; +typedef struct _dlink_list dlink_list; + +struct _dlink_node +{ + void *data; + dlink_node *prev; + dlink_node *next; +}; + +struct _dlink_list +{ + dlink_node *head; + dlink_node *tail; + unsigned int length; +}; + +extern void dlinkAdd(void *, dlink_node *, dlink_list *); +extern void dlinkAddBefore(dlink_node *, void *, dlink_node *, dlink_list *); +extern void dlinkAddTail(void *, dlink_node *, dlink_list *); +extern void dlinkDelete(dlink_node *, dlink_list *); +extern void dlinkMoveList(dlink_list *, dlink_list *); +extern void dlink_move_node(dlink_node *, dlink_list *, dlink_list *); +extern dlink_node *dlinkFind(dlink_list *, void *); +extern dlink_node *dlinkFindDelete(dlink_list *, void *); + +extern void init_dlink_nodes(void); +extern void free_dlink_node(dlink_node *); +extern dlink_node *make_dlink_node(void); +#endif diff --git a/include/listener.h b/include/listener.h new file mode 100644 index 0000000..6e402f6 --- /dev/null +++ b/include/listener.h @@ -0,0 +1,54 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * listener.h: A header for the listener code. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_listener_h +#define INCLUDED_listener_h + +#define LISTENER_SSL 0x1 +#define LISTENER_HIDDEN 0x2 +#define LISTENER_SERVER 0x4 + +#include "ircd_defs.h" +#include "fdlist.h" + +struct Client; + +struct Listener +{ + dlink_node listener_node; /* list node pointer */ + fde_t fd; /* file descriptor */ + int port; /* listener IP port */ + int ref_count; /* number of connection references */ + int active; /* current state of listener */ + struct irc_ssaddr addr; /* virtual address or INADDR_ANY */ + char name[HOSTLEN + 1]; /* virtual name of listener */ + unsigned int flags; +}; + +extern void add_listener(int, const char *, unsigned int); +extern void close_listeners(void); +extern const char *get_listener_name(const struct Listener *const); +extern void show_ports(struct Client *); +extern void free_listener(struct Listener *); +#endif /* INCLUDED_listener_h */ diff --git a/include/log.h b/include/log.h new file mode 100644 index 0000000..3467e51 --- /dev/null +++ b/include/log.h @@ -0,0 +1,46 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * log.h: A header for the logger functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_s_log_h +#define INCLUDED_s_log_h + +#define LOG_BUFSIZE 1024 + +enum log_type { + LOG_TYPE_IRCD, + LOG_TYPE_KILL, + LOG_TYPE_KLINE, + LOG_TYPE_DLINE, + LOG_TYPE_GLINE, + LOG_TYPE_OPER, + LOG_TYPE_USER, + LOG_TYPE_DEBUG, + LOG_TYPE_LAST +}; + +extern int log_add_file(enum log_type, size_t, const char *); +extern void log_close_all(void); +extern void ilog(enum log_type, const char *, ...); + +#endif /* INCLUDED_s_log_h */ diff --git a/include/memory.h b/include/memory.h new file mode 100644 index 0000000..8ed1bb1 --- /dev/null +++ b/include/memory.h @@ -0,0 +1,45 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * memory.h: A header for the memory functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef _I_MEMORY_H +#define _I_MEMORY_H + +#include "ircd_defs.h" +#include "config.h" + +extern void outofmemory(void); + +extern void *MyMalloc(size_t); +extern void *MyRealloc(void *, size_t); +extern void MyFree(void *); +extern void _DupString(char **, const char *); + +#define DupString(x,y) _DupString(&x, y) + +#ifndef NDEBUG +extern void mem_frob(void *, int); +#else +#define mem_frob(x, y) +#endif +#endif /* _I_MEMORY_H */ diff --git a/include/modules.h b/include/modules.h new file mode 100644 index 0000000..f96d544 --- /dev/null +++ b/include/modules.h @@ -0,0 +1,74 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * modules.h: A header for the modules functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_modules_h +#define INCLUDED_modules_h + +#include "config.h" + + +#define MODULE_FLAG_CORE 0x1 +#define MODULE_FLAG_NOUNLOAD 0x2 + +struct module +{ + dlink_node node; + char *name; + const char *version; + void *handle; + void (*modinit)(void); + void (*modexit)(void); + unsigned int flags; +}; + +struct module_path +{ + dlink_node node; + char path[PATH_MAX + 1]; +}; + +extern dlink_list modules_list; + +/* add a path */ +extern void mod_add_path(const char *); +extern void mod_clear_paths(void); + +/* load all modules */ +extern void load_all_modules(int); + +/* load core modules */ +extern void load_core_modules(int); + +/* Add this module to list of modules to be loaded from conf */ +extern void add_conf_module(const char *); +/* load all modules listed in conf */ +extern void load_conf_modules(void); +extern void modules_init(void); + +extern int unload_one_module(const char *, int); +extern int modules_valid_suffix(const char *); +extern int load_one_module(const char *); +extern int load_a_module(const char *, int); +extern struct module *findmodule_byname(const char *); +#endif /* INCLUDED_modules_h */ diff --git a/include/motd.h b/include/motd.h new file mode 100644 index 0000000..24e15e6 --- /dev/null +++ b/include/motd.h @@ -0,0 +1,65 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * motd.h: A header for the MOTD functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_motd_h +#define INCLUDED_motd_h +#include "ircd_defs.h" + + +#define MESSAGELINELEN 256 + +struct MessageFileLine +{ + struct MessageFileLine *next; + char line[MESSAGELINELEN + 1]; +}; + +typedef struct MessageFileLine MessageFileLine; + +typedef enum { + USER_MOTD, + USER_LINKS, + ISSUPPORT +} MotdType; + +struct MessageFile +{ + MessageFileLine *contentsOfFile; + MotdType motdType; + char fileName[PATH_MAX + 1]; + char lastChangedDate[MAX_DATE_STRING + 1]; +}; + +typedef struct MessageFile MessageFile; + +struct Client; + +extern void init_message_file(MotdType, const char *, struct MessageFile *); +extern int send_message_file(struct Client *, struct MessageFile *); +extern int read_message_file(MessageFile *); +extern MessageFile *init_MessageLine(void); +extern void addto_MessageLine(MessageFile *, const char *); +extern void destroy_MessageLine(MessageFile *); + +#endif /* INCLUDED_motd_h */ diff --git a/include/numeric.h b/include/numeric.h new file mode 100644 index 0000000..558b7e5 --- /dev/null +++ b/include/numeric.h @@ -0,0 +1,483 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * numeric.h: A header for the numeric functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_numeric_h +#define INCLUDED_numeric_h + +#define LOCALE_LENGTH 64 /* maximum length of locale name + 1 */ + +struct NumericInfo +{ + const char *name; /* common name of the numeric */ + const char *standard; /* standard numeric text */ + char *translated; /* translated numeric text */ +}; + +/* form_str - return a format string for a message number + * messages are defined below + */ +extern const char *form_str(int); +extern void set_locale(const char *); +extern const char *get_locale(void); + +/* + * Reserve numerics 000-099 for server-client connections where the client + * is local to the server. If any server is passed a numeric in this range + * from another server then it is remapped to 100-199. -avalon + */ +#define RPL_WELCOME 001 +#define RPL_YOURHOST 002 +#define RPL_CREATED 003 +#define RPL_MYINFO 004 +#define RPL_ISUPPORT 005 + /* RPL_BOUNCE IRCnet extension */ +/* RPL_MAP 6 unreal */ +/* RPL_MAPEND 7 unreal */ +/* RPL_SNOMASK 8 Undernet extension */ +/* RPL_STATMEMTOT 9 Undernet extension */ +/* RPL_STATMEM 10 Undernet extension */ + +#define RPL_REDIR 10 +#define RPL_MAP 15 /* Undernet extension */ +#define RPL_MAPMORE 16 /* Undernet extension */ +#define RPL_MAPEND 17 /* Undernet extension */ + +#define RPL_YOURID 42 /* IRCnet extension */ +/* RPL_ATTEMPTINGJUNC 50 aircd extension */ +/* RPL_ATTEMPTINGREROUTE 51 aircd extension */ + +/* + * Numeric replies from server commands. + * These are currently in the range 200-399. + */ +#define RPL_TRACELINK 200 +#define RPL_TRACECONNECTING 201 +#define RPL_TRACEHANDSHAKE 202 +#define RPL_TRACEUNKNOWN 203 +#define RPL_TRACEOPERATOR 204 +#define RPL_TRACEUSER 205 +#define RPL_TRACESERVER 206 +#define RPL_TRACENEWTYPE 208 +#define RPL_TRACECLASS 209 + +/* RPL_STATS 210 aircd extension, used instead of having + multiple stats numerics */ +/* RPL_TRACERECONNECT 210 IRCnet extension */ + +#define RPL_STATSLINKINFO 211 +#define RPL_STATSCOMMANDS 212 +#define RPL_STATSCLINE 213 +#define RPL_STATSNLINE 214 +/* RPL_STATSOLDNLINE 214 unreal */ +#define RPL_STATSILINE 215 +#define RPL_STATSKLINE 216 +#define RPL_STATSQLINE 217 +#define RPL_STATSYLINE 218 +#define RPL_ENDOFSTATS 219 +/* note ircu uses 217 for STATSPLINE frip. conflict + * as RPL_STATSQLINE was used in old 2.8 for Q line + * I'm going to steal 220 for now *sigh* + * -Dianora + */ + +#define RPL_STATSPLINE 220 +#define RPL_UMODEIS 221 + +/* RPL_SQLINE_NICK 222 Numerics List: Dalnet */ +/* RPL_STATSELINE 223 dalnet */ +/* RPL_STATSGLINE 223 unreal */ +/* RPL_STATSFLINE 224 Hybrid extension,Dalnet */ +/* RPL_STATSTLINE 224 unreal */ +/* RPL_STATSDLINE 225 Hybrid extension */ +/* RPL_STATSZLINE 225 Dalnet + RPL_STATSELINE 225 unreal + RPL_STATSCOUNT 226 Dalnet + RPL_STATSNLINE 226 unreal + RPL_STATSGLINE 227 Dalnet + RPL_STATSVLINE 227 unreal */ + +#define RPL_STATSFLINE 224 +#define RPL_STATSDLINE 225 +#define RPL_STATSALINE 226 + +/* RPL_RULES 232 unreal */ + +/* RPL_STATSIAUTH 239 IRCnet extension */ +/* RPL_STATSVLINE 240 IRCnet extension */ +/* RPL_STATSXLINE 240 austnet */ + +#define RPL_STATSLLINE 241 +#define RPL_STATSUPTIME 242 +#define RPL_STATSOLINE 243 +#define RPL_STATSHLINE 244 +/* 245 No longer used in ircd-hybrid */ +#define RPL_STATSSLINE 245 +#define RPL_STATSSERVICE 246 +#define RPL_STATSXLINE 247 +#define RPL_STATSULINE 248 +#define RPL_STATSDEBUG 249 +#define RPL_STATSCONN 250 +/* RPL_STATSDLINE 250 Numerics List: IRCnet */ +#define RPL_LUSERCLIENT 251 +#define RPL_LUSEROP 252 +#define RPL_LUSERUNKNOWN 253 +#define RPL_LUSERCHANNELS 254 +#define RPL_LUSERME 255 +#define RPL_ADMINME 256 +#define RPL_ADMINLOC1 257 +#define RPL_ADMINLOC2 258 +#define RPL_ADMINEMAIL 259 + +#define RPL_ENDOFTRACE 262 +#define RPL_LOAD2HI 263 + +/* RPL_TRYAGAIN 263 Numerics List: IRCnet */ +/* RPL_LOAD2HI 263 Dalnet */ +/* RPL_CURRENT_LOCAL 265 aircd/efnet/hybrid/dalnet*/ +/* RPL_CURRENT_GLOBAL 266 aircd/efnet/hybrid/dalnet */ +/* RPL_START_NETSTAT 267 aircd */ +/* RPL_NETSTAT 268 aircd */ +/* RPL_END_NETSTAT 269 aircd */ + +#define RPL_LOCALUSERS 265 +#define RPL_GLOBALUSERS 266 + +#define RPL_ACCEPTLIST 281 +#define RPL_ENDOFACCEPT 282 + +/* RPL_GLIST 280 Undernet extension */ +/* RPL_ENDOFGLIST 281 Undernet extension */ +/* RPL_JUPELIST 282 Undernet extension - jupe -Kev */ +/* RPL_ENDOFJUPELIST 283 Undernet extension - jupe -Kev */ +/* RPL_FEATURE 284 Undernet extension - features */ +/* RPL_CHANINFO_HANDLE 285 aircd */ +/* RPL_CHANINFO_USERS 286 aircd */ +/* RPL_CHANINFO_CHOPS 287 aircd */ +/* RPL_CHANINFO_VOICES 288 aircd */ +/* RPL_CHANINFO_AWAY 289 aircd */ +/* RPL_CHANINFO_OPERS 290 aircd */ +/* RPL_HELPHDR 290 Numeric List: Dalnet */ +/* RPL_CHANINFO_BANNED 291 aircd */ +/* RPL_HELPOP 291 Numeric List: Dalnet */ +/* RPL_CHANINFO_BANS 292 aircd */ +/* RPL_HELPTLR 292 Numeric List: Dalnet */ +/* RPL_CHANINFO_INVITE 293 aircd */ +/* RPL_HELPHLP 293 Numeric List: Dalnet */ +/* RPL_CHANINFO_INVITES 294 aircd */ +/* RPL_HELPFWD 294 Numeric List: Dalnet */ +/* RPL_CHANINFO_KICK 295 aircd */ +/* RPL_HELPIGN 295 Numeric List: Dalnet */ +/* RPL_CHANINFO_KICKS 296 aircd */ + +/* RPL_END_CHANINFO 299 aircd */ + +/* numeric_replies */ +#define RPL_AWAY 301 +#define RPL_USERHOST 302 +#define RPL_ISON 303 +#define RPL_TEXT 304 +#define RPL_UNAWAY 305 +#define RPL_NOWAWAY 306 +/* RPL_USERIP 307 Undernet extension */ +#define RPL_WHOISREGNICK 307 +/* RPL_SUSERHOST 307 austnet */ +/* RPL_NOTIFYACTION 308 aircd */ +#define RPL_WHOISADMIN 308 /* Numeric List: Dalnet */ +/* RPL_RULESSTART 308 unreal */ +/* RPL_NICKTRACE 309 aircd */ +/* RPL_WHOISSADMIN 309 Numeric List: Dalnet */ +/* RPL_ENDOFRULES 309 unreal */ +/* RPL_WHOISHELPER 309 austnet */ +/* RPL_WHOISSVCMSG 310 Dalnet */ +/* RPL_WHOISHELPOP 310 unreal */ +/* RPL_WHOISSERVICE 310 austnet */ + +#define RPL_WHOISUSER 311 +#define RPL_WHOISSERVER 312 +#define RPL_WHOISOPERATOR 313 + +#define RPL_WHOWASUSER 314 +/* rpl_endofwho below (315) */ +#define RPL_ENDOFWHOWAS 369 + +#define RPL_WHOISCHANOP 316 /* redundant and not needed but reserved */ +#define RPL_WHOISIDLE 317 + +#define RPL_ENDOFWHOIS 318 +#define RPL_WHOISCHANNELS 319 +/* RPL_WHOIS_HIDDEN 320 Anothernet +h, ick! */ +/* RPL_WHOISSPECIAL 320 unreal */ +#define RPL_LISTSTART 321 +#define RPL_LIST 322 +#define RPL_LISTEND 323 +#define RPL_CHANNELMODEIS 324 +/* RPL_CHANNELPASSIS 325 IRCnet extension */ +/* RPL_UNIQOPIS 325 IRCnet extension */ +/* RPL_NOCHANPASS 326 IRCnet extension */ +/* RPL_CHPASSUNKNOWN 327 IRCnet extension */ +/* RPL_CHANNEL_URL 328 dalnet, anothernet */ +#define RPL_CREATIONTIME 329 +/* RPL_WHOWAS_TIME 330 ? */ +#define RPL_NOTOPIC 331 +#define RPL_TOPIC 332 +#define RPL_TOPICWHOTIME 333 +/* RPL_COMMANDSYNTAX 334 Dalnet */ +/* RPL_LISTSYNTAX 334 unreal */ +/* RPL_CHANPASSOK 338 IRCnet extension (?)*/ +#define RPL_WHOISACTUALLY 338 /* dalnet */ +/* RPL_WHOISACTUALLY 338 Undernet extension, dalnet */ +/* RPL_BADCHANPASS 339 IRCnet extension (?)*/ +/* RPL_USERIP 340 (old) Undernet extension */ +#define RPL_INVITING 341 +/* RPL_SUMMONING 342 removed from RFC1459 */ + +#define RPL_INVITELIST 346 +#define RPL_ENDOFINVITELIST 347 /* IRCnet, Undernet extension */ +#define RPL_EXCEPTLIST 348 +#define RPL_ENDOFEXCEPTLIST 349 + +#define RPL_VERSION 351 + +#define RPL_WHOREPLY 352 +#define RPL_ENDOFWHO 315 +#define RPL_NAMREPLY 353 +#define RPL_ENDOFNAMES 366 + +#define RPL_CLOSING 362 +#define RPL_CLOSEEND 363 +#define RPL_LINKS 364 +#define RPL_ENDOFLINKS 365 +/* rpl_endofnames above (366) */ +#define RPL_BANLIST 367 +#define RPL_ENDOFBANLIST 368 +/* rpl_endofwhowas above (369) */ + +#define RPL_INFO 371 +#define RPL_MOTD 372 +#define RPL_INFOSTART 373 +#define RPL_ENDOFINFO 374 +#define RPL_MOTDSTART 375 +#define RPL_ENDOFMOTD 376 + +/* RPL_KICKEXPIRED 377 aircd */ +/* RPL_SPAM 377 austnet */ +/* RPL_BANEXPIRED 378 aircd */ +/* RPL_KICKLINKED 379 aircd */ +/* RPL_BANLINKED 380 aircd */ + +#define RPL_YOUREOPER 381 +#define RPL_REHASHING 382 +/* RPL_YOURSERVICE 383 Numeric List: various */ +#define RPL_RSACHALLENGE 386 + +/* RPL_QLIST 386 unreal */ +/* RPL_ENDOFQLIST 387 unreal */ +/* RPL_ALIST 388 unreal */ +/* RPL_ENDOFALIST 389 unreal */ + +#define RPL_TIME 391 +#define RPL_USERSSTART 392 +#define RPL_USERS 393 +#define RPL_ENDOFUSERS 394 +#define RPL_NOUSERS 395 +#define RPL_HOSTHIDDEN 396 + +/* + * Errors are in the range from 400-599 currently and are grouped by what + * commands they come from. + */ +#define ERR_NOSUCHNICK 401 +#define ERR_NOSUCHSERVER 402 +#define ERR_NOSUCHCHANNEL 403 +#define ERR_CANNOTSENDTOCHAN 404 +#define ERR_TOOMANYCHANNELS 405 +#define ERR_WASNOSUCHNICK 406 +#define ERR_TOOMANYTARGETS 407 +#define ERR_NOORIGIN 409 +#define ERR_INVALIDCAPCMD 410 + +#define ERR_NORECIPIENT 411 +#define ERR_NOTEXTTOSEND 412 +#define ERR_NOTOPLEVEL 413 +#define ERR_WILDTOPLEVEL 414 +/* ERR_BADMASK 415 IRCnet extension */ +#define ERR_UNKNOWNCOMMAND 421 +#define ERR_NOMOTD 422 +#define ERR_NOADMININFO 423 + +/* ERR_TOOMANYAWAY 429 Dalnet */ + +#define ERR_NONICKNAMEGIVEN 431 +#define ERR_ERRONEUSNICKNAME 432 +#define ERR_NICKNAMEINUSE 433 + +/* ERR_SERVICENAMEINUSE 434 ? */ +/* ERR_NORULES 434 unreal */ +/* ERR_SERVICECONFUSED 435 ? */ +/* ERR_BANONCHAN 435 dalnet */ + +#define ERR_NICKCOLLISION 436 +#define ERR_UNAVAILRESOURCE 437 +#define ERR_NICKTOOFAST 438 /* We did it first Undernet! ;) db */ + +#define ERR_SERVICESDOWN 440 + +#define ERR_USERNOTINCHANNEL 441 +#define ERR_NOTONCHANNEL 442 +#define ERR_USERONCHANNEL 443 + +#define ERR_NOTREGISTERED 451 + +/* ERR_IDCOLLISION 452 IRCnet extension ? */ +/* ERR_NICKLOST 453 IRCnet extension ? */ + +/* ERR_HOSTILENAME 455 unreal */ + +/* ERR_NOHIDING 459 unreal */ +/* ERR_NOTFORHALFOPS 460 unreal */ + +#define ERR_ACCEPTFULL 456 +#define ERR_ACCEPTEXIST 457 +#define ERR_ACCEPTNOT 458 + +#define ERR_NEEDMOREPARAMS 461 +#define ERR_ALREADYREGISTRED 462 +#define ERR_PASSWDMISMATCH 464 +#define ERR_YOUREBANNEDCREEP 465 +#define ERR_ONLYSERVERSCANCHANGE 468 +/* ERR_LINKSET 469 unreal */ +/* ERR_LINKCHANNEL 470 unreal */ +/* ERR_KICKEDFROMCHAN 470 aircd */ +#define ERR_OPERONLYCHAN 470 +#define ERR_CHANNELISFULL 471 +#define ERR_UNKNOWNMODE 472 +#define ERR_INVITEONLYCHAN 473 +#define ERR_BANNEDFROMCHAN 474 +#define ERR_BADCHANNELKEY 475 +#define ERR_NEEDREGGEDNICK 477 +#define ERR_BANLISTFULL 478 /* I stole the numeric from ircu -db */ +#define ERR_BADCHANNAME 479 +/* ERR_LINKFAIL 479 unreal */ +#define ERR_SSLONLYCHAN 480 +#define ERR_NOPRIVILEGES 481 +#define ERR_CHANOPRIVSNEEDED 482 +#define ERR_CANTKILLSERVER 483 +#define ERR_RESTRICTED 484 +/* ERR_DESYNC 484 Dalnet,PTlink */ +/* ERR_ATTACKDENY 484 unreal */ +/* ERR_RESTRICTED 484 IRCnet extension */ +/* ERR_UNIQOPRIVSNEEDED 485 IRCnet extension */ +/* ERR_KILLDENY 485 unreal */ +/* ERR_CANTKICKADMIN 485 PTlink */ +#define ERR_NONONREG 486 +/* ERR_CHANTOORECENT 487 IRCnet extension (?) */ +/* ERR_TSLESSCHAN 488 IRCnet extension (?) */ +/* ERR_VOICENEEDED 489 Undernet extension */ +#define ERR_NOOPERHOST 491 +/* ERR_NOSERVICEHOST 492 IRCnet extension */ + +#define ERR_UMODEUNKNOWNFLAG 501 +#define ERR_USERSDONTMATCH 502 + +#define ERR_GHOSTEDCLIENT 503 +/* ERR_VWORLDWARN 503 austnet */ + +#define ERR_USERNOTONSERV 504 + +/* #define ERR_LAST_ERR_MSG 505 + * moved to 999 + */ + + +#define ERR_TOOMANYWATCH 512 +#define ERR_WRONGPONG 513 +/* ERR_TOOMANYDCC 514 dalnet */ +/* ERR_NOINVITE 518 unreal */ +#define ERR_LONGMASK 518 /* Undernet extension -Kev */ +/* ERR_ADMONLY 519 unreal */ +/* ERR_TOOMANYUSERS 519 Undernet extension -Kev */ +/* ERR_OPERONLY 520 unreal */ +/* ERR_MASKTOOWIDE 520 Undernet extension -Kev */ +/* ERR_WHOTRUNC 520 austnet */ +/* ERR_LASTERROR 521 Undernet extension -Kev */ +#define ERR_LISTSYNTAX 521 +/* ERR_WHOSYNTAX 522 dalnet */ +/* ERR_WHOLIMEXCEED 523 dalnet */ + +#define ERR_HELPNOTFOUND 524 + +#define RPL_LOGON 600 +#define RPL_LOGOFF 601 +#define RPL_WATCHOFF 602 +#define RPL_WATCHSTAT 603 +#define RPL_NOWON 604 +#define RPL_NOWOFF 605 +#define RPL_WATCHLIST 606 +#define RPL_ENDOFWATCHLIST 607 + +/* RPL_MAPMORE 610 unreal + + RPL_MAPMORE 615 PTlink + + RPL_DCCSTATUS 617 dalnet + RPL_DCCLIST 618 dalnet + RPL_ENDOFDCCLIST 619 dalnet + RPL_DCCINFO 620 dalnet + + RPL_DUMPING 640 unreal + RPL_DUMPRPL 641 unreal + RPL_EODUMP 642 unreal +*/ + +#define RPL_WHOISSECURE 671 +#define RPL_MODLIST 702 +#define RPL_ENDOFMODLIST 703 + +#define RPL_HELPSTART 704 +#define RPL_HELPTXT 705 +#define RPL_ENDOFHELP 706 + +#define RPL_ETRACE_FULL 708 +#define RPL_ETRACE 709 + +#define RPL_KNOCK 710 +#define RPL_KNOCKDLVR 711 + +#define ERR_TOOMANYKNOCK 712 +#define ERR_CHANOPEN 713 +#define ERR_KNOCKONCHAN 714 + +#define RPL_TARGUMODEG 716 +#define RPL_TARGNOTIFY 717 +#define RPL_UMODEGMSG 718 + +#define ERR_NOPRIVS 723 + +#define RPL_TESTMASK 724 +#define RPL_TESTLINE 725 +#define RPL_NOTESTLINE 726 + +#define ERR_LAST_ERR_MSG 999 + +#endif /* INCLUDED_numeric_h */ diff --git a/include/packet.h b/include/packet.h new file mode 100644 index 0000000..1f2b272 --- /dev/null +++ b/include/packet.h @@ -0,0 +1,58 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * packet.h: A header for the packet functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_packet_h +#define INCLUDED_packet_h + +#include "fdlist.h" + +/* + * this hides in here rather than in defaults.h because it really shouldn't + * be tweaked unless you *REALLY REALLY* know what you're doing! + * Remember, messages are only anti-flooded on incoming from the client, not on + * incoming from a server for a given client, so if you tweak this you risk + * allowing a client to flood differently depending upon where they are on + * the network.. + * -- adrian + */ +/* MAX_FLOOD is the amount of lines in a 'burst' we allow from a client, + * anything beyond MAX_FLOOD is limited to about one line per second. + * + * MAX_FLOOD_CONN is the amount of lines we allow from a client who has + * just connected. this allows clients to rejoin multiple channels + * without being so heavily penalised they excess flood. + */ +#define MAX_FLOOD 5 +#define MAX_FLOOD_BURST MAX_FLOOD * 8 + +struct Callback; + +void *iorecv_default(va_list); +extern struct Callback *iorecv_cb; + +PF read_packet; +PF flood_recalc; +void flood_endgrace(struct Client *); + +#endif /* INCLUDED_packet_h */ diff --git a/include/parse.h b/include/parse.h new file mode 100644 index 0000000..1a58e66 --- /dev/null +++ b/include/parse.h @@ -0,0 +1,165 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * parse.h: A header for the message parser. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_parse_h +#define INCLUDED_parse_h + +struct Client; + + +/* + * m_functions execute protocol messages on this server: + * int m_func(struct Client* client_p, struct Client* source_p, int parc, char* parv[]); + * + * client_p is always NON-NULL, pointing to a *LOCAL* client + * structure (with an open socket connected!). This + * identifies the physical socket where the message + * originated (or which caused the m_function to be + * executed--some m_functions may call others...). + * + * source_p is the source of the message, defined by the + * prefix part of the message if present. If not + * or prefix not found, then source_p==client_p. + * + * (!IsServer(client_p)) => (client_p == source_p), because + * prefixes are taken *only* from servers... + * + * (IsServer(client_p)) + * (source_p == client_p) => the message didn't + * have the prefix. + * + * (source_p != client_p && IsServer(source_p) means + * the prefix specified servername. (?) + * + * (source_p != client_p && !IsServer(source_p) means + * that message originated from a remote + * user (not local). + * + * + * combining + * + * (!IsServer(source_p)) means that, source_p can safely + * taken as defining the target structure of the + * message in this server. + * + * *Always* true (if 'parse' and others are working correct): + * + * 1) source_p->from == client_p (note: client_p->from == client_p) + * + * 2) MyConnect(source_p) <=> source_p == client_p (e.g. source_p + * *cannot* be a local connection, unless it's + * actually client_p!). [MyConnect(x) should probably + * be defined as (x == x->from) --msa ] + * + * parc number of variable parameter strings (if zero, + * parv is allowed to be NULL) + * + * parv a NULL terminated list of parameter pointers, + * + * parv[0], sender (prefix string), if not present + * this points to an empty string. + * parv[1]...parv[parc-1] + * pointers to additional parameters + * parv[parc] == NULL, *always* + * + * note: it is guaranteed that parv[0]..parv[parc-1] are all + * non-NULL pointers. + */ + +/* + * MessageHandler + */ +typedef enum HandlerType { + UNREGISTERED_HANDLER, + CLIENT_HANDLER, + SERVER_HANDLER, + ENCAP_HANDLER, + OPER_HANDLER, + DUMMY_HANDLER, + LAST_HANDLER_TYPE +} HandlerType; + +/* + * MessageHandler function + * Params: + * struct Client* client_p - connection message originated from + * struct Client* source_p - source of message, may be different from client_p + * int parc - parameter count + * char* parv[] - parameter vector + */ +typedef void (*MessageHandler)(struct Client *, struct Client *, int, char *[]); + +/* + * Message table structure + */ +struct Message +{ + const char *cmd; + unsigned int count; /* number of times command used */ + unsigned int rcount; /* number of times command used by server */ + unsigned int args_min; /* at least this many args must be passed + * or an error will be sent to the user + * before the m_func is even called + */ + unsigned int args_max; /* maximum permitted parameters */ + unsigned int flags; /* bit 0 set means that this command is allowed + * to be used only on the average of once per 2 + * seconds -SRB + */ + uint64_t bytes; /* bytes received for this message */ + + /* + * client_p = Connected client ptr + * source_p = Source client ptr + * parc = parameter count + * parv = parameter variable array + */ + /* handlers: + * UNREGISTERED, CLIENT, SERVER, ENCAP, OPER, DUMMY, LAST + */ + MessageHandler handlers[LAST_HANDLER_TYPE]; +}; + +/* + * Constants + */ +#define MFLG_SLOW 0x001 /* Command can be executed roughly + * once per 2 seconds. + */ +#define MAXPARA 15 + +extern void parse(struct Client *, char *, char *); +extern void mod_add_cmd(struct Message *); +extern void mod_del_cmd(struct Message *); +extern struct Message *find_command(const char *); +extern void report_messages(struct Client *); + +/* generic handlers */ +extern void rfc1459_command_send_error(struct Client *, struct Client *,int, char *[]); +extern void m_ignore(struct Client *, struct Client *, int, char *[]); +extern void m_not_oper(struct Client *, struct Client *, int, char *[]); +extern void m_registered(struct Client *, struct Client *, int, char *[]); +extern void m_unregistered(struct Client *, struct Client *, int, char *[]); + +#endif /* INCLUDED_parse_h */ diff --git a/include/patchlevel.h b/include/patchlevel.h new file mode 100644 index 0000000..7365468 --- /dev/null +++ b/include/patchlevel.h @@ -0,0 +1,27 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * patchlevel.h: A header defining the patchlevel. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef PATCHLEVEL +#define PATCHLEVEL "hybrid-8.0.0" +#endif diff --git a/include/restart.h b/include/restart.h new file mode 100644 index 0000000..9b79800 --- /dev/null +++ b/include/restart.h @@ -0,0 +1,31 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * restart.h: A header with restart functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_restart_h +#define INCLUDED_restart_h + +extern void restart(const char *); +extern void server_die(const char *, int); + +#endif diff --git a/include/resv.h b/include/resv.h new file mode 100644 index 0000000..87bbe85 --- /dev/null +++ b/include/resv.h @@ -0,0 +1,52 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * resv.h: A header for the RESV functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_resv_h +#define INCLUDED_resv_h + +struct ResvChannel +{ + dlink_node node; + struct ResvChannel *hnext; + time_t hold; /* Hold action until this time (calendar time) */ + /* +1 for \0 */ + char name[CHANNELLEN + 1]; + char *reason; + int conf; /* 1 if set from ircd.conf, 0 if from elsewhere */ +}; + +extern dlink_list nresv_items; +extern dlink_list resv_channel_list; + +extern struct ConfItem *create_channel_resv(char *, char *, int); +extern struct ConfItem *create_nick_resv(char *, char *, int); + +extern int delete_channel_resv(struct ResvChannel *); + +extern void clear_conf_resv(void); +extern void report_resv(struct Client *); + +extern int valid_wild_card_simple(const char *); +extern struct ResvChannel *match_find_resv(const char *); +#endif /* INCLUDED_resv_h */ diff --git a/include/rng_mt.h b/include/rng_mt.h new file mode 100644 index 0000000..1f32ef1 --- /dev/null +++ b/include/rng_mt.h @@ -0,0 +1,53 @@ +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + 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. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) + + $Id$ +*/ + + +#ifndef __include_rng_mt_header__ +#define __include_rng_mt_header__ + +extern void init_genrand(uint32_t); +extern void init_by_array(uint32_t[], int); +extern uint32_t genrand_int32(void); +#endif diff --git a/include/rsa.h b/include/rsa.h new file mode 100644 index 0000000..06f7f6e --- /dev/null +++ b/include/rsa.h @@ -0,0 +1,35 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * rsa.h: A header for the RSA functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ +#ifndef INCLUDED_rsa_h +#define INCLUDED_rsa_h + +#include "config.h" + +#ifdef HAVE_LIBCRYPTO +extern void report_crypto_errors(void); +extern int generate_challenge(char **, char **, RSA *); +extern int get_randomness(unsigned char *, int); +#endif +#endif /* INCLUDED_rsa_h */ + diff --git a/include/s_auth.h b/include/s_auth.h new file mode 100644 index 0000000..b9ffc35 --- /dev/null +++ b/include/s_auth.h @@ -0,0 +1,66 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_auth.h: A header for the ident functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_s_auth_h +#define INCLUDED_s_auth_h + +#include "irc_res.h" +#include "hook.h" + + +struct Client; + +struct AuthRequest +{ + dlink_node node; /* auth_doing_list */ + int flags; + struct Client* client; /* pointer to client struct for request */ + fde_t fd; /* file descriptor for auth queries */ + time_t timeout; /* time when query expires */ +}; + +/* + * flag values for AuthRequest + * NAMESPACE: AM_xxx - Authentication Module + */ +#define AM_DOING_AUTH 0x1 +#define AM_DNS_PENDING 0x2 + +#define SetDNSPending(x) ((x)->flags |= AM_DNS_PENDING) +#define ClearDNSPending(x) ((x)->flags &= ~AM_DNS_PENDING) +#define IsDNSPending(x) ((x)->flags & AM_DNS_PENDING) + +#define SetDoingAuth(x) ((x)->flags |= AM_DOING_AUTH) +#define ClearAuth(x) ((x)->flags &= ~AM_DOING_AUTH) +#define IsDoingAuth(x) ((x)->flags & AM_DOING_AUTH) + +extern struct Callback *auth_cb; + +extern void init_auth(void); +extern void send_auth_query(struct AuthRequest *); +extern void remove_auth_request(struct AuthRequest *); +extern void delete_auth(struct AuthRequest *); +extern void release_auth_client(struct AuthRequest *); + +#endif /* INCLUDED_s_auth_h */ diff --git a/include/s_bsd.h b/include/s_bsd.h new file mode 100644 index 0000000..a76ce6d --- /dev/null +++ b/include/s_bsd.h @@ -0,0 +1,73 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_bsd.h: A header for the network subsystem. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_s_bsd_h +#define INCLUDED_s_bsd_h + +#include "config.h" +#include "fdlist.h" +#include "hook.h" + +/* Type of IO */ +#define COMM_SELECT_READ 1 +#define COMM_SELECT_WRITE 2 + +/* How long can comm_select() wait for network events [milliseconds] */ +#define SELECT_DELAY 500 + +struct Client; +struct AccessItem; +struct Listener; + +extern struct Callback *setup_socket_cb; + +extern void add_connection(struct Listener *, struct irc_ssaddr *, int); +extern void close_connection(struct Client *); +extern void report_error(int, const char *, const char *, int); + +extern int get_sockerr(int); +extern int ignoreErrno(int); + +extern void comm_settimeout(fde_t *, time_t, PF *, void *); +extern void comm_setflush(fde_t *, time_t, PF *, void *); +extern void comm_checktimeouts(void *); +extern void comm_connect_tcp(fde_t *, const char *, u_short, + struct sockaddr *, int, CNCB *, void *, int, int); +extern const char * comm_errstr(int status); +extern int comm_open(fde_t *F, int family, int sock_type, int proto, + const char *note); +extern int comm_accept(struct Listener *, struct irc_ssaddr *pn); + +/* These must be defined in the network IO loop code of your choice */ +extern void init_netio(void); +extern void comm_setselect(fde_t *, unsigned int, PF *, void *, time_t); +extern void init_comm(void); +extern int read_message (time_t, unsigned char); +extern void comm_select(void); +extern void check_can_use_v6(void); +#ifdef IPV6 +extern void remove_ipv6_mapping(struct irc_ssaddr *); +#endif + +#endif /* INCLUDED_s_bsd_h */ diff --git a/include/s_gline.h b/include/s_gline.h new file mode 100644 index 0000000..1ecc9b2 --- /dev/null +++ b/include/s_gline.h @@ -0,0 +1,60 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_gline.h: A header for the gline functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_s_gline_h +#define INCLUDED_s_gline_h + +#include "ircd_defs.h" + +#define GLINE_PENDING_DEL_TYPE 0 +#define GLINE_PENDING_ADD_TYPE 1 + +struct AccessItem; + +extern void cleanup_glines(void *); +extern struct AccessItem *find_is_glined(const char *, const char *); + +struct gline_pending +{ + dlink_node node; + + struct { + char oper_nick[NICKLEN + 1]; + char oper_user[USERLEN + 1]; + char oper_host[HOSTLEN + 1]; + char oper_server[HOSTLEN + 1]; + char reason[REASONLEN + 1]; + time_t time_request; + } vote_1, vote_2; + + time_t last_gline_time; /* for expiring entry */ + char user[USERLEN * 2 + 2]; + char host[HOSTLEN * 2 + 2]; +}; + + +#define CLEANUP_GLINES_TIME 300 + +extern dlink_list pending_glines[]; +#endif /* INCLUDED_s_gline_h */ diff --git a/include/s_misc.h b/include/s_misc.h new file mode 100644 index 0000000..88dd5bf --- /dev/null +++ b/include/s_misc.h @@ -0,0 +1,47 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_misc.h: A header for the miscellaneous functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_s_misc_h +#define INCLUDED_s_misc_h + +extern char *date(time_t); +extern const char *smalldate(time_t); +#ifdef HAVE_LIBCRYPTO +extern char *ssl_get_cipher(const SSL *); +#endif + +/* Just blindly define our own MIN/MAX macro */ + +#define IRCD_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define IRCD_MIN(a, b) ((a) < (b) ? (a) : (b)) + +#define _1MEG (1024.0) +#define _1GIG (1024.0*1024.0) +#define _1TER (1024.0*1024.0*1024.0) +#define _GMKs(x) (((x) > _1TER) ? "Terabytes" : (((x) > _1GIG) ? "Gigabytes" :\ + (((x) > _1MEG) ? "Megabytes" : "Kilobytes"))) +#define _GMKv(x) (((x) > _1TER) ? (float)((x)/_1TER) : (((x) > _1GIG) ? \ + (float)((x)/_1GIG) : (((x) > _1MEG) ? (float)((x)/_1MEG) : \ + (float)(x)))) +#endif diff --git a/include/s_serv.h b/include/s_serv.h new file mode 100644 index 0000000..31582ea --- /dev/null +++ b/include/s_serv.h @@ -0,0 +1,101 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_serv.h: A header for the server functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_serv_h +#define INCLUDED_serv_h +#include "config.h" + +struct ConfItem; + +/* + * number of seconds to wait after server starts up, before + * starting try_connections() + * TOO SOON and you can nick collide like crazy. + */ +#define STARTUP_CONNECTIONS_TIME 60 + +struct Client; +struct AccessItem; +struct Channel; + +/* Capabilities */ +struct Capability +{ + dlink_node node; + char *name; /* name of capability */ + unsigned int cap; /* mask value */ +}; + +#define CAP_CAP 0x00000001 /* received a CAP to begin with */ +#define CAP_QS 0x00000002 /* Can handle quit storm removal */ +#define CAP_EX 0x00000004 /* Can do channel +e exemptions */ +#define CAP_CHW 0x00000008 /* Can do channel wall @# */ +#define CAP_IE 0x00000010 /* Can do invite exceptions */ +#define CAP_EOB 0x00000020 /* Can do EOB message */ +#define CAP_KLN 0x00000040 /* Can do KLINE message */ +#define CAP_GLN 0x00000080 /* Can do GLINE message */ +#define CAP_TS6 0x00000100 /* Can do TS6 */ +#define CAP_KNOCK 0x00000200 /* supports KNOCK */ +#define CAP_UNKLN 0x00000400 /* Can do UNKLINE message */ +#define CAP_CLUSTER 0x00000800 /* supports server clustering */ +#define CAP_ENCAP 0x00001000 /* supports ENCAP message */ +#define CAP_HOPS 0x00002000 /* supports HALFOPS */ +#define CAP_TBURST 0x00004000 /* supports TBURST */ +#define CAP_SVS 0x00008000 /* supports services */ +#define CAP_DLN 0x00010000 /* Can do DLINE message */ +#define CAP_UNDLN 0x00020000 /* Can do UNDLINE message */ + +/* + * Capability macros. + */ +#define IsCapable(x, cap) ((x)->localClient->caps & (cap)) +#define SetCapable(x, cap) ((x)->localClient->caps |= (cap)) +#define ClearCap(x, cap) ((x)->localClient->caps &= ~(cap)) + + +/* + * return values for hunt_server() + */ +#define HUNTED_NOSUCH (-1) /* if the hunted server is not found */ +#define HUNTED_ISME 0 /* if this server should execute the command */ +#define HUNTED_PASS 1 /* if message passed onwards successfully */ + +extern int valid_servname(const char *); +extern int check_server(const char *, struct Client *); +extern int hunt_server(struct Client *, struct Client *, + const char *, int, int, char **); +extern void add_capability(const char *, int, int); +extern int delete_capability(const char *); +extern int find_capability(const char *); +extern void send_capabilities(struct Client *, struct AccessItem *, int); +extern void write_links_file(void *); +extern void server_estab(struct Client *); +extern const char *show_capabilities(struct Client *); +extern void try_connections(void *); +extern void burst_channel(struct Client *client_p, struct Channel *); +extern void sendnick_TS(struct Client *, struct Client *); +extern int serv_connect(struct AccessItem *, struct Client *); +extern struct Client *find_servconn_in_progress(const char *); +extern struct Server *make_server(struct Client *); +#endif /* INCLUDED_s_serv_h */ diff --git a/include/s_user.h b/include/s_user.h new file mode 100644 index 0000000..e90a31d --- /dev/null +++ b/include/s_user.h @@ -0,0 +1,61 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_user.h: A header for the user functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_s_user_h +#define INCLUDED_s_user_h + +#define IRC_MAXSID 3 +#define IRC_MAXUID 6 +#define TOTALSIDUID (IRC_MAXSID + IRC_MAXUID) + +struct Client; + +extern struct Callback *entering_umode_cb; +extern struct Callback *umode_cb; +extern unsigned int user_modes[]; + +extern void assemble_umode_buffer(void); +extern void set_user_mode(struct Client *, struct Client *, int, char **); +extern void send_umode(struct Client *, struct Client *, + unsigned int, unsigned int, char *); +extern void send_umode_out(struct Client *, struct Client *, unsigned int); +extern void show_lusers(struct Client *); +extern void show_isupport(struct Client *); +extern void oper_up(struct Client *); + +extern void register_local_user(struct Client *); +extern void register_remote_user(struct Client *, + const char *, const char *, + const char *, const char *); +extern void init_uid(void); +extern int valid_sid(const char *); +extern int valid_hostname(const char *); +extern int valid_username(const char *); +extern int valid_nickname(const char *, const int); +extern void add_isupport(const char *, const char *, int); +extern void delete_isupport(const char *); +extern void init_isupport(void); +extern void rebuild_isupport_message_line(void); + +#endif diff --git a/include/send.h b/include/send.h new file mode 100644 index 0000000..1039618 --- /dev/null +++ b/include/send.h @@ -0,0 +1,98 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * send.h: A header for the message sending functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_send_h +#define INCLUDED_send_h + +#include "fdlist.h" + +/* + * struct decls + */ +struct Callback; +struct Channel; +struct Client; +struct dlink_list; + +extern void *iosend_default(va_list); +extern struct Callback *iosend_cb; + +/* send.c prototypes */ + +extern void sendq_unblocked(fde_t *, struct Client *); +extern void send_queued_write(struct Client *); +extern void send_queued_all(void); +extern void sendto_one(struct Client *, const char *, ...); +extern void sendto_channel_butone(struct Client *, struct Client *, + struct Channel *, unsigned int, + const char *, ...); +extern void sendto_common_channels_local(struct Client *, int, + const char *, ...); +extern void sendto_channel_local(int, int, struct Channel *, + const char *, ...); +extern void sendto_channel_local_butone(struct Client *, int, struct Channel *, + const char *, ...); +extern void sendto_channel_remote(struct Client *, struct Client *, int, + const unsigned int, const unsigned int, + struct Channel *, const char *, ...); +extern void sendto_server(struct Client *, + const unsigned int, + const unsigned int, const char *, ...); +extern void sendto_match_butone(struct Client *, struct Client *, + char *, int, const char *, ...); +extern void sendto_match_servs(struct Client *, const char *, int, + const char *, ...); +extern void sendto_realops_flags(unsigned int, int, + const char *, ...); +extern void sendto_globops_flags(unsigned int, int, const char *, ...); +extern void sendto_wallops_flags(unsigned int, struct Client *, + const char *, ...); +extern void ts_warn(const char *, ...); + +extern void sendto_anywhere(struct Client *, struct Client *, + const char *, ...); +extern void kill_client(struct Client *, struct Client *, + const char *, ... ); +extern void kill_client_ll_serv_butone(struct Client *, struct Client *, + const char *, ...); + + +#define ALL_MEMBERS 0 +#define NON_CHANOPS 1 +#define ONLY_CHANOPS_VOICED 2 +#define ONLY_CHANOPS 3 +#define ONLY_SERVERS 4 /* for channel_mode.c */ + +#define L_ALL 0 +#define L_OPER 1 +#define L_ADMIN 2 + +#define NOCAPS 0 /* no caps */ +#define NOFLAGS 0 /* no flags */ + +/* used when sending to #mask or $mask */ +#define MATCH_SERVER 1 +#define MATCH_HOST 2 + +#endif /* INCLUDED_send_h */ diff --git a/include/serno.h b/include/serno.h new file mode 100644 index 0000000..bdad155 --- /dev/null +++ b/include/serno.h @@ -0,0 +1 @@ +#define SERIALNUM "SVN" diff --git a/include/sprintf_irc.h b/include/sprintf_irc.h new file mode 100644 index 0000000..641c636 --- /dev/null +++ b/include/sprintf_irc.h @@ -0,0 +1,39 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * sprintf_irc.h: The irc sprintf header. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef SPRINTF_IRC +#define SPRINTF_IRC + + +/*============================================================================= + * Proto types + */ + +extern int vsprintf_irc(char *, const char *, va_list); + +/* + * ircsprintf - optimized sprintf + */ +extern int ircsprintf(char *, const char *, ...); +#endif /* SPRINTF_IRC */ diff --git a/include/stdinc.h b/include/stdinc.h new file mode 100644 index 0000000..09c0939 --- /dev/null +++ b/include/stdinc.h @@ -0,0 +1,90 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * stdinc.h: Pull in all of the necessary system headers + * + * Copyright (C) 2002 Aaron Sethman <androsyn@ratbox.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id$ + * + */ + +#ifndef STDINC_H /* prevent multiple #includes */ +#define STDINC_H + +#include "config.h" + +#include "defaults.h" + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <errno.h> + +#ifdef HAVE_STRTOK_R +# define strtoken(x, y, z) strtok_r(y, z, x) +#endif + +#include <sys/types.h> + +#ifdef HAVE_CRYPT_H +#include <crypt.h> +#endif + +#ifdef HAVE_LIBCRYPTO +#include <openssl/ssl.h> +#include <openssl/err.h> +#endif + +#include <stdio.h> +#include <assert.h> +#include <time.h> +#include <fcntl.h> + +#include <stdarg.h> +#include <signal.h> +#include <ctype.h> + +#include <dirent.h> +#include <netdb.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/time.h> +#include <sys/file.h> + +#include <limits.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#ifdef HAVE_SYS_RESOURCE_H +#include <sys/resource.h> +#endif + +#include <sys/stat.h> +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif + +#endif diff --git a/include/supported.h b/include/supported.h new file mode 100644 index 0000000..0e59fd5 --- /dev/null +++ b/include/supported.h @@ -0,0 +1,73 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * supported.h: Header for 005 numeric etc... + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_supported_h +#define INCLUDED_supported_h + +#include "channel.h" +#include "ircd_defs.h" +#include "s_serv.h" + +#define CASEMAP "rfc1459" + +/* ConfigChannel.use_knock ? " KNOCK" */ + +/* + * - from mirc's versions.txt + * + * mIRC now supports the numeric 005 tokens: CHANTYPES=# and + * PREFIX=(ohv)@%+ and can handle a dynamic set of channel and + * nick prefixes. + * + * mIRC assumes that @ is supported on all networks, any mode + * left of @ is assumed to have at least equal power to @, and + * any mode right of @ has less power. + * + * mIRC has internal support for @%+ modes. + * + * $nick() can now handle all mode letters listed in PREFIX. + * + * Also added support for CHANMODES=A,B,C,D token (not currently + * supported by any servers), which lists all modes supported + * by a channel, where: + * + * A = modes that take a parameter, and add or remove nicks + * or addresses to a list, such as +bIe for the ban, + * invite, and exception lists. + * + * B = modes that change channel settings, but which take + * a parameter when they are set and unset, such as + * +k key, and -k key. + * + * C = modes that change channel settings, but which take + * a parameter only when they are set, such as +l N, + * and -l. + * + * D = modes that change channel settings, such as +imnpst + * and take no parameters. + * + * All unknown/unlisted modes are treated as type D. + */ + +#endif /* INCLUDED_supported_h */ diff --git a/include/userhost.h b/include/userhost.h new file mode 100644 index 0000000..2608507 --- /dev/null +++ b/include/userhost.h @@ -0,0 +1,47 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * userhost.h: A header for global user limits. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_userhost_h +#define INCLUDED_userhost_h + +struct NameHost +{ + dlink_node node; /* point to other names on this hostname */ + char name[USERLEN + 1]; + int icount; /* number of =local= identd on this name*/ + int gcount; /* global user count on this name */ + int lcount; /* local user count on this name */ +}; + +struct UserHost +{ + dlink_list list; /* list of names on this hostname */ + struct UserHost *next; + char host[HOSTLEN + 1]; +}; + +extern void count_user_host(const char *, const char *, int *, int *, int *); +extern void add_user_host(const char *, const char *, int); +extern void delete_user_host(const char *, const char *, int global); +#endif /* INCLUDED_userhost_h */ diff --git a/include/watch.h b/include/watch.h new file mode 100644 index 0000000..2d14818 --- /dev/null +++ b/include/watch.h @@ -0,0 +1,48 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 1997 Jukka Santala (Donwulff) + * Copyright (C) 2005 by the Hybrid 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 + */ + +/*! \file watch.h + * \brief Header including structures and prototypes for WATCH support + * \version $Id$ + */ + +#ifndef INCLUDED_watch_h +#define INCLUDED_watch_h + +/*! \brief Watch structure */ +struct Watch +{ + dlink_node node; /**< Embedded dlink_node used to link into watchTable */ + dlink_list watched_by; /**< list of clients that have this + entry on their watch list */ + time_t lasttime; /**< last time the client was seen */ + char nick[NICKLEN + 1]; /**< nick name of the client to watch */ +}; + +extern void watch_init(void); +extern void watch_add_to_hash_table(const char *, struct Client *); +extern void watch_del_from_hash_table(const char *, struct Client *); +extern void watch_check_hash(struct Client *, int); +extern void watch_del_watch_list(struct Client *); +extern void watch_count_memory(unsigned int *const, uint64_t *const); +extern struct Watch *watch_find_hash(const char *); +#endif diff --git a/include/whowas.h b/include/whowas.h new file mode 100644 index 0000000..3f23ec5 --- /dev/null +++ b/include/whowas.h @@ -0,0 +1,82 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * whowas.h: Header for the whowas functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#ifndef INCLUDED_whowas_h +#define INCLUDED_whowas_h + +#include "ircd_defs.h" +#include "client.h" +#include "config.h" + + +struct Whowas +{ + int hashv; + time_t logoff; + char name[NICKLEN + 1]; + char username[USERLEN + 1]; + char hostname[HOSTLEN + 1]; + char realname[REALLEN + 1]; + char servername[HOSTLEN + 1]; + struct Client *online; /* Pointer to new nickname for chasing or NULL */ + dlink_node tnode; /* for hash table... */ + dlink_node cnode; /* for client struct linked list */ +}; + +/* +** initwhowas +*/ +extern void whowas_init(void); + +/* +** add_history +** Add the currently defined name of the client to history. +** usually called before changing to a new name (nick). +** Client must be a fully registered user. +*/ +extern void add_history(struct Client *, int); + +/* +** off_history +** This must be called when the client structure is about to +** be released. History mechanism keeps pointers to client +** structures and it must know when they cease to exist. This +** also implicitly calls AddHistory. +*/ +extern void off_history(struct Client *); + +/* +** get_history +** Return the current client that was using the given +** nickname within the timelimit. Returns NULL, if no +** one found... +*/ +extern struct Client *get_history(const char *, time_t); + +/* +** for debugging...counts related structures stored in whowas array. +*/ +extern void count_whowas_memory(unsigned int *, uint64_t *); +extern dlink_list WHOWASHASH[]; +#endif /* INCLUDED_whowas_h */ diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..377bb86 --- /dev/null +++ b/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-11-20.07; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/libltdl/COPYING.LIB b/libltdl/COPYING.LIB new file mode 100644 index 0000000..ba2be48 --- /dev/null +++ b/libltdl/COPYING.LIB @@ -0,0 +1,515 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +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 and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +^L + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +^L + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +^L + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +^L + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +^L + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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 with +this License. +^L + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +^L + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +^L + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +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 library's name and a brief idea of what it +does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper +mail. + +You should also get your employer (if you work as a programmer) or +your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James +Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/libltdl/Makefile.am b/libltdl/Makefile.am new file mode 100644 index 0000000..e5e43f2 --- /dev/null +++ b/libltdl/Makefile.am @@ -0,0 +1,163 @@ +## -- Process this file with automake to produce +## +## Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc. +## Written by Gary V. Vaughan, 2003 +## +## NOTE: The canonical source of this file is maintained with the +## GNU Libtool package. Report bugs to bug-libtool@gnu.org. +## +## GNU Libltdl is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2 of the License, or (at your option) any later version. +## +## As a special exception to the GNU Lesser General Public License, +## if you distribute this file as part of a program or library that +## is built using GNU libtool, you may include this file under the +## same distribution terms that you use for the rest of that program. +## +## GNU Libltdl is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU LesserGeneral Public +## License along with GNU Libltdl; see the file COPYING.LIB. If not, a +## copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +## or obtained by writing to the Free Software Foundation, Inc., +## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +##### + +ACLOCAL_AMFLAGS = -I m4 +AUTOMAKE_OPTIONS = foreign +AM_CPPFLAGS = +AM_LDFLAGS = +BUILT_SOURCES = +include_HEADERS = +noinst_LTLIBRARIES = +lib_LTLIBRARIES = +EXTRA_LTLIBRARIES = +EXTRA_DIST = +CLEANFILES = +MOSTLYCLEANFILES = + +# -I$(srcdir) is needed for user that built libltdl with a sub-Automake +# (not as a sub-package!) using 'nostdinc': +AM_CPPFLAGS += -DLT_CONFIG_H='<$(LT_CONFIG_H)>' \ + -DLTDL -I. -I$(srcdir) -Ilibltdl \ + -I$(srcdir)/libltdl -I$(srcdir)/libltdl +AM_LDFLAGS += -no-undefined +LTDL_VERSION_INFO = -version-info 10:0:3 + +noinst_LTLIBRARIES += $(LT_DLLOADERS) + +if INSTALL_LTDL +ltdlincludedir = $(includedir)/libltdl +ltdlinclude_HEADERS = libltdl/lt_system.h \ + libltdl/lt_error.h \ + libltdl/lt_dlloader.h +include_HEADERS += ltdl.h +lib_LTLIBRARIES += libltdl.la +endif + +if CONVENIENCE_LTDL +noinst_LTLIBRARIES += libltdlc.la +endif + +libltdl_la_SOURCES = libltdl/lt__alloc.h \ + libltdl/lt__dirent.h \ + libltdl/lt__glibc.h \ + libltdl/lt__private.h \ + libltdl/lt__strl.h \ + libltdl/lt_dlloader.h \ + libltdl/lt_error.h \ + libltdl/lt_system.h \ + libltdl/slist.h \ + loaders/preopen.c \ + lt__alloc.c \ + lt_dlloader.c \ + lt_error.c \ + ltdl.c \ + ltdl.h \ + slist.c + +EXTRA_DIST += lt__dirent.c \ + lt__strl.c + +libltdl_la_CPPFLAGS = -DLTDLOPEN=$(LTDLOPEN) $(AM_CPPFLAGS) +libltdl_la_LDFLAGS = $(AM_LDFLAGS) $(LTDL_VERSION_INFO) $(LT_DLPREOPEN) +libltdl_la_LIBADD = $(ltdl_LTLIBOBJS) +libltdl_la_DEPENDENCIES = $(LT_DLLOADERS) $(ltdl_LTLIBOBJS) + +libltdlc_la_SOURCES = $(libltdl_la_SOURCES) +libltdlc_la_CPPFLAGS = -DLTDLOPEN=$(LTDLOPEN)c $(AM_CPPFLAGS) +libltdlc_la_LDFLAGS = $(AM_LDFLAGS) $(LT_DLPREOPEN) +libltdlc_la_LIBADD = $(libltdl_la_LIBADD) +libltdlc_la_DEPENDENCIES= $(libltdl_la_DEPENDENCIES) + +## The loaders are preopened by libltdl, itself always built from +## pic-objects (either as a shared library, or a convenience library), +## so the loaders themselves must be made from pic-objects too. We +## use convenience libraries for that purpose: +EXTRA_LTLIBRARIES += dlopen.la \ + dld_link.la \ + dyld.la \ + load_add_on.la \ + loadlibrary.la \ + shl_load.la + +dlopen_la_SOURCES = loaders/dlopen.c +dlopen_la_LDFLAGS = -module -avoid-version +dlopen_la_LIBADD = $(LIBADD_DLOPEN) + +dld_link_la_SOURCES = loaders/dld_link.c +dld_link_la_LDFLAGS = -module -avoid-version +dld_link_la_LIBADD = -ldld + +dyld_la_SOURCES = loaders/dyld.c +dyld_la_LDFLAGS = -module -avoid-version + +load_add_on_la_SOURCES = loaders/load_add_on.c +load_add_on_la_LDFLAGS = -module -avoid-version + +loadlibrary_la_SOURCES = loaders/loadlibrary.c +loadlibrary_la_LDFLAGS = -module -avoid-version + +shl_load_la_SOURCES = loaders/shl_load.c +shl_load_la_LDFLAGS = -module -avoid-version +shl_load_la_LIBADD = $(LIBADD_SHL_LOAD) + +## Make sure these will be cleaned even when they're not built by default: +CLEANFILES += libltdl.la \ + libltdlc.la \ + libdlloader.la + +## Automake-1.9.6 doesn't clean subdir AC_LIBOBJ compiled objects +## automatically: +CLEANFILES += $(ltdl_LIBOBJS) $(ltdl_LTLIBOBJS) + +EXTRA_DIST += COPYING.LIB \ + \ + \ + \ + \ + \ + \ + README + +## --------------------------- ## +## Gnulib snippets ## +## --------------------------- ## + +BUILT_SOURCES += $(ARGZ_H) +EXTRA_DIST += argz_.h \ + argz.c + +# We need the following in order to create an <argz.h> when the system +# doesn't have one that works with the given compiler. +all-local $(lib_OBJECTS): $(ARGZ_H) +argz.h: argz_.h + cp $(srcdir)/argz_.h $@-t + mv $@-t $@ +MOSTLYCLEANFILES += argz.h \ + argz.h-t diff --git a/libltdl/Makefile.in b/libltdl/Makefile.in new file mode 100644 index 0000000..1dbd6a8 --- /dev/null +++ b/libltdl/Makefile.in @@ -0,0 +1,951 @@ +# Makefile.in generated by automake 1.12.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +##### + + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@INSTALL_LTDL_TRUE@am__append_1 = ltdl.h +@INSTALL_LTDL_TRUE@am__append_2 = libltdl.la +@CONVENIENCE_LTDL_TRUE@am__append_3 = libltdlc.la +subdir = libltdl +DIST_COMMON = README $(am__include_HEADERS_DIST) \ + $(am__ltdlinclude_HEADERS_DIST) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(top_srcdir)/depcomp COPYING.LIB +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" \ + "$(DESTDIR)$(ltdlincludedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) +dld_link_la_DEPENDENCIES = +am_dld_link_la_OBJECTS = dld_link.lo +dld_link_la_OBJECTS = $(am_dld_link_la_OBJECTS) +dld_link_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(dld_link_la_LDFLAGS) $(LDFLAGS) -o $@ +am__DEPENDENCIES_1 = +dlopen_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_dlopen_la_OBJECTS = dlopen.lo +dlopen_la_OBJECTS = $(am_dlopen_la_OBJECTS) +dlopen_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(dlopen_la_LDFLAGS) $(LDFLAGS) -o $@ +dyld_la_LIBADD = +am_dyld_la_OBJECTS = dyld.lo +dyld_la_OBJECTS = $(am_dyld_la_OBJECTS) +dyld_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(dyld_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_libltdl_la_OBJECTS = libltdl_la-preopen.lo libltdl_la-lt__alloc.lo \ + libltdl_la-lt_dlloader.lo libltdl_la-lt_error.lo \ + libltdl_la-ltdl.lo libltdl_la-slist.lo +libltdl_la_OBJECTS = $(am_libltdl_la_OBJECTS) +libltdl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libltdl_la_LDFLAGS) $(LDFLAGS) -o $@ +@INSTALL_LTDL_TRUE@am_libltdl_la_rpath = -rpath $(libdir) +am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +am__objects_1 = libltdlc_la-preopen.lo libltdlc_la-lt__alloc.lo \ + libltdlc_la-lt_dlloader.lo libltdlc_la-lt_error.lo \ + libltdlc_la-ltdl.lo libltdlc_la-slist.lo +am_libltdlc_la_OBJECTS = $(am__objects_1) +libltdlc_la_OBJECTS = $(am_libltdlc_la_OBJECTS) +libltdlc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libltdlc_la_LDFLAGS) $(LDFLAGS) -o $@ +@CONVENIENCE_LTDL_TRUE@am_libltdlc_la_rpath = +load_add_on_la_LIBADD = +am_load_add_on_la_OBJECTS = load_add_on.lo +load_add_on_la_OBJECTS = $(am_load_add_on_la_OBJECTS) +load_add_on_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(load_add_on_la_LDFLAGS) $(LDFLAGS) -o $@ +loadlibrary_la_LIBADD = +am_loadlibrary_la_OBJECTS = loadlibrary.lo +loadlibrary_la_OBJECTS = $(am_loadlibrary_la_OBJECTS) +loadlibrary_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(loadlibrary_la_LDFLAGS) $(LDFLAGS) -o $@ +shl_load_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_shl_load_la_OBJECTS = shl_load.lo +shl_load_la_OBJECTS = $(am_shl_load_la_OBJECTS) +shl_load_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(shl_load_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(dld_link_la_SOURCES) $(dlopen_la_SOURCES) \ + $(dyld_la_SOURCES) $(libltdl_la_SOURCES) \ + $(libltdlc_la_SOURCES) $(load_add_on_la_SOURCES) \ + $(loadlibrary_la_SOURCES) $(shl_load_la_SOURCES) +DIST_SOURCES = $(dld_link_la_SOURCES) $(dlopen_la_SOURCES) \ + $(dyld_la_SOURCES) $(libltdl_la_SOURCES) \ + $(libltdlc_la_SOURCES) $(load_add_on_la_SOURCES) \ + $(loadlibrary_la_SOURCES) $(shl_load_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__include_HEADERS_DIST = ltdl.h +am__ltdlinclude_HEADERS_DIST = libltdl/lt_system.h libltdl/lt_error.h \ + libltdl/lt_dlloader.h +HEADERS = $(include_HEADERS) $(ltdlinclude_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBDIR = @LIBDIR@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PREFIX = @PREFIX@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I m4 +AUTOMAKE_OPTIONS = foreign + +# -I$(srcdir) is needed for user that built libltdl with a sub-Automake +# (not as a sub-package!) using 'nostdinc': +AM_CPPFLAGS = -DLT_CONFIG_H='<$(LT_CONFIG_H)>' -DLTDL -I. -I$(srcdir) \ + -Ilibltdl -I$(srcdir)/libltdl -I$(srcdir)/libltdl +AM_LDFLAGS = -no-undefined +BUILT_SOURCES = $(ARGZ_H) +include_HEADERS = $(am__append_1) +noinst_LTLIBRARIES = $(LT_DLLOADERS) $(am__append_3) +lib_LTLIBRARIES = $(am__append_2) +EXTRA_LTLIBRARIES = dlopen.la dld_link.la dyld.la load_add_on.la \ + loadlibrary.la shl_load.la +EXTRA_DIST = lt__dirent.c lt__strl.c COPYING.LIB README argz_.h argz.c +CLEANFILES = libltdl.la libltdlc.la libdlloader.la $(ltdl_LIBOBJS) \ + $(ltdl_LTLIBOBJS) +MOSTLYCLEANFILES = argz.h argz.h-t +LTDL_VERSION_INFO = -version-info 10:0:3 +@INSTALL_LTDL_TRUE@ltdlincludedir = $(includedir)/libltdl +@INSTALL_LTDL_TRUE@ltdlinclude_HEADERS = libltdl/lt_system.h \ +@INSTALL_LTDL_TRUE@ libltdl/lt_error.h \ +@INSTALL_LTDL_TRUE@ libltdl/lt_dlloader.h + +libltdl_la_SOURCES = libltdl/lt__alloc.h \ + libltdl/lt__dirent.h \ + libltdl/lt__glibc.h \ + libltdl/lt__private.h \ + libltdl/lt__strl.h \ + libltdl/lt_dlloader.h \ + libltdl/lt_error.h \ + libltdl/lt_system.h \ + libltdl/slist.h \ + loaders/preopen.c \ + lt__alloc.c \ + lt_dlloader.c \ + lt_error.c \ + ltdl.c \ + ltdl.h \ + slist.c + +libltdl_la_CPPFLAGS = -DLTDLOPEN=$(LTDLOPEN) $(AM_CPPFLAGS) +libltdl_la_LDFLAGS = $(AM_LDFLAGS) $(LTDL_VERSION_INFO) $(LT_DLPREOPEN) +libltdl_la_LIBADD = $(ltdl_LTLIBOBJS) +libltdl_la_DEPENDENCIES = $(LT_DLLOADERS) $(ltdl_LTLIBOBJS) +libltdlc_la_SOURCES = $(libltdl_la_SOURCES) +libltdlc_la_CPPFLAGS = -DLTDLOPEN=$(LTDLOPEN)c $(AM_CPPFLAGS) +libltdlc_la_LDFLAGS = $(AM_LDFLAGS) $(LT_DLPREOPEN) +libltdlc_la_LIBADD = $(libltdl_la_LIBADD) +libltdlc_la_DEPENDENCIES = $(libltdl_la_DEPENDENCIES) +dlopen_la_SOURCES = loaders/dlopen.c +dlopen_la_LDFLAGS = -module -avoid-version +dlopen_la_LIBADD = $(LIBADD_DLOPEN) +dld_link_la_SOURCES = loaders/dld_link.c +dld_link_la_LDFLAGS = -module -avoid-version +dld_link_la_LIBADD = -ldld +dyld_la_SOURCES = loaders/dyld.c +dyld_la_LDFLAGS = -module -avoid-version +load_add_on_la_SOURCES = loaders/load_add_on.c +load_add_on_la_LDFLAGS = -module -avoid-version +loadlibrary_la_SOURCES = loaders/loadlibrary.c +loadlibrary_la_LDFLAGS = -module -avoid-version +shl_load_la_SOURCES = loaders/shl_load.c +shl_load_la_LDFLAGS = -module -avoid-version +shl_load_la_LIBADD = $(LIBADD_SHL_LOAD) +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libltdl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libltdl/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +dld_link.la: $(dld_link_la_OBJECTS) $(dld_link_la_DEPENDENCIES) $(EXTRA_dld_link_la_DEPENDENCIES) + $(dld_link_la_LINK) $(dld_link_la_OBJECTS) $(dld_link_la_LIBADD) $(LIBS) +dlopen.la: $(dlopen_la_OBJECTS) $(dlopen_la_DEPENDENCIES) $(EXTRA_dlopen_la_DEPENDENCIES) + $(dlopen_la_LINK) $(dlopen_la_OBJECTS) $(dlopen_la_LIBADD) $(LIBS) +dyld.la: $(dyld_la_OBJECTS) $(dyld_la_DEPENDENCIES) $(EXTRA_dyld_la_DEPENDENCIES) + $(dyld_la_LINK) $(dyld_la_OBJECTS) $(dyld_la_LIBADD) $(LIBS) +libltdl.la: $(libltdl_la_OBJECTS) $(libltdl_la_DEPENDENCIES) $(EXTRA_libltdl_la_DEPENDENCIES) + $(libltdl_la_LINK) $(am_libltdl_la_rpath) $(libltdl_la_OBJECTS) $(libltdl_la_LIBADD) $(LIBS) +libltdlc.la: $(libltdlc_la_OBJECTS) $(libltdlc_la_DEPENDENCIES) $(EXTRA_libltdlc_la_DEPENDENCIES) + $(libltdlc_la_LINK) $(am_libltdlc_la_rpath) $(libltdlc_la_OBJECTS) $(libltdlc_la_LIBADD) $(LIBS) +load_add_on.la: $(load_add_on_la_OBJECTS) $(load_add_on_la_DEPENDENCIES) $(EXTRA_load_add_on_la_DEPENDENCIES) + $(load_add_on_la_LINK) $(load_add_on_la_OBJECTS) $(load_add_on_la_LIBADD) $(LIBS) +loadlibrary.la: $(loadlibrary_la_OBJECTS) $(loadlibrary_la_DEPENDENCIES) $(EXTRA_loadlibrary_la_DEPENDENCIES) + $(loadlibrary_la_LINK) $(loadlibrary_la_OBJECTS) $(loadlibrary_la_LIBADD) $(LIBS) +shl_load.la: $(shl_load_la_OBJECTS) $(shl_load_la_DEPENDENCIES) $(EXTRA_shl_load_la_DEPENDENCIES) + $(shl_load_la_LINK) $(shl_load_la_OBJECTS) $(shl_load_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dld_link.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dlopen.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dyld.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdl_la-lt__alloc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdl_la-lt_dlloader.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdl_la-lt_error.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdl_la-ltdl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdl_la-preopen.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdl_la-slist.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdlc_la-lt__alloc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdlc_la-lt_dlloader.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdlc_la-lt_error.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdlc_la-ltdl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdlc_la-preopen.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltdlc_la-slist.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load_add_on.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loadlibrary.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shl_load.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +dld_link.lo: loaders/dld_link.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dld_link.lo -MD -MP -MF $(DEPDIR)/dld_link.Tpo -c -o dld_link.lo `test -f 'loaders/dld_link.c' || echo '$(srcdir)/'`loaders/dld_link.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/dld_link.Tpo $(DEPDIR)/dld_link.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/dld_link.c' object='dld_link.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dld_link.lo `test -f 'loaders/dld_link.c' || echo '$(srcdir)/'`loaders/dld_link.c + +dlopen.lo: loaders/dlopen.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dlopen.lo -MD -MP -MF $(DEPDIR)/dlopen.Tpo -c -o dlopen.lo `test -f 'loaders/dlopen.c' || echo '$(srcdir)/'`loaders/dlopen.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/dlopen.Tpo $(DEPDIR)/dlopen.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/dlopen.c' object='dlopen.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dlopen.lo `test -f 'loaders/dlopen.c' || echo '$(srcdir)/'`loaders/dlopen.c + +dyld.lo: loaders/dyld.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dyld.lo -MD -MP -MF $(DEPDIR)/dyld.Tpo -c -o dyld.lo `test -f 'loaders/dyld.c' || echo '$(srcdir)/'`loaders/dyld.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/dyld.Tpo $(DEPDIR)/dyld.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/dyld.c' object='dyld.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dyld.lo `test -f 'loaders/dyld.c' || echo '$(srcdir)/'`loaders/dyld.c + +libltdl_la-preopen.lo: loaders/preopen.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdl_la-preopen.lo -MD -MP -MF $(DEPDIR)/libltdl_la-preopen.Tpo -c -o libltdl_la-preopen.lo `test -f 'loaders/preopen.c' || echo '$(srcdir)/'`loaders/preopen.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libltdl_la-preopen.Tpo $(DEPDIR)/libltdl_la-preopen.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/preopen.c' object='libltdl_la-preopen.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdl_la-preopen.lo `test -f 'loaders/preopen.c' || echo '$(srcdir)/'`loaders/preopen.c + +libltdl_la-lt__alloc.lo: lt__alloc.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdl_la-lt__alloc.lo -MD -MP -MF $(DEPDIR)/libltdl_la-lt__alloc.Tpo -c -o libltdl_la-lt__alloc.lo `test -f 'lt__alloc.c' || echo '$(srcdir)/'`lt__alloc.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libltdl_la-lt__alloc.Tpo $(DEPDIR)/libltdl_la-lt__alloc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lt__alloc.c' object='libltdl_la-lt__alloc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdl_la-lt__alloc.lo `test -f 'lt__alloc.c' || echo '$(srcdir)/'`lt__alloc.c + +libltdl_la-lt_dlloader.lo: lt_dlloader.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdl_la-lt_dlloader.lo -MD -MP -MF $(DEPDIR)/libltdl_la-lt_dlloader.Tpo -c -o libltdl_la-lt_dlloader.lo `test -f 'lt_dlloader.c' || echo '$(srcdir)/'`lt_dlloader.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libltdl_la-lt_dlloader.Tpo $(DEPDIR)/libltdl_la-lt_dlloader.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lt_dlloader.c' object='libltdl_la-lt_dlloader.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdl_la-lt_dlloader.lo `test -f 'lt_dlloader.c' || echo '$(srcdir)/'`lt_dlloader.c + +libltdl_la-lt_error.lo: lt_error.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdl_la-lt_error.lo -MD -MP -MF $(DEPDIR)/libltdl_la-lt_error.Tpo -c -o libltdl_la-lt_error.lo `test -f 'lt_error.c' || echo '$(srcdir)/'`lt_error.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libltdl_la-lt_error.Tpo $(DEPDIR)/libltdl_la-lt_error.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lt_error.c' object='libltdl_la-lt_error.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdl_la-lt_error.lo `test -f 'lt_error.c' || echo '$(srcdir)/'`lt_error.c + +libltdl_la-ltdl.lo: ltdl.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdl_la-ltdl.lo -MD -MP -MF $(DEPDIR)/libltdl_la-ltdl.Tpo -c -o libltdl_la-ltdl.lo `test -f 'ltdl.c' || echo '$(srcdir)/'`ltdl.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libltdl_la-ltdl.Tpo $(DEPDIR)/libltdl_la-ltdl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ltdl.c' object='libltdl_la-ltdl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdl_la-ltdl.lo `test -f 'ltdl.c' || echo '$(srcdir)/'`ltdl.c + +libltdl_la-slist.lo: slist.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdl_la-slist.lo -MD -MP -MF $(DEPDIR)/libltdl_la-slist.Tpo -c -o libltdl_la-slist.lo `test -f 'slist.c' || echo '$(srcdir)/'`slist.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libltdl_la-slist.Tpo $(DEPDIR)/libltdl_la-slist.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='slist.c' object='libltdl_la-slist.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdl_la-slist.lo `test -f 'slist.c' || echo '$(srcdir)/'`slist.c + +libltdlc_la-preopen.lo: loaders/preopen.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdlc_la-preopen.lo -MD -MP -MF $(DEPDIR)/libltdlc_la-preopen.Tpo -c -o libltdlc_la-preopen.lo `test -f 'loaders/preopen.c' || echo '$(srcdir)/'`loaders/preopen.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libltdlc_la-preopen.Tpo $(DEPDIR)/libltdlc_la-preopen.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/preopen.c' object='libltdlc_la-preopen.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdlc_la-preopen.lo `test -f 'loaders/preopen.c' || echo '$(srcdir)/'`loaders/preopen.c + +libltdlc_la-lt__alloc.lo: lt__alloc.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdlc_la-lt__alloc.lo -MD -MP -MF $(DEPDIR)/libltdlc_la-lt__alloc.Tpo -c -o libltdlc_la-lt__alloc.lo `test -f 'lt__alloc.c' || echo '$(srcdir)/'`lt__alloc.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libltdlc_la-lt__alloc.Tpo $(DEPDIR)/libltdlc_la-lt__alloc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lt__alloc.c' object='libltdlc_la-lt__alloc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdlc_la-lt__alloc.lo `test -f 'lt__alloc.c' || echo '$(srcdir)/'`lt__alloc.c + +libltdlc_la-lt_dlloader.lo: lt_dlloader.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdlc_la-lt_dlloader.lo -MD -MP -MF $(DEPDIR)/libltdlc_la-lt_dlloader.Tpo -c -o libltdlc_la-lt_dlloader.lo `test -f 'lt_dlloader.c' || echo '$(srcdir)/'`lt_dlloader.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libltdlc_la-lt_dlloader.Tpo $(DEPDIR)/libltdlc_la-lt_dlloader.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lt_dlloader.c' object='libltdlc_la-lt_dlloader.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdlc_la-lt_dlloader.lo `test -f 'lt_dlloader.c' || echo '$(srcdir)/'`lt_dlloader.c + +libltdlc_la-lt_error.lo: lt_error.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdlc_la-lt_error.lo -MD -MP -MF $(DEPDIR)/libltdlc_la-lt_error.Tpo -c -o libltdlc_la-lt_error.lo `test -f 'lt_error.c' || echo '$(srcdir)/'`lt_error.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libltdlc_la-lt_error.Tpo $(DEPDIR)/libltdlc_la-lt_error.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lt_error.c' object='libltdlc_la-lt_error.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdlc_la-lt_error.lo `test -f 'lt_error.c' || echo '$(srcdir)/'`lt_error.c + +libltdlc_la-ltdl.lo: ltdl.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdlc_la-ltdl.lo -MD -MP -MF $(DEPDIR)/libltdlc_la-ltdl.Tpo -c -o libltdlc_la-ltdl.lo `test -f 'ltdl.c' || echo '$(srcdir)/'`ltdl.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libltdlc_la-ltdl.Tpo $(DEPDIR)/libltdlc_la-ltdl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ltdl.c' object='libltdlc_la-ltdl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdlc_la-ltdl.lo `test -f 'ltdl.c' || echo '$(srcdir)/'`ltdl.c + +libltdlc_la-slist.lo: slist.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libltdlc_la-slist.lo -MD -MP -MF $(DEPDIR)/libltdlc_la-slist.Tpo -c -o libltdlc_la-slist.lo `test -f 'slist.c' || echo '$(srcdir)/'`slist.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libltdlc_la-slist.Tpo $(DEPDIR)/libltdlc_la-slist.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='slist.c' object='libltdlc_la-slist.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libltdlc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libltdlc_la-slist.lo `test -f 'slist.c' || echo '$(srcdir)/'`slist.c + +load_add_on.lo: loaders/load_add_on.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT load_add_on.lo -MD -MP -MF $(DEPDIR)/load_add_on.Tpo -c -o load_add_on.lo `test -f 'loaders/load_add_on.c' || echo '$(srcdir)/'`loaders/load_add_on.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/load_add_on.Tpo $(DEPDIR)/load_add_on.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/load_add_on.c' object='load_add_on.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o load_add_on.lo `test -f 'loaders/load_add_on.c' || echo '$(srcdir)/'`loaders/load_add_on.c + +loadlibrary.lo: loaders/loadlibrary.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT loadlibrary.lo -MD -MP -MF $(DEPDIR)/loadlibrary.Tpo -c -o loadlibrary.lo `test -f 'loaders/loadlibrary.c' || echo '$(srcdir)/'`loaders/loadlibrary.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/loadlibrary.Tpo $(DEPDIR)/loadlibrary.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/loadlibrary.c' object='loadlibrary.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o loadlibrary.lo `test -f 'loaders/loadlibrary.c' || echo '$(srcdir)/'`loaders/loadlibrary.c + +shl_load.lo: loaders/shl_load.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shl_load.lo -MD -MP -MF $(DEPDIR)/shl_load.Tpo -c -o shl_load.lo `test -f 'loaders/shl_load.c' || echo '$(srcdir)/'`loaders/shl_load.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/shl_load.Tpo $(DEPDIR)/shl_load.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loaders/shl_load.c' object='shl_load.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shl_load.lo `test -f 'loaders/shl_load.c' || echo '$(srcdir)/'`loaders/shl_load.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) +install-ltdlincludeHEADERS: $(ltdlinclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(ltdlinclude_HEADERS)'; test -n "$(ltdlincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(ltdlincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(ltdlincludedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(ltdlincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(ltdlincludedir)" || exit $$?; \ + done + +uninstall-ltdlincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(ltdlinclude_HEADERS)'; test -n "$(ltdlincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(ltdlincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscopelist: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(ltdlincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS install-ltdlincludeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \ + uninstall-ltdlincludeHEADERS + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \ + cscopelist ctags distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am \ + install-includeHEADERS install-info install-info-am \ + install-libLTLIBRARIES install-ltdlincludeHEADERS install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-includeHEADERS uninstall-libLTLIBRARIES \ + uninstall-ltdlincludeHEADERS + + +# We need the following in order to create an <argz.h> when the system +# doesn't have one that works with the given compiler. +all-local $(lib_OBJECTS): $(ARGZ_H) +argz.h: argz_.h + cp $(srcdir)/argz_.h $@-t + mv $@-t $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libltdl/README b/libltdl/README new file mode 100644 index 0000000..90a0aef --- /dev/null +++ b/libltdl/README @@ -0,0 +1,20 @@ +This is GNU libltdl, a system independent dlopen wrapper for GNU libtool. + +It supports the following dlopen interfaces: +* dlopen (POSIX) +* shl_load (HP-UX) +* LoadLibrary (Win16 and Win32) +* load_add_on (BeOS) +* GNU DLD (emulates dynamic linking for static libraries) +* dyld (darwin/Mac OS X) +* libtool's dlpreopen +-- + Copyright (C) 1999, 2003, 2011 Free Software Foundation, Inc. + Written by Thomas Tanner, 1999 + + This file is part of GNU Libtool. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. diff --git a/libltdl/argz.c b/libltdl/argz.c new file mode 100644 index 0000000..8567723 --- /dev/null +++ b/libltdl/argz.c @@ -0,0 +1,226 @@ +/* argz.c -- argz implementation for non-glibc systems + + Copyright (C) 2004, 2006, 2007, 2008 Free Software Foundation, Inc. + Written by Gary V. Vaughan, 2004 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#if defined(LTDL) && defined LT_CONFIG_H +# include LT_CONFIG_H +#else +# include <config.h> +#endif + +#include <argz.h> + +#include <assert.h> +#include <stddef.h> +#include <stdlib.h> +#include <sys/types.h> +#include <errno.h> +#include <string.h> + +#define EOS_CHAR '\0' + +error_t +argz_append (char **pargz, size_t *pargz_len, const char *buf, size_t buf_len) +{ + size_t argz_len; + char *argz; + + assert (pargz); + assert (pargz_len); + assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len)); + + /* If nothing needs to be appended, no more work is required. */ + if (buf_len == 0) + return 0; + + /* Ensure there is enough room to append BUF_LEN. */ + argz_len = *pargz_len + buf_len; + argz = (char *) realloc (*pargz, argz_len); + if (!argz) + return ENOMEM; + + /* Copy characters from BUF after terminating '\0' in ARGZ. */ + memcpy (argz + *pargz_len, buf, buf_len); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + + return 0; +} + + +error_t +argz_create_sep (const char *str, int delim, char **pargz, size_t *pargz_len) +{ + size_t argz_len; + char *argz = 0; + + assert (str); + assert (pargz); + assert (pargz_len); + + /* Make a copy of STR, but replacing each occurrence of + DELIM with '\0'. */ + argz_len = 1+ strlen (str); + if (argz_len) + { + const char *p; + char *q; + + argz = (char *) malloc (argz_len); + if (!argz) + return ENOMEM; + + for (p = str, q = argz; *p != EOS_CHAR; ++p) + { + if (*p == delim) + { + /* Ignore leading delimiters, and fold consecutive + delimiters in STR into a single '\0' in ARGZ. */ + if ((q > argz) && (q[-1] != EOS_CHAR)) + *q++ = EOS_CHAR; + else + --argz_len; + } + else + *q++ = *p; + } + /* Copy terminating EOS_CHAR. */ + *q = *p; + } + + /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */ + if (!argz_len) + argz = (free (argz), (char *) 0); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + + return 0; +} + + +error_t +argz_insert (char **pargz, size_t *pargz_len, char *before, const char *entry) +{ + assert (pargz); + assert (pargz_len); + assert (entry && *entry); + + /* No BEFORE address indicates ENTRY should be inserted after the + current last element. */ + if (!before) + return argz_append (pargz, pargz_len, entry, 1+ strlen (entry)); + + /* This probably indicates a programmer error, but to preserve + semantics, scan back to the start of an entry if BEFORE points + into the middle of it. */ + while ((before > *pargz) && (before[-1] != EOS_CHAR)) + --before; + + { + size_t entry_len = 1+ strlen (entry); + size_t argz_len = *pargz_len + entry_len; + size_t offset = before - *pargz; + char *argz = (char *) realloc (*pargz, argz_len); + + if (!argz) + return ENOMEM; + + /* Make BEFORE point to the equivalent offset in ARGZ that it + used to have in *PARGZ incase realloc() moved the block. */ + before = argz + offset; + + /* Move the ARGZ entries starting at BEFORE up into the new + space at the end -- making room to copy ENTRY into the + resulting gap. */ + memmove (before + entry_len, before, *pargz_len - offset); + memcpy (before, entry, entry_len); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + } + + return 0; +} + + +char * +argz_next (char *argz, size_t argz_len, const char *entry) +{ + assert ((argz && argz_len) || (!argz && !argz_len)); + + if (entry) + { + /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address + within the ARGZ vector. */ + assert ((!argz && !argz_len) + || ((argz <= entry) && (entry < (argz + argz_len)))); + + /* Move to the char immediately after the terminating + '\0' of ENTRY. */ + entry = 1+ strchr (entry, EOS_CHAR); + + /* Return either the new ENTRY, or else NULL if ARGZ is + exhausted. */ + return (entry >= argz + argz_len) ? 0 : (char *) entry; + } + else + { + /* This should probably be flagged as a programmer error, + since starting an argz_next loop with the iterator set + to ARGZ is safer. To preserve semantics, handle the NULL + case by returning the start of ARGZ (if any). */ + if (argz_len > 0) + return argz; + else + return 0; + } +} + + +void +argz_stringify (char *argz, size_t argz_len, int sep) +{ + assert ((argz && argz_len) || (!argz && !argz_len)); + + if (sep) + { + --argz_len; /* don't stringify the terminating EOS */ + while (--argz_len > 0) + { + if (argz[argz_len] == EOS_CHAR) + argz[argz_len] = sep; + } + } +} + diff --git a/libltdl/argz_.h b/libltdl/argz_.h new file mode 100644 index 0000000..0557575 --- /dev/null +++ b/libltdl/argz_.h @@ -0,0 +1,68 @@ +/* lt__argz.h -- internal argz interface for non-glibc systems + + Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. + Written by Gary V. Vaughan, 2004 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if !defined(LT__ARGZ_H) +#define LT__ARGZ_H 1 + +#include <stdlib.h> +#define __need_error_t +#include <errno.h> +#include <sys/types.h> + +#if defined(LTDL) +# include "lt__glibc.h" +# include "lt_system.h" +#else +# define LT_SCOPE +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +LT_SCOPE error_t argz_append (char **pargz, size_t *pargz_len, + const char *buf, size_t buf_len); +LT_SCOPE error_t argz_create_sep(const char *str, int delim, + char **pargz, size_t *pargz_len); +LT_SCOPE error_t argz_insert (char **pargz, size_t *pargz_len, + char *before, const char *entry); +LT_SCOPE char * argz_next (char *argz, size_t argz_len, + const char *entry); +LT_SCOPE void argz_stringify (char *argz, size_t argz_len, int sep); + +#if defined(__cplusplus) +} +#endif + +#if !defined(LTDL) +# undef LT_SCOPE +#endif + +#endif /*!defined(LT__ARGZ_H)*/ diff --git a/libltdl/libltdl/lt__alloc.h b/libltdl/libltdl/lt__alloc.h new file mode 100644 index 0000000..1ceddf0 --- /dev/null +++ b/libltdl/libltdl/lt__alloc.h @@ -0,0 +1,58 @@ +/* lt__alloc.h -- internal memory management interface + + Copyright (C) 2004 Free Software Foundation, Inc. + Written by Gary V. Vaughan, 2004 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if !defined(LT__ALLOC_H) +#define LT__ALLOC_H 1 + +#include "lt_system.h" + +LT_BEGIN_C_DECLS + +#define MALLOC(tp, n) (tp*) lt__malloc((n) * sizeof(tp)) +#define REALLOC(tp, mem, n) (tp*) lt__realloc((mem), (n) * sizeof(tp)) +#define FREE(mem) LT_STMT_START { \ + if (mem) { free ((void *)mem); mem = NULL; } } LT_STMT_END +#define MEMREASSIGN(p, q) LT_STMT_START { \ + if ((p) != (q)) { if (p) free (p); (p) = (q); (q) = 0; } \ + } LT_STMT_END + +/* If set, this function is called when memory allocation has failed. */ +LT_SCOPE void (*lt__alloc_die) (void); + +LT_SCOPE void *lt__malloc (size_t n); +LT_SCOPE void *lt__zalloc (size_t n); +LT_SCOPE void *lt__realloc (void *mem, size_t n); +LT_SCOPE void *lt__memdup (void const *mem, size_t n); + +LT_SCOPE char *lt__strdup (const char *string); + +LT_END_C_DECLS + +#endif /*!defined(LT__ALLOC_H)*/ diff --git a/libltdl/libltdl/lt__dirent.h b/libltdl/libltdl/lt__dirent.h new file mode 100644 index 0000000..4f24f82 --- /dev/null +++ b/libltdl/libltdl/lt__dirent.h @@ -0,0 +1,87 @@ +/* lt__dirent.h -- internal directory entry scanning interface + + Copyright (C) 2001, 2004, 2006 Free Software Foundation, Inc. + Written by Bob Friesenhahn, 2001 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if !defined(LT__DIRENT_H) +#define LT__DIRENT_H 1 + +#if defined(LT_CONFIG_H) +# include LT_CONFIG_H +#else +# include <config.h> +#endif + +#include "lt_system.h" + +#ifdef HAVE_DIRENT_H +/* We have a fully operational dirent subsystem. */ +# include <dirent.h> +# define D_NAMLEN(dirent) (strlen((dirent)->d_name)) + +#elif defined __WINDOWS__ +/* Use some wrapper code to emulate dirent on windows.. */ +# define WINDOWS_DIRENT_EMULATION 1 + +# include <windows.h> + +# define D_NAMLEN(dirent) (strlen((dirent)->d_name)) +# define dirent lt__dirent +# define DIR lt__DIR +# define opendir lt__opendir +# define readdir lt__readdir +# define closedir lt__closedir + +LT_BEGIN_C_DECLS + +struct dirent +{ + char d_name[LT_FILENAME_MAX]; + int d_namlen; +}; + +typedef struct +{ + HANDLE hSearch; + WIN32_FIND_DATA Win32FindData; + BOOL firsttime; + struct dirent file_info; +} DIR; + + +LT_SCOPE DIR * opendir (const char *path); +LT_SCOPE struct dirent *readdir (DIR *entry); +LT_SCOPE void closedir (DIR *entry); + +LT_END_C_DECLS + +#else /* !defined(__WINDOWS__)*/ +ERROR - cannot find dirent +#endif /*!defined(__WINDOWS__)*/ + +#endif /*!defined(LT__DIRENT_H)*/ diff --git a/libltdl/libltdl/lt__glibc.h b/libltdl/libltdl/lt__glibc.h new file mode 100644 index 0000000..f284773 --- /dev/null +++ b/libltdl/libltdl/lt__glibc.h @@ -0,0 +1,83 @@ +/* lt__glibc.h -- support for non glibc environments + + Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc. + Written by Gary V. Vaughan, 2004 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if !defined(LT__GLIBC_H) +#define LT__GLIBC_H 1 + +#if defined(LT_CONFIG_H) +# include LT_CONFIG_H +#else +# include <config.h> +#endif + +#if !defined(HAVE_ARGZ_H) || !defined(HAVE_WORKING_ARGZ) +/* Redefine any glibc symbols we reimplement to import the + implementations into our lt__ namespace so we don't ever + clash with the system library if our clients use argz_* + from there in addition to libltdl. */ +# undef argz_append +# define argz_append lt__argz_append +# undef argz_create_sep +# define argz_create_sep lt__argz_create_sep +# undef argz_insert +# define argz_insert lt__argz_insert +# undef argz_next +# define argz_next lt__argz_next +# undef argz_stringify +# define argz_stringify lt__argz_stringify +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include <argz.h> + +#ifdef __cplusplus +} +#endif + +# define slist_concat lt__slist_concat +# define slist_cons lt__slist_cons +# define slist_delete lt__slist_delete +# define slist_remove lt__slist_remove +# define slist_reverse lt__slist_reverse +# define slist_sort lt__slist_sort +# define slist_tail lt__slist_tail +# define slist_nth lt__slist_nth +# define slist_find lt__slist_find +# define slist_length lt__slist_length +# define slist_foreach lt__slist_foreach +# define slist_box lt__slist_box +# define slist_unbox lt__slist_unbox + +#include <slist.h> + +#endif /*!defined(LT__GLIBC_H)*/ diff --git a/libltdl/libltdl/lt__private.h b/libltdl/libltdl/lt__private.h new file mode 100644 index 0000000..f4c4a3d --- /dev/null +++ b/libltdl/libltdl/lt__private.h @@ -0,0 +1,149 @@ +/* lt__private.h -- internal apis for libltdl + + Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + Written by Gary V. Vaughan, 2004 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy con be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if !defined(LT__PRIVATE_H) +#define LT__PRIVATE_H 1 + +#if defined(LT_CONFIG_H) +# include LT_CONFIG_H +#else +# include <config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#include <assert.h> +#include <errno.h> +#include <string.h> + +#if defined(HAVE_UNISTD_H) +# include <unistd.h> +#endif + +/* Import internal interfaces... */ +#include "lt__alloc.h" +#include "lt__dirent.h" +#include "lt__strl.h" +#include "lt__glibc.h" + +/* ...and all exported interfaces. */ +#include "ltdl.h" + +#if defined(WITH_DMALLOC) +# include <dmalloc.h> +#endif + +/* DLL building support on win32 hosts; mostly to workaround their + ridiculous implementation of data symbol exporting. */ +#ifndef LT_GLOBAL_DATA +# if defined(__WINDOWS__) || defined(__CYGWIN__) +# if defined(DLL_EXPORT) /* defined by libtool (if required) */ +# define LT_GLOBAL_DATA __declspec(dllexport) +# endif +# endif +# ifndef LT_GLOBAL_DATA +# define LT_GLOBAL_DATA /* static linking or !__WINDOWS__ */ +# endif +#endif + +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ +# define __attribute__(x) +# endif +#endif + +#ifndef LT__UNUSED +# define LT__UNUSED __attribute__ ((__unused__)) +#endif + + +LT_BEGIN_C_DECLS + +#if !defined(errno) +extern int errno; +#endif + +LT_SCOPE void lt__alloc_die_callback (void); + + +/* For readability: */ +#define strneq(s1, s2) (strcmp((s1), (s2)) != 0) +#define streq(s1, s2) (!strcmp((s1), (s2))) + + + +/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */ + +/* This type is used for the array of interface data sets in each handler. */ +typedef struct { + lt_dlinterface_id key; + void * data; +} lt_interface_data; + +struct lt__handle { + lt_dlhandle next; + const lt_dlvtable * vtable; /* dlopening interface */ + lt_dlinfo info; /* user visible fields */ + int depcount; /* number of dependencies */ + lt_dlhandle * deplibs; /* dependencies */ + lt_module module; /* system module handle */ + void * system; /* system specific data */ + lt_interface_data * interface_data; /* per caller associated data */ + int flags; /* various boolean stats */ +}; + +struct lt__advise { + unsigned int try_ext:1; /* try system library extensions. */ + unsigned int is_resident:1; /* module can't be unloaded. */ + unsigned int is_symglobal:1; /* module symbols can satisfy + subsequently loaded modules. */ + unsigned int is_symlocal:1; /* module symbols are only available + locally. */ + unsigned int try_preload_only:1;/* only preloaded modules will be tried. */ +}; + +/* --- ERROR HANDLING --- */ + +/* Extract the diagnostic strings from the error table macro in the same + order as the enumerated indices in lt_error.h. */ + +#define LT__STRERROR(name) lt__error_string(LT_CONC(LT_ERROR_,name)) + +#define LT__GETERROR(lvalue) (lvalue) = lt__get_last_error() +#define LT__SETERRORSTR(errormsg) lt__set_last_error(errormsg) +#define LT__SETERROR(errorcode) LT__SETERRORSTR(LT__STRERROR(errorcode)) + +LT_SCOPE const char *lt__error_string (int errorcode); +LT_SCOPE const char *lt__get_last_error (void); +LT_SCOPE const char *lt__set_last_error (const char *errormsg); + +LT_END_C_DECLS + +#endif /*!defined(LT__PRIVATE_H)*/ diff --git a/libltdl/libltdl/lt__strl.h b/libltdl/libltdl/lt__strl.h new file mode 100644 index 0000000..5799dc8 --- /dev/null +++ b/libltdl/libltdl/lt__strl.h @@ -0,0 +1,53 @@ +/* lt__strl.h -- size-bounded string copying and concatenation + + Copyright (C) 2004, 2006 Free Software Foundation, Inc. + Written by Bob Friesenhahn, 2004 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#if !defined(LT__STRL_H) +#define LT__STRL_H 1 + +#if defined(LT_CONFIG_H) +# include LT_CONFIG_H +#else +# include <config.h> +#endif + +#include <string.h> +#include "lt_system.h" + +#if !defined(HAVE_STRLCAT) +# define strlcat(dst,src,dstsize) lt_strlcat(dst,src,dstsize) +LT_SCOPE size_t lt_strlcat(char *dst, const char *src, const size_t dstsize); +#endif /* !defined(HAVE_STRLCAT) */ + +#if !defined(HAVE_STRLCPY) +# define strlcpy(dst,src,dstsize) lt_strlcpy(dst,src,dstsize) +LT_SCOPE size_t lt_strlcpy(char *dst, const char *src, const size_t dstsize); +#endif /* !defined(HAVE_STRLCPY) */ + +#endif /*!defined(LT__STRL_H)*/ diff --git a/libltdl/libltdl/lt_dlloader.h b/libltdl/libltdl/lt_dlloader.h new file mode 100644 index 0000000..589fd0d --- /dev/null +++ b/libltdl/libltdl/lt_dlloader.h @@ -0,0 +1,90 @@ +/* lt_dlloader.h -- dynamic library loader interface + + Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. + Written by Gary V. Vaughan, 2004 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#if !defined(LT_DLLOADER_H) +#define LT_DLLOADER_H 1 + +#include <libltdl/lt_system.h> + +LT_BEGIN_C_DECLS + +typedef void * lt_dlloader; +typedef void * lt_module; +typedef void * lt_user_data; +typedef struct lt__advise * lt_dladvise; + +/* Function pointer types for module loader vtable entries: */ +typedef lt_module lt_module_open (lt_user_data data, + const char *filename, + lt_dladvise advise); +typedef int lt_module_close (lt_user_data data, + lt_module module); +typedef void * lt_find_sym (lt_user_data data, lt_module module, + const char *symbolname); +typedef int lt_dlloader_init (lt_user_data data); +typedef int lt_dlloader_exit (lt_user_data data); + +/* Default priority is LT_DLLOADER_PREPEND if none is explicitly given. */ +typedef enum { + LT_DLLOADER_PREPEND = 0, LT_DLLOADER_APPEND +} lt_dlloader_priority; + +/* This structure defines a module loader, as populated by the get_vtable + entry point of each loader. */ +typedef struct { + const char * name; + const char * sym_prefix; + lt_module_open * module_open; + lt_module_close * module_close; + lt_find_sym * find_sym; + lt_dlloader_init * dlloader_init; + lt_dlloader_exit * dlloader_exit; + lt_user_data dlloader_data; + lt_dlloader_priority priority; +} lt_dlvtable; + +LT_SCOPE int lt_dlloader_add (const lt_dlvtable *vtable); +LT_SCOPE lt_dlloader lt_dlloader_next (const lt_dlloader loader); + +LT_SCOPE lt_dlvtable * lt_dlloader_remove (const char *name); +LT_SCOPE const lt_dlvtable *lt_dlloader_find (const char *name); +LT_SCOPE const lt_dlvtable *lt_dlloader_get (lt_dlloader loader); + + +/* Type of a function to get a loader's vtable: */ +typedef const lt_dlvtable *lt_get_vtable (lt_user_data data); + +#ifdef LT_DEBUG_LOADERS +LT_SCOPE void lt_dlloader_dump (void); +#endif + +LT_END_C_DECLS + +#endif /*!defined(LT_DLLOADER_H)*/ diff --git a/libltdl/libltdl/lt_error.h b/libltdl/libltdl/lt_error.h new file mode 100644 index 0000000..e789b3a --- /dev/null +++ b/libltdl/libltdl/lt_error.h @@ -0,0 +1,85 @@ +/* lt_error.h -- error propogation interface + + Copyright (C) 1999, 2000, 2001, 2004, 2007 Free Software Foundation, Inc. + Written by Thomas Tanner, 1999 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/* Only include this header file once. */ +#if !defined(LT_ERROR_H) +#define LT_ERROR_H 1 + +#include <libltdl/lt_system.h> + +LT_BEGIN_C_DECLS + +/* Defining error strings alongside their symbolic names in a macro in + this way allows us to expand the macro in different contexts with + confidence that the enumeration of symbolic names will map correctly + onto the table of error strings. \0 is appended to the strings to + expilicitely initialize the string terminator. */ +#define lt_dlerror_table \ + LT_ERROR(UNKNOWN, "unknown error\0") \ + LT_ERROR(DLOPEN_NOT_SUPPORTED, "dlopen support not available\0") \ + LT_ERROR(INVALID_LOADER, "invalid loader\0") \ + LT_ERROR(INIT_LOADER, "loader initialization failed\0") \ + LT_ERROR(REMOVE_LOADER, "loader removal failed\0") \ + LT_ERROR(FILE_NOT_FOUND, "file not found\0") \ + LT_ERROR(DEPLIB_NOT_FOUND, "dependency library not found\0") \ + LT_ERROR(NO_SYMBOLS, "no symbols defined\0") \ + LT_ERROR(CANNOT_OPEN, "can't open the module\0") \ + LT_ERROR(CANNOT_CLOSE, "can't close the module\0") \ + LT_ERROR(SYMBOL_NOT_FOUND, "symbol not found\0") \ + LT_ERROR(NO_MEMORY, "not enough memory\0") \ + LT_ERROR(INVALID_HANDLE, "invalid module handle\0") \ + LT_ERROR(BUFFER_OVERFLOW, "internal buffer overflow\0") \ + LT_ERROR(INVALID_ERRORCODE, "invalid errorcode\0") \ + LT_ERROR(SHUTDOWN, "library already shutdown\0") \ + LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module\0") \ + LT_ERROR(INVALID_MUTEX_ARGS, "internal error (code withdrawn)\0")\ + LT_ERROR(INVALID_POSITION, "invalid search path insert position\0")\ + LT_ERROR(CONFLICTING_FLAGS, "symbol visibility can be global or local\0") + +/* Enumerate the symbolic error names. */ +enum { +#define LT_ERROR(name, diagnostic) LT_CONC(LT_ERROR_, name), + lt_dlerror_table +#undef LT_ERROR + + LT_ERROR_MAX +}; + +/* Should be max of the error string lengths above (plus one for C++) */ +#define LT_ERROR_LEN_MAX (41) + +/* These functions are only useful from inside custom module loaders. */ +LT_SCOPE int lt_dladderror (const char *diagnostic); +LT_SCOPE int lt_dlseterror (int errorcode); + + +LT_END_C_DECLS + +#endif /*!defined(LT_ERROR_H)*/ diff --git a/libltdl/libltdl/lt_system.h b/libltdl/libltdl/lt_system.h new file mode 100644 index 0000000..f1545ce --- /dev/null +++ b/libltdl/libltdl/lt_system.h @@ -0,0 +1,166 @@ +/* lt_system.h -- system portability abstraction layer + + Copyright (C) 2004, 2007, 2010 Free Software Foundation, Inc. + Written by Gary V. Vaughan, 2004 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#if !defined(LT_SYSTEM_H) +#define LT_SYSTEM_H 1 + +#include <stddef.h> +#include <stdlib.h> +#include <sys/types.h> + +/* Some systems do not define EXIT_*, even with STDC_HEADERS. */ +#if !defined(EXIT_SUCCESS) +# define EXIT_SUCCESS 0 +#endif +#if !defined(EXIT_FAILURE) +# define EXIT_FAILURE 1 +#endif + +/* Just pick a big number... */ +#define LT_FILENAME_MAX 2048 + + +/* Saves on those hard to debug '\0' typos.... */ +#define LT_EOS_CHAR '\0' + +/* LTDL_BEGIN_C_DECLS should be used at the beginning of your declarations, + so that C++ compilers don't mangle their names. Use LTDL_END_C_DECLS at + the end of C declarations. */ +#if defined(__cplusplus) +# define LT_BEGIN_C_DECLS extern "C" { +# define LT_END_C_DECLS } +#else +# define LT_BEGIN_C_DECLS /* empty */ +# define LT_END_C_DECLS /* empty */ +#endif + +/* LT_STMT_START/END are used to create macros which expand to a + a single compound statement in a portable way. */ +#if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus) +# define LT_STMT_START (void)( +# define LT_STMT_END ) +#else +# if (defined (sun) || defined (__sun__)) +# define LT_STMT_START if (1) +# define LT_STMT_END else (void)0 +# else +# define LT_STMT_START do +# define LT_STMT_END while (0) +# endif +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +/* Canonicalise Windows and Cygwin recognition macros. + To match the values set by recent Cygwin compilers, make sure that if + __CYGWIN__ is defined (after canonicalisation), __WINDOWS__ is NOT! */ +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if defined(__CYGWIN__) +# if defined(__WINDOWS__) +# undef __WINDOWS__ +# endif +#elif defined(_WIN32) +# define __WINDOWS__ _WIN32 +#elif defined(WIN32) +# define __WINDOWS__ WIN32 +#endif +#if defined(__CYGWIN__) && defined(__WINDOWS__) +# undef __WINDOWS__ +#endif + + +/* DLL building support on win32 hosts; mostly to workaround their + ridiculous implementation of data symbol exporting. */ +#if !defined(LT_SCOPE) +# if defined(__WINDOWS__) || defined(__CYGWIN__) +# if defined(DLL_EXPORT) /* defined by libtool (if required) */ +# define LT_SCOPE extern __declspec(dllexport) +# endif +# if defined(LIBLTDL_DLL_IMPORT) /* define if linking with this dll */ + /* note: cygwin/mingw compilers can rely instead on auto-import */ +# define LT_SCOPE extern __declspec(dllimport) +# endif +# endif +# if !defined(LT_SCOPE) /* static linking or !__WINDOWS__ */ +# define LT_SCOPE extern +# endif +#endif + +#if defined(__WINDOWS__) +/* LT_DIRSEP_CHAR is accepted *in addition* to '/' as a directory + separator when it is set. */ +# define LT_DIRSEP_CHAR '\\' +# define LT_PATHSEP_CHAR ';' +#else +# define LT_PATHSEP_CHAR ':' +#endif + +#if defined(_MSC_VER) /* Visual Studio */ +# define R_OK 4 +#endif + +/* fopen() mode flags for reading a text file */ +#undef LT_READTEXT_MODE +#if defined(__WINDOWS__) || defined(__CYGWIN__) +# define LT_READTEXT_MODE "rt" +#else +# define LT_READTEXT_MODE "r" +#endif + +/* The extra indirection to the LT__STR and LT__CONC macros is required so + that if the arguments to LT_STR() (or LT_CONC()) are themselves macros, + they will be expanded before being quoted. */ +#ifndef LT_STR +# define LT__STR(arg) #arg +# define LT_STR(arg) LT__STR(arg) +#endif + +#ifndef LT_CONC +# define LT__CONC(a, b) a##b +# define LT_CONC(a, b) LT__CONC(a, b) +#endif +#ifndef LT_CONC3 +# define LT__CONC3(a, b, c) a##b##c +# define LT_CONC3(a, b, c) LT__CONC3(a, b, c) +#endif + +#endif /*!defined(LT_SYSTEM_H)*/ diff --git a/libltdl/libltdl/slist.h b/libltdl/libltdl/slist.h new file mode 100644 index 0000000..4d56509 --- /dev/null +++ b/libltdl/libltdl/slist.h @@ -0,0 +1,96 @@ +/* slist.h -- generalised singly linked lists + + Copyright (C) 2000, 2004, 2009 Free Software Foundation, Inc. + Written by Gary V. Vaughan, 2000 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/* A generalised list. This is deliberately transparent so that you + can make the NEXT field of all your chained data structures first, + and then cast them to `(SList *)' so that they can be manipulated + by this API. + + Alternatively, you can generate raw SList elements using slist_new(), + and put the element data in the USERDATA field. Either way you + get to manage the memory involved by yourself. +*/ + +#if !defined(SLIST_H) +#define SLIST_H 1 + +#if defined(LTDL) +# include <libltdl/lt__glibc.h> +# include <libltdl/lt_system.h> +#else +# define LT_SCOPE +#endif + +#include <stddef.h> + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef struct slist { + struct slist *next; /* chain forward pointer*/ + const void *userdata; /* for boxed `SList' item */ +} SList; + +typedef void * SListCallback (SList *item, void *userdata); +typedef int SListCompare (const SList *item1, const SList *item2, + void *userdata); + +LT_SCOPE SList *slist_concat (SList *head, SList *tail); +LT_SCOPE SList *slist_cons (SList *item, SList *slist); + +LT_SCOPE SList *slist_delete (SList *slist, void (*delete_fct) (void *item)); +LT_SCOPE SList *slist_remove (SList **phead, SListCallback *find, + void *matchdata); +LT_SCOPE SList *slist_reverse (SList *slist); +LT_SCOPE SList *slist_sort (SList *slist, SListCompare *compare, + void *userdata); + +LT_SCOPE SList *slist_tail (SList *slist); +LT_SCOPE SList *slist_nth (SList *slist, size_t n); +LT_SCOPE void * slist_find (SList *slist, SListCallback *find, + void *matchdata); +LT_SCOPE size_t slist_length (SList *slist); + +LT_SCOPE void * slist_foreach (SList *slist, SListCallback *foreach, + void *userdata); + +LT_SCOPE SList *slist_box (const void *userdata); +LT_SCOPE void * slist_unbox (SList *item); + +#if defined(__cplusplus) +} +#endif + +#if !defined(LTDL) +# undef LT_SCOPE +#endif + +#endif /*!defined(SLIST_H)*/ diff --git a/libltdl/loaders/dld_link.c b/libltdl/loaders/dld_link.c new file mode 100644 index 0000000..7e882c9 --- /dev/null +++ b/libltdl/loaders/dld_link.c @@ -0,0 +1,158 @@ +/* loader-dld_link.c -- dynamic linking with dld + + Copyright (C) 1998, 1999, 2000, 2004, 2006, + 2007, 2008 Free Software Foundation, Inc. + Written by Thomas Tanner, 1998 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "lt__private.h" +#include "lt_dlloader.h" + +/* Use the preprocessor to rename non-static symbols to avoid namespace + collisions when the loader code is statically linked into libltdl. + Use the "<module_name>_LTX_" prefix so that the symbol addresses can + be fetched from the preloaded symbol list by lt_dlsym(): */ +#define get_vtable dld_link_LTX_get_vtable + +LT_BEGIN_C_DECLS +LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); +LT_END_C_DECLS + + +/* Boilerplate code to set up the vtable for hooking this loader into + libltdl's loader list: */ +static int vl_exit (lt_user_data loader_data); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); +static int vm_close (lt_user_data loader_data, lt_module module); +static void * vm_sym (lt_user_data loader_data, lt_module module, + const char *symbolname); + +static lt_dlvtable *vtable = 0; + +/* Return the vtable for this loader, only the name and sym_prefix + attributes (plus the virtual function implementations, obviously) + change between loaders. */ +lt_dlvtable * +get_vtable (lt_user_data loader_data) +{ + if (!vtable) + { + vtable = lt__zalloc (sizeof *vtable); + } + + if (vtable && !vtable->name) + { + vtable->name = "lt_dld_link"; + vtable->module_open = vm_open; + vtable->module_close = vm_close; + vtable->find_sym = vm_sym; + vtable->dlloader_exit = vl_exit; + vtable->dlloader_data = loader_data; + vtable->priority = LT_DLLOADER_APPEND; + } + + if (vtable && (vtable->dlloader_data != loader_data)) + { + LT__SETERROR (INIT_LOADER); + return 0; + } + + return vtable; +} + + + +/* --- IMPLEMENTATION --- */ + + +#if defined(HAVE_DLD_H) +# include <dld.h> +#endif + +/* A function called through the vtable when this loader is no + longer needed by the application. */ +static int +vl_exit (lt_user_data LT__UNUSED loader_data) +{ + vtable = NULL; + return 0; +} + +/* A function called through the vtable to open a module with this + loader. Returns an opaque representation of the newly opened + module for processing with this loader's other vtable functions. */ +static lt_module +vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, + lt_dladvise LT__UNUSED advise) +{ + lt_module module = lt__strdup (filename); + + if (dld_link (filename) != 0) + { + LT__SETERROR (CANNOT_OPEN); + FREE (module); + } + + return module; +} + +/* A function called through the vtable when a particular module + should be unloaded. */ +static int +vm_close (lt_user_data LT__UNUSED loader_data, lt_module module) +{ + int errors = 0; + + if (dld_unlink_by_file ((char*)(module), 1) != 0) + { + LT__SETERROR (CANNOT_CLOSE); + ++errors; + } + else + { + FREE (module); + } + + return errors; +} + +/* A function called through the vtable to get the address of + a symbol loaded from a particular module. */ +static void * +vm_sym (lt_user_data LT__UNUSED loader_data, lt_module LT__UNUSED module, + const char *name) +{ + void *address = dld_get_func (name); + + if (!address) + { + LT__SETERROR (SYMBOL_NOT_FOUND); + } + + return address; +} diff --git a/libltdl/loaders/dlopen.c b/libltdl/loaders/dlopen.c new file mode 100644 index 0000000..1d052b4 --- /dev/null +++ b/libltdl/loaders/dlopen.c @@ -0,0 +1,235 @@ +/* loader-dlopen.c -- dynamic linking with dlopen/dlsym + + Copyright (C) 1998, 1999, 2000, 2004, 2006, + 2007, 2008 Free Software Foundation, Inc. + Written by Thomas Tanner, 1998 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "lt__private.h" +#include "lt_dlloader.h" + +/* Use the preprocessor to rename non-static symbols to avoid namespace + collisions when the loader code is statically linked into libltdl. + Use the "<module_name>_LTX_" prefix so that the symbol addresses can + be fetched from the preloaded symbol list by lt_dlsym(): */ +#define get_vtable dlopen_LTX_get_vtable + +LT_BEGIN_C_DECLS +LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); +LT_END_C_DECLS + + +/* Boilerplate code to set up the vtable for hooking this loader into + libltdl's loader list: */ +static int vl_exit (lt_user_data loader_data); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); +static int vm_close (lt_user_data loader_data, lt_module module); +static void * vm_sym (lt_user_data loader_data, lt_module module, + const char *symbolname); + +static lt_dlvtable *vtable = 0; + +/* Return the vtable for this loader, only the name and sym_prefix + attributes (plus the virtual function implementations, obviously) + change between loaders. */ +lt_dlvtable * +get_vtable (lt_user_data loader_data) +{ + if (!vtable) + { + vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable); + } + + if (vtable && !vtable->name) + { + vtable->name = "lt_dlopen"; +#if defined(DLSYM_USCORE) + vtable->sym_prefix = "_"; +#endif + vtable->module_open = vm_open; + vtable->module_close = vm_close; + vtable->find_sym = vm_sym; + vtable->dlloader_exit = vl_exit; + vtable->dlloader_data = loader_data; + vtable->priority = LT_DLLOADER_PREPEND; + } + + if (vtable && (vtable->dlloader_data != loader_data)) + { + LT__SETERROR (INIT_LOADER); + return 0; + } + + return vtable; +} + + + +/* --- IMPLEMENTATION --- */ + + +#if defined(HAVE_DLFCN_H) +# include <dlfcn.h> +#endif + +#if defined(HAVE_SYS_DL_H) +# include <sys/dl.h> +#endif + + +/* We may have to define LT_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#if !defined(LT_LAZY_OR_NOW) +# if defined(RTLD_LAZY) +# define LT_LAZY_OR_NOW RTLD_LAZY +# else +# if defined(DL_LAZY) +# define LT_LAZY_OR_NOW DL_LAZY +# endif +# endif /* !RTLD_LAZY */ +#endif +#if !defined(LT_LAZY_OR_NOW) +# if defined(RTLD_NOW) +# define LT_LAZY_OR_NOW RTLD_NOW +# else +# if defined(DL_NOW) +# define LT_LAZY_OR_NOW DL_NOW +# endif +# endif /* !RTLD_NOW */ +#endif +#if !defined(LT_LAZY_OR_NOW) +# define LT_LAZY_OR_NOW 0 +#endif /* !LT_LAZY_OR_NOW */ + +/* We only support local and global symbols from modules for loaders + that provide such a thing, otherwise the system default is used. */ +#if !defined(RTLD_GLOBAL) +# if defined(DL_GLOBAL) +# define RTLD_GLOBAL DL_GLOBAL +# endif +#endif /* !RTLD_GLOBAL */ +#if !defined(RTLD_LOCAL) +# if defined(DL_LOCAL) +# define RTLD_LOCAL DL_LOCAL +# endif +#endif /* !RTLD_LOCAL */ + +#if defined(HAVE_DLERROR) +# define DLERROR(arg) dlerror () +#else +# define DLERROR(arg) LT__STRERROR (arg) +#endif + +#define DL__SETERROR(errorcode) \ + LT__SETERRORSTR (DLERROR (errorcode)) + + +/* A function called through the vtable when this loader is no + longer needed by the application. */ +static int +vl_exit (lt_user_data LT__UNUSED loader_data) +{ + vtable = NULL; + return 0; +} + + +/* A function called through the vtable to open a module with this + loader. Returns an opaque representation of the newly opened + module for processing with this loader's other vtable functions. */ +static lt_module +vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, + lt_dladvise advise) +{ + int module_flags = LT_LAZY_OR_NOW; + lt_module module; + + if (advise) + { +#ifdef RTLD_GLOBAL + /* If there is some means of asking for global symbol resolution, + do so. */ + if (advise->is_symglobal) + module_flags |= RTLD_GLOBAL; +#else + /* Otherwise, reset that bit so the caller can tell it wasn't + acted on. */ + advise->is_symglobal = 0; +#endif + +/* And similarly for local only symbol resolution. */ +#ifdef RTLD_LOCAL + if (advise->is_symlocal) + module_flags |= RTLD_LOCAL; +#else + advise->is_symlocal = 0; +#endif + } + + module = dlopen (filename, module_flags); + + if (!module) + { + DL__SETERROR (CANNOT_OPEN); + } + + return module; +} + + +/* A function called through the vtable when a particular module + should be unloaded. */ +static int +vm_close (lt_user_data LT__UNUSED loader_data, lt_module module) +{ + int errors = 0; + + if (dlclose (module) != 0) + { + DL__SETERROR (CANNOT_CLOSE); + ++errors; + } + + return errors; +} + + +/* A function called through the vtable to get the address of + a symbol loaded from a particular module. */ +static void * +vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name) +{ + void *address = dlsym (module, name); + + if (!address) + { + DL__SETERROR (SYMBOL_NOT_FOUND); + } + + return address; +} diff --git a/libltdl/loaders/dyld.c b/libltdl/loaders/dyld.c new file mode 100644 index 0000000..b139d6c --- /dev/null +++ b/libltdl/loaders/dyld.c @@ -0,0 +1,511 @@ +/* loader-dyld.c -- dynamic linking on darwin and OS X + + Copyright (C) 1998, 1999, 2000, 2004, 2006, + 2007, 2008 Free Software Foundation, Inc. + Written by Peter O'Gorman, 1998 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "lt__private.h" +#include "lt_dlloader.h" + +/* Use the preprocessor to rename non-static symbols to avoid namespace + collisions when the loader code is statically linked into libltdl. + Use the "<module_name>_LTX_" prefix so that the symbol addresses can + be fetched from the preloaded symbol list by lt_dlsym(): */ +#define get_vtable dyld_LTX_get_vtable + +LT_BEGIN_C_DECLS +LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); +LT_END_C_DECLS + + +/* Boilerplate code to set up the vtable for hooking this loader into + libltdl's loader list: */ +static int vl_init (lt_user_data loader_data); +static int vl_exit (lt_user_data loader_data); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); +static int vm_close (lt_user_data loader_data, lt_module module); +static void * vm_sym (lt_user_data loader_data, lt_module module, + const char *symbolname); + +static lt_dlvtable *vtable = 0; + +/* Return the vtable for this loader, only the name and sym_prefix + attributes (plus the virtual function implementations, obviously) + change between loaders. */ +lt_dlvtable * +get_vtable (lt_user_data loader_data) +{ + if (!vtable) + { + vtable = lt__zalloc (sizeof *vtable); + } + + if (vtable && !vtable->name) + { + vtable->name = "lt_dyld"; + vtable->sym_prefix = "_"; + vtable->dlloader_init = vl_init; + vtable->module_open = vm_open; + vtable->module_close = vm_close; + vtable->find_sym = vm_sym; + vtable->dlloader_exit = vl_exit; + vtable->dlloader_data = loader_data; + vtable->priority = LT_DLLOADER_APPEND; + } + + if (vtable && (vtable->dlloader_data != loader_data)) + { + LT__SETERROR (INIT_LOADER); + return 0; + } + + return vtable; +} + + + +/* --- IMPLEMENTATION --- */ + + +#if defined(HAVE_MACH_O_DYLD_H) +# if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__) + /* Is this correct? Does it still function properly? */ +# define __private_extern__ extern +# endif +# include <mach-o/dyld.h> +#endif + +#include <mach-o/getsect.h> + +/* We have to put some stuff here that isn't in older dyld.h files */ +#if !defined(ENUM_DYLD_BOOL) +# define ENUM_DYLD_BOOL +# undef FALSE +# undef TRUE + enum DYLD_BOOL { + FALSE, + TRUE + }; +#endif +#if !defined(LC_REQ_DYLD) +# define LC_REQ_DYLD 0x80000000 +#endif +#if !defined(LC_LOAD_WEAK_DYLIB) +# define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) +#endif + +#if !defined(NSADDIMAGE_OPTION_NONE) +# define NSADDIMAGE_OPTION_NONE 0x0 +#endif +#if !defined(NSADDIMAGE_OPTION_RETURN_ON_ERROR) +# define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1 +#endif +#if !defined(NSADDIMAGE_OPTION_WITH_SEARCHING) +# define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2 +#endif +#if !defined(NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED) +# define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4 +#endif +#if !defined(NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME) +# define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8 +#endif + +#if !defined(NSLOOKUPSYMBOLINIMAGE_OPTION_BIND) +# define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0 +#endif +#if !defined(NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW) +# define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1 +#endif +#if !defined(NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY) +# define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2 +#endif +#if !defined(NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) +# define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4 +#endif + +#define LT__SYMLOOKUP_OPTS (NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW \ + | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) + +#if defined(__BIG_ENDIAN__) +# define LT__MAGIC MH_MAGIC +#else +# define LT__MAGIC MH_CIGAM +#endif + +#define DYLD__SETMYERROR(errmsg) LT__SETERRORSTR (dylderror (errmsg)) +#define DYLD__SETERROR(errcode) DYLD__SETMYERROR (LT__STRERROR (errcode)) + +typedef struct mach_header mach_header; +typedef struct dylib_command dylib_command; + +static const char *dylderror (const char *errmsg); +static const mach_header *lt__nsmodule_get_header (NSModule module); +static const char *lt__header_get_instnam (const mach_header *mh); +static const mach_header *lt__match_loadedlib (const char *name); +static NSSymbol lt__linkedlib_symbol (const char *symname, const mach_header *mh); + +static const mach_header *(*lt__addimage) (const char *image_name, + unsigned long options) = 0; +static NSSymbol (*lt__image_symbol) (const mach_header *image, + const char *symbolName, + unsigned long options) = 0; +static enum DYLD_BOOL (*lt__image_symbol_p) (const mach_header *image, + const char *symbolName) = 0; +static enum DYLD_BOOL (*lt__module_export) (NSModule module) = 0; + +static int dyld_cannot_close = 0; + + +/* A function called through the vtable when this loader is no + longer needed by the application. */ +static int +vl_exit (lt_user_data LT__UNUSED loader_data) +{ + vtable = NULL; + return 0; +} + +/* A function called through the vtable to initialise this loader. */ +static int +vl_init (lt_user_data loader_data) +{ + int errors = 0; + + if (! dyld_cannot_close) + { + if (!_dyld_present ()) + { + ++errors; + } + else + { + (void) _dyld_func_lookup ("__dyld_NSAddImage", + (unsigned long*) <__addimage); + (void) _dyld_func_lookup ("__dyld_NSLookupSymbolInImage", + (unsigned long*)<__image_symbol); + (void) _dyld_func_lookup ("__dyld_NSIsSymbolNameDefinedInImage", + (unsigned long*) <__image_symbol_p); + (void) _dyld_func_lookup ("__dyld_NSMakePrivateModulePublic", + (unsigned long*) <__module_export); + dyld_cannot_close = lt_dladderror ("can't close a dylib"); + } + } + + return errors; +} + + +/* A function called through the vtable to open a module with this + loader. Returns an opaque representation of the newly opened + module for processing with this loader's other vtable functions. */ +static lt_module +vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise LT__UNUSED advise) +{ + lt_module module = 0; + NSObjectFileImage ofi = 0; + + if (!filename) + { + return (lt_module) -1; + } + + switch (NSCreateObjectFileImageFromFile (filename, &ofi)) + { + case NSObjectFileImageSuccess: + module = NSLinkModule (ofi, filename, NSLINKMODULE_OPTION_RETURN_ON_ERROR + | NSLINKMODULE_OPTION_PRIVATE + | NSLINKMODULE_OPTION_BINDNOW); + NSDestroyObjectFileImage (ofi); + + if (module) + { + lt__module_export (module); + } + break; + + case NSObjectFileImageInappropriateFile: + if (lt__image_symbol_p && lt__image_symbol) + { + module = (lt_module) lt__addimage(filename, + NSADDIMAGE_OPTION_RETURN_ON_ERROR); + } + break; + + case NSObjectFileImageFailure: + case NSObjectFileImageArch: + case NSObjectFileImageFormat: + case NSObjectFileImageAccess: + /*NOWORK*/ + break; + } + + if (!module) + { + DYLD__SETERROR (CANNOT_OPEN); + } + + return module; +} + + +/* A function called through the vtable when a particular module + should be unloaded. */ +static int +vm_close (lt_user_data loader_data, lt_module module) +{ + int errors = 0; + + if (module != (lt_module) -1) + { + const mach_header *mh = (const mach_header *) module; + int flags = 0; + if (mh->magic == LT__MAGIC) + { + lt_dlseterror (dyld_cannot_close); + ++errors; + } + else + { + /* Currently, if a module contains c++ static destructors and it + is unloaded, we get a segfault in atexit(), due to compiler and + dynamic loader differences of opinion, this works around that. */ + if ((const struct section *) NULL != + getsectbynamefromheader (lt__nsmodule_get_header (module), + "__DATA", "__mod_term_func")) + { + flags |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED; + } +#if defined(__ppc__) + flags |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES; +#endif + if (!NSUnLinkModule (module, flags)) + { + DYLD__SETERROR (CANNOT_CLOSE); + ++errors; + } + } + } + + return errors; +} + +/* A function called through the vtable to get the address of + a symbol loaded from a particular module. */ +static void * +vm_sym (lt_user_data loader_data, lt_module module, const char *name) +{ + NSSymbol *nssym = 0; + const mach_header *mh = (const mach_header *) module; + char saveError[256] = "Symbol not found"; + + if (module == (lt_module) -1) + { + void *address, *unused; + _dyld_lookup_and_bind (name, (unsigned long*) &address, &unused); + return address; + } + + if (mh->magic == LT__MAGIC) + { + if (lt__image_symbol_p && lt__image_symbol) + { + if (lt__image_symbol_p (mh, name)) + { + nssym = lt__image_symbol (mh, name, LT__SYMLOOKUP_OPTS); + } + } + + } + else + { + nssym = NSLookupSymbolInModule (module, name); + } + + if (!nssym) + { + strncpy (saveError, dylderror (LT__STRERROR (SYMBOL_NOT_FOUND)), 255); + saveError[255] = 0; + if (!mh) + { + mh = (mach_header *)lt__nsmodule_get_header (module); + } + nssym = lt__linkedlib_symbol (name, mh); + } + + if (!nssym) + { + LT__SETERRORSTR (saveError); + } + + return nssym ? NSAddressOfSymbol (nssym) : 0; +} + + + + +/* --- HELPER FUNCTIONS --- */ + + +/* Return the dyld error string, or the passed in error string if none. */ +static const char * +dylderror (const char *errmsg) +{ + NSLinkEditErrors ler; + int lerno; + const char *file; + const char *errstr; + + NSLinkEditError (&ler, &lerno, &file, &errstr); + + if (! (errstr && *errstr)) + { + errstr = errmsg; + } + + return errstr; +} + +/* There should probably be an apple dyld api for this. */ +static const mach_header * +lt__nsmodule_get_header (NSModule module) +{ + int i = _dyld_image_count(); + const char *modname = NSNameOfModule (module); + const mach_header *mh = 0; + + if (!modname) + return NULL; + + while (i > 0) + { + --i; + if (strneq (_dyld_get_image_name (i), modname)) + { + mh = _dyld_get_image_header (i); + break; + } + } + + return mh; +} + +/* NSAddImage is also used to get the loaded image, but it only works if + the lib is installed, for uninstalled libs we need to check the + install_names against each other. Note that this is still broken if + DYLD_IMAGE_SUFFIX is set and a different lib was loaded as a result. */ +static const char * +lt__header_get_instnam (const mach_header *mh) +{ + unsigned long offset = sizeof(mach_header); + const char* result = 0; + int j; + + for (j = 0; j < mh->ncmds; j++) + { + struct load_command *lc; + + lc = (struct load_command*) (((unsigned long) mh) + offset); + if (LC_ID_DYLIB == lc->cmd) + { + result=(char*)(((dylib_command*) lc)->dylib.name.offset + + (unsigned long) lc); + } + offset += lc->cmdsize; + } + + return result; +} + +static const mach_header * +lt__match_loadedlib (const char *name) +{ + const mach_header *mh = 0; + int i = _dyld_image_count(); + + while (i > 0) + { + const char *id; + + --i; + id = lt__header_get_instnam (_dyld_get_image_header (i)); + if (id && strneq (id, name)) + { + mh = _dyld_get_image_header (i); + break; + } + } + + return mh; +} + +/* Safe to assume our mh is good. */ +static NSSymbol +lt__linkedlib_symbol (const char *symname, const mach_header *mh) +{ + NSSymbol symbol = 0; + + if (lt__image_symbol && NSIsSymbolNameDefined (symname)) + { + unsigned long offset = sizeof(mach_header); + struct load_command *lc; + int j; + + for (j = 0; j < mh->ncmds; j++) + { + lc = (struct load_command*) (((unsigned long) mh) + offset); + if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd)) + { + unsigned long base = ((dylib_command *) lc)->dylib.name.offset; + char *name = (char *) (base + (unsigned long) lc); + const mach_header *mh1 = lt__match_loadedlib (name); + + if (!mh1) + { + /* Maybe NSAddImage can find it */ + mh1 = lt__addimage (name, + NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED + | NSADDIMAGE_OPTION_WITH_SEARCHING + | NSADDIMAGE_OPTION_RETURN_ON_ERROR); + } + + if (mh1) + { + symbol = lt__image_symbol (mh1, symname, LT__SYMLOOKUP_OPTS); + if (symbol) + break; + } + } + + offset += lc->cmdsize; + } + } + + return symbol; +} diff --git a/libltdl/loaders/load_add_on.c b/libltdl/loaders/load_add_on.c new file mode 100644 index 0000000..379f9ba --- /dev/null +++ b/libltdl/loaders/load_add_on.c @@ -0,0 +1,167 @@ +/* loader-load_add_on.c -- dynamic linking for BeOS + + Copyright (C) 1998, 1999, 2000, 2004, 2006, + 2007, 2008 Free Software Foundation, Inc. + Written by Thomas Tanner, 1998 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "lt__private.h" +#include "lt_dlloader.h" + +/* Use the preprocessor to rename non-static symbols to avoid namespace + collisions when the loader code is statically linked into libltdl. + Use the "<module_name>_LTX_" prefix so that the symbol addresses can + be fetched from the preloaded symbol list by lt_dlsym(): */ +#define get_vtable load_add_on_LTX_get_vtable + +LT_BEGIN_C_DECLS +LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); +LT_END_C_DECLS + + +/* Boilerplate code to set up the vtable for hooking this loader into + libltdl's loader list: */ +static int vl_exit (lt_user_data loader_data); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); +static int vm_close (lt_user_data loader_data, lt_module module); +static void * vm_sym (lt_user_data loader_data, lt_module module, + const char *symbolname); + +static lt_dlvtable *vtable = 0; + +/* Return the vtable for this loader, only the name and sym_prefix + attributes (plus the virtual function implementations, obviously) + change between loaders. */ +lt_dlvtable * +get_vtable (lt_user_data loader_data) +{ + if (!vtable) + { + vtable = lt__zalloc (sizeof *vtable); + } + + if (vtable && !vtable->name) + { + vtable->name = "lt_load_add_on"; + vtable->module_open = vm_open; + vtable->module_close = vm_close; + vtable->find_sym = vm_sym; + vtable->dlloader_exit = vl_exit; + vtable->dlloader_data = loader_data; + vtable->priority = LT_DLLOADER_APPEND; + } + + if (vtable && (vtable->dlloader_data != loader_data)) + { + LT__SETERROR (INIT_LOADER); + return 0; + } + + return vtable; +} + + + +/* --- IMPLEMENTATION --- */ + + +#include <kernel/image.h> + +/* A function called through the vtable when this loader is no + longer needed by the application. */ +static int +vl_exit (lt_user_data LT__UNUSED loader_data) +{ + vtable = NULL; + return 0; +} + +/* A function called through the vtable to open a module with this + loader. Returns an opaque representation of the newly opened + module for processing with this loader's other vtable functions. */ +static lt_module +vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, + lt_dladvise LT__UNUSED advise) +{ + image_id image = 0; + + if (filename) + { + image = load_add_on (filename); + } + else + { + image_info info; + int32 cookie = 0; + if (get_next_image_info (0, &cookie, &info) == B_OK) + image = load_add_on (info.name); + } + + if (image <= 0) + { + LT__SETERROR (CANNOT_OPEN); + image = 0; + } + + return (lt_module) image; +} + + +/* A function called through the vtable when a particular module + should be unloaded. */ +static int +vm_close (lt_user_data LT__UNUSED loader_data, lt_module module) +{ + int errors = 0; + + if (unload_add_on ((image_id) module) != B_OK) + { + LT__SETERROR (CANNOT_CLOSE); + ++errors; + } + + return errors; +} + + +/* A function called through the vtable to get the address of + a symbol loaded from a particular module. */ +static void * +vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name) +{ + void *address = 0; + image_id image = (image_id) module; + + if (get_image_symbol (image, name, B_SYMBOL_TYPE_ANY, address) != B_OK) + { + LT__SETERROR (SYMBOL_NOT_FOUND); + address = 0; + } + + return address; +} diff --git a/libltdl/loaders/loadlibrary.c b/libltdl/loaders/loadlibrary.c new file mode 100644 index 0000000..179c009 --- /dev/null +++ b/libltdl/loaders/loadlibrary.c @@ -0,0 +1,369 @@ +/* loader-loadlibrary.c -- dynamic linking for Win32 + + Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006, + 2007, 2008, 2010 Free Software Foundation, Inc. + Written by Thomas Tanner, 1998 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "lt__private.h" +#include "lt_dlloader.h" + +#if defined(__CYGWIN__) +# include <sys/cygwin.h> +#endif + +/* Use the preprocessor to rename non-static symbols to avoid namespace + collisions when the loader code is statically linked into libltdl. + Use the "<module_name>_LTX_" prefix so that the symbol addresses can + be fetched from the preloaded symbol list by lt_dlsym(): */ +#define get_vtable loadlibrary_LTX_get_vtable + +LT_BEGIN_C_DECLS +LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); +LT_END_C_DECLS + + +/* Boilerplate code to set up the vtable for hooking this loader into + libltdl's loader list: */ +static int vl_exit (lt_user_data loader_data); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); +static int vm_close (lt_user_data loader_data, lt_module module); +static void * vm_sym (lt_user_data loader_data, lt_module module, + const char *symbolname); + +static lt_dlinterface_id iface_id = 0; +static lt_dlvtable *vtable = 0; + +/* Return the vtable for this loader, only the name and sym_prefix + attributes (plus the virtual function implementations, obviously) + change between loaders. */ +lt_dlvtable * +get_vtable (lt_user_data loader_data) +{ + if (!vtable) + { + vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable); + iface_id = lt_dlinterface_register ("ltdl loadlibrary", NULL); + } + + if (vtable && !vtable->name) + { + vtable->name = "lt_loadlibrary"; + vtable->module_open = vm_open; + vtable->module_close = vm_close; + vtable->find_sym = vm_sym; + vtable->dlloader_exit = vl_exit; + vtable->dlloader_data = loader_data; + vtable->priority = LT_DLLOADER_APPEND; + } + + if (vtable && (vtable->dlloader_data != loader_data)) + { + LT__SETERROR (INIT_LOADER); + return 0; + } + + return vtable; +} + + + +/* --- IMPLEMENTATION --- */ + + +#include <windows.h> + +#define LOCALFREE(mem) LT_STMT_START { \ + if (mem) { LocalFree ((void *)mem); mem = NULL; } } LT_STMT_END +#define LOADLIB__SETERROR(errmsg) LT__SETERRORSTR (loadlibraryerror (errmsg)) +#define LOADLIB_SETERROR(errcode) LOADLIB__SETERROR (LT__STRERROR (errcode)) + +static const char *loadlibraryerror (const char *default_errmsg); +static DWORD WINAPI wrap_getthreaderrormode (void); +static DWORD WINAPI fallback_getthreaderrormode (void); +static BOOL WINAPI wrap_setthreaderrormode (DWORD mode, DWORD *oldmode); +static BOOL WINAPI fallback_setthreaderrormode (DWORD mode, DWORD *oldmode); + +typedef DWORD (WINAPI getthreaderrormode_type) (void); +typedef BOOL (WINAPI setthreaderrormode_type) (DWORD, DWORD *); + +static getthreaderrormode_type *getthreaderrormode = wrap_getthreaderrormode; +static setthreaderrormode_type *setthreaderrormode = wrap_setthreaderrormode; +static char *error_message = 0; + + +/* A function called through the vtable when this loader is no + longer needed by the application. */ +static int +vl_exit (lt_user_data LT__UNUSED loader_data) +{ + vtable = NULL; + LOCALFREE (error_message); + return 0; +} + +/* A function called through the vtable to open a module with this + loader. Returns an opaque representation of the newly opened + module for processing with this loader's other vtable functions. */ +static lt_module +vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, + lt_dladvise LT__UNUSED advise) +{ + lt_module module = 0; + char *ext; + char wpath[MAX_PATH]; + size_t len; + + if (!filename) + { + /* Get the name of main module */ + *wpath = 0; + GetModuleFileName (NULL, wpath, sizeof (wpath)); + filename = wpath; + } + else + { + len = LT_STRLEN (filename); + + if (len >= MAX_PATH) + { + LT__SETERROR (CANNOT_OPEN); + return 0; + } + +#if HAVE_DECL_CYGWIN_CONV_PATH + if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, filename, wpath, MAX_PATH)) + { + LT__SETERROR (CANNOT_OPEN); + return 0; + } + len = 0; +#elif defined(__CYGWIN__) + cygwin_conv_to_full_win32_path (filename, wpath); + len = 0; +#else + strcpy(wpath, filename); +#endif + + ext = strrchr (wpath, '.'); + if (!ext) + { + /* Append a `.' to stop Windows from adding an + implicit `.dll' extension. */ + if (!len) + len = strlen (wpath); + + if (len + 1 >= MAX_PATH) + { + LT__SETERROR (CANNOT_OPEN); + return 0; + } + + wpath[len] = '.'; + wpath[len+1] = '\0'; + } + } + + { + /* Silence dialog from LoadLibrary on some failures. */ + DWORD errormode = getthreaderrormode (); + DWORD last_error; + + setthreaderrormode (errormode | SEM_FAILCRITICALERRORS, NULL); + + module = LoadLibrary (wpath); + + /* Restore the error mode. */ + last_error = GetLastError (); + setthreaderrormode (errormode, NULL); + SetLastError (last_error); + } + + /* libltdl expects this function to fail if it is unable + to physically load the library. Sadly, LoadLibrary + will search the loaded libraries for a match and return + one of them if the path search load fails. + + We check whether LoadLibrary is returning a handle to + an already loaded module, and simulate failure if we + find one. */ + { + lt_dlhandle cur = 0; + + while ((cur = lt_dlhandle_iterate (iface_id, cur))) + { + if (!cur->module) + { + cur = 0; + break; + } + + if (cur->module == module) + { + break; + } + } + + if (!module) + LOADLIB_SETERROR (CANNOT_OPEN); + else if (cur) + { + LT__SETERROR (CANNOT_OPEN); + module = 0; + } + } + + return module; +} + + +/* A function called through the vtable when a particular module + should be unloaded. */ +static int +vm_close (lt_user_data LT__UNUSED loader_data, lt_module module) +{ + int errors = 0; + + if (FreeLibrary ((HMODULE) module) == 0) + { + LOADLIB_SETERROR (CANNOT_CLOSE); + ++errors; + } + + return errors; +} + + +/* A function called through the vtable to get the address of + a symbol loaded from a particular module. */ +static void * +vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name) +{ + void *address = (void *) GetProcAddress ((HMODULE) module, name); + + if (!address) + { + LOADLIB_SETERROR (SYMBOL_NOT_FOUND); + } + + return address; +} + + + +/* --- HELPER FUNCTIONS --- */ + + +/* Return the windows error message, or the passed in error message on + failure. */ +static const char * +loadlibraryerror (const char *default_errmsg) +{ + size_t len; + LOCALFREE (error_message); + + FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError (), + 0, + (char *) &error_message, + 0, NULL); + + /* Remove trailing CRNL */ + len = LT_STRLEN (error_message); + if (len && error_message[len - 1] == '\n') + error_message[--len] = LT_EOS_CHAR; + if (len && error_message[len - 1] == '\r') + error_message[--len] = LT_EOS_CHAR; + + return len ? error_message : default_errmsg; +} + +/* A function called through the getthreaderrormode variable which checks + if the system supports GetThreadErrorMode (or GetErrorMode) and arranges + for it or a fallback implementation to be called directly in the future. + The selected version is then called. */ +static DWORD WINAPI +wrap_getthreaderrormode (void) +{ + HMODULE kernel32 = GetModuleHandleA ("kernel32.dll"); + getthreaderrormode + = (getthreaderrormode_type *) GetProcAddress (kernel32, + "GetThreadErrorMode"); + if (!getthreaderrormode) + getthreaderrormode + = (getthreaderrormode_type *) GetProcAddress (kernel32, + "GetErrorMode"); + if (!getthreaderrormode) + getthreaderrormode = fallback_getthreaderrormode; + return getthreaderrormode (); +} + +/* A function called through the getthreaderrormode variable for cases + where the system does not support GetThreadErrorMode or GetErrorMode */ +static DWORD WINAPI +fallback_getthreaderrormode (void) +{ + /* Prior to Windows Vista, the only way to get the current error + mode was to set a new one. In our case, we are setting a new + error mode right after "getting" it while ignoring the error + mode in effect when setting the new error mode, so that's + fairly ok. */ + return (DWORD) SetErrorMode (SEM_FAILCRITICALERRORS); +} + +/* A function called through the setthreaderrormode variable which checks + if the system supports SetThreadErrorMode and arranges for it or a + fallback implementation to be called directly in the future. + The selected version is then called. */ +static BOOL WINAPI +wrap_setthreaderrormode (DWORD mode, DWORD *oldmode) +{ + HMODULE kernel32 = GetModuleHandleA ("kernel32.dll"); + setthreaderrormode + = (setthreaderrormode_type *) GetProcAddress (kernel32, + "SetThreadErrorMode"); + if (!setthreaderrormode) + setthreaderrormode = fallback_setthreaderrormode; + return setthreaderrormode (mode, oldmode); +} + +/* A function called through the setthreaderrormode variable for cases + where the system does not support SetThreadErrorMode. */ +static BOOL WINAPI +fallback_setthreaderrormode (DWORD mode, DWORD *oldmode) +{ + /* Prior to Windows 7, there was no way to set the thread local error + mode, so set the process global error mode instead. */ + DWORD old = (DWORD) SetErrorMode (mode); + if (oldmode) + *oldmode = old; + return TRUE; +} diff --git a/libltdl/loaders/preopen.c b/libltdl/loaders/preopen.c new file mode 100644 index 0000000..7149287 --- /dev/null +++ b/libltdl/loaders/preopen.c @@ -0,0 +1,375 @@ +/* loader-preopen.c -- emulate dynamic linking using preloaded_symbols + + Copyright (C) 1998, 1999, 2000, 2004, 2006, + 2007, 2008 Free Software Foundation, Inc. + Written by Thomas Tanner, 1998 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "lt__private.h" +#include "lt_dlloader.h" + +/* Use the preprocessor to rename non-static symbols to avoid namespace + collisions when the loader code is statically linked into libltdl. + Use the "<module_name>_LTX_" prefix so that the symbol addresses can + be fetched from the preloaded symbol list by lt_dlsym(): */ +#define get_vtable preopen_LTX_get_vtable + +LT_BEGIN_C_DECLS +LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); +LT_END_C_DECLS + + +/* Boilerplate code to set up the vtable for hooking this loader into + libltdl's loader list: */ +static int vl_init (lt_user_data loader_data); +static int vl_exit (lt_user_data loader_data); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); +static int vm_close (lt_user_data loader_data, lt_module module); +static void * vm_sym (lt_user_data loader_data, lt_module module, + const char *symbolname); + +static lt_dlvtable *vtable = 0; + +/* Return the vtable for this loader, only the name and sym_prefix + attributes (plus the virtual function implementations, obviously) + change between loaders. */ +lt_dlvtable * +get_vtable (lt_user_data loader_data) +{ + if (!vtable) + { + vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable); + } + + if (vtable && !vtable->name) + { + vtable->name = "lt_preopen"; + vtable->sym_prefix = 0; + vtable->module_open = vm_open; + vtable->module_close = vm_close; + vtable->find_sym = vm_sym; + vtable->dlloader_init = vl_init; + vtable->dlloader_exit = vl_exit; + vtable->dlloader_data = loader_data; + vtable->priority = LT_DLLOADER_PREPEND; + } + + if (vtable && (vtable->dlloader_data != loader_data)) + { + LT__SETERROR (INIT_LOADER); + return 0; + } + + return vtable; +} + + + +/* --- IMPLEMENTATION --- */ + + +/* Wrapper type to chain together symbol lists of various origins. */ +typedef struct symlist_chain +{ + struct symlist_chain *next; + const lt_dlsymlist *symlist; +} symlist_chain; + + +static int add_symlist (const lt_dlsymlist *symlist); +static int free_symlists (void); + +/* The start of the symbol lists chain. */ +static symlist_chain *preloaded_symlists = 0; + +/* A symbol list preloaded before lt_init() was called. */ +static const lt_dlsymlist *default_preloaded_symbols = 0; + + +/* A function called through the vtable to initialise this loader. */ +static int +vl_init (lt_user_data LT__UNUSED loader_data) +{ + int errors = 0; + + preloaded_symlists = 0; + if (default_preloaded_symbols) + { + errors = lt_dlpreload (default_preloaded_symbols); + } + + return errors; +} + + +/* A function called through the vtable when this loader is no + longer needed by the application. */ +static int +vl_exit (lt_user_data LT__UNUSED loader_data) +{ + vtable = NULL; + free_symlists (); + return 0; +} + + +/* A function called through the vtable to open a module with this + loader. Returns an opaque representation of the newly opened + module for processing with this loader's other vtable functions. */ +static lt_module +vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, + lt_dladvise LT__UNUSED advise) +{ + symlist_chain *lists; + lt_module module = 0; + + if (!preloaded_symlists) + { + LT__SETERROR (NO_SYMBOLS); + goto done; + } + + /* Can't use NULL as the reflective symbol header, as NULL is + used to mark the end of the entire symbol list. Self-dlpreopened + symbols follow this magic number, chosen to be an unlikely + clash with a real module name. */ + if (!filename) + { + filename = "@PROGRAM@"; + } + + for (lists = preloaded_symlists; lists; lists = lists->next) + { + const lt_dlsymlist *symbol; + for (symbol= lists->symlist; symbol->name; ++symbol) + { + if (!symbol->address && streq (symbol->name, filename)) + { + /* If the next symbol's name and address is 0, it means + the module just contains the originator and no symbols. + In this case we pretend that we never saw the module and + hope that some other loader will be able to load the module + and have access to its symbols */ + const lt_dlsymlist *next_symbol = symbol +1; + if (next_symbol->address && next_symbol->name) + { + module = (lt_module) lists->symlist; + goto done; + } + } + } + } + + LT__SETERROR (FILE_NOT_FOUND); + + done: + return module; +} + + +/* A function called through the vtable when a particular module + should be unloaded. */ +static int +vm_close (lt_user_data LT__UNUSED loader_data, lt_module LT__UNUSED module) +{ + /* Just to silence gcc -Wall */ + module = 0; + return 0; +} + + +/* A function called through the vtable to get the address of + a symbol loaded from a particular module. */ +static void * +vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name) +{ + lt_dlsymlist *symbol = (lt_dlsymlist*) module; + + symbol +=2; /* Skip header (originator then libname). */ + + while (symbol->name) + { + if (streq (symbol->name, name)) + { + return symbol->address; + } + + ++symbol; + } + + LT__SETERROR (SYMBOL_NOT_FOUND); + + return 0; +} + + + +/* --- HELPER FUNCTIONS --- */ + + +/* The symbol lists themselves are not allocated from the heap, but + we can unhook them and free up the chain of links between them. */ +static int +free_symlists (void) +{ + symlist_chain *lists; + + lists = preloaded_symlists; + while (lists) + { + symlist_chain *next = lists->next; + FREE (lists); + lists = next; + } + preloaded_symlists = 0; + + return 0; +} + +/* Add a new symbol list to the global chain. */ +static int +add_symlist (const lt_dlsymlist *symlist) +{ + symlist_chain *lists; + int errors = 0; + + /* Search for duplicate entries: */ + for (lists = preloaded_symlists; + lists && lists->symlist != symlist; lists = lists->next) + /*NOWORK*/; + + /* Don't add the same list twice: */ + if (!lists) + { + symlist_chain *tmp = (symlist_chain *) lt__zalloc (sizeof *tmp); + + if (tmp) + { + tmp->symlist = symlist; + tmp->next = preloaded_symlists; + preloaded_symlists = tmp; + } + else + { + ++errors; + } + } + + return errors; +} + + + +/* --- PRELOADING API CALL IMPLEMENTATIONS --- */ + + +/* Save a default symbol list for later. */ +int +lt_dlpreload_default (const lt_dlsymlist *preloaded) +{ + default_preloaded_symbols = preloaded; + return 0; +} + + +/* Add a symbol list to the global chain, or with a NULL argument, + revert to just the default list. */ +int +lt_dlpreload (const lt_dlsymlist *preloaded) +{ + int errors = 0; + + if (preloaded) + { + errors = add_symlist (preloaded); + } + else + { + free_symlists(); + + if (default_preloaded_symbols) + { + errors = lt_dlpreload (default_preloaded_symbols); + } + } + + return errors; +} + + +/* Open all the preloaded modules from the named originator, executing + a callback for each one. If ORIGINATOR is NULL, then call FUNC for + each preloaded module from the program itself. */ +int +lt_dlpreload_open (const char *originator, lt_dlpreload_callback_func *func) +{ + symlist_chain *list; + int errors = 0; + int found = 0; + + /* For each symlist in the chain... */ + for (list = preloaded_symlists; list; list = list->next) + { + /* ...that was preloaded by the requesting ORIGINATOR... */ + if ((originator && streq (list->symlist->name, originator)) + || (!originator && streq (list->symlist->name, "@PROGRAM@"))) + { + const lt_dlsymlist *symbol; + unsigned int idx = 0; + + ++found; + + /* ...load the symbols per source compilation unit: + (we preincrement the index to skip over the originator entry) */ + while ((symbol = &list->symlist[++idx])->name != 0) + { + if ((symbol->address == 0) + && (strneq (symbol->name, "@PROGRAM@"))) + { + lt_dlhandle handle = lt_dlopen (symbol->name); + if (handle == 0) + { + ++errors; + } + else + { + errors += (*func) (handle); + } + } + } + } + } + + if (!found) + { + LT__SETERROR(CANNOT_OPEN); + ++errors; + } + + return errors; +} diff --git a/libltdl/loaders/shl_load.c b/libltdl/loaders/shl_load.c new file mode 100644 index 0000000..5a09d87 --- /dev/null +++ b/libltdl/loaders/shl_load.c @@ -0,0 +1,222 @@ +/* loader-shl_load.c -- dynamic linking with shl_load (HP-UX) + + Copyright (C) 1998, 1999, 2000, 2004, 2006, + 2007, 2008 Free Software Foundation, Inc. + Written by Thomas Tanner, 1998 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "lt__private.h" +#include "lt_dlloader.h" + +/* Use the preprocessor to rename non-static symbols to avoid namespace + collisions when the loader code is statically linked into libltdl. + Use the "<module_name>_LTX_" prefix so that the symbol addresses can + be fetched from the preloaded symbol list by lt_dlsym(): */ +#define get_vtable shl_load_LTX_get_vtable + +LT_BEGIN_C_DECLS +LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data); +LT_END_C_DECLS + + +/* Boilerplate code to set up the vtable for hooking this loader into + libltdl's loader list: */ +static int vl_exit (lt_user_data loader_data); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); +static int vm_close (lt_user_data loader_data, lt_module module); +static void * vm_sym (lt_user_data loader_data, lt_module module, + const char *symbolname); + +static lt_dlvtable *vtable = 0; + +/* Return the vtable for this loader, only the name and sym_prefix + attributes (plus the virtual function implementations, obviously) + change between loaders. */ +lt_dlvtable * +get_vtable (lt_user_data loader_data) +{ + if (!vtable) + { + vtable = lt__zalloc (sizeof *vtable); + } + + if (vtable && !vtable->name) + { + vtable->name = "lt_shl_load"; + vtable->module_open = vm_open; + vtable->module_close = vm_close; + vtable->find_sym = vm_sym; + vtable->dlloader_exit = vl_exit; + vtable->dlloader_data = loader_data; + vtable->priority = LT_DLLOADER_APPEND; + } + + if (vtable && (vtable->dlloader_data != loader_data)) + { + LT__SETERROR (INIT_LOADER); + return 0; + } + + return vtable; +} + + + +/* --- IMPLEMENTATION --- */ + + +#if defined(HAVE_DL_H) +# include <dl.h> +#endif + +/* some flags are missing on some systems, so we provide + * harmless defaults. + * + * Mandatory: + * BIND_IMMEDIATE - Resolve symbol references when the library is loaded. + * BIND_DEFERRED - Delay code symbol resolution until actual reference. + * + * Optionally: + * BIND_FIRST - Place the library at the head of the symbol search + * order. + * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all + * unsatisfied symbols as fatal. This flag allows + * binding of unsatisfied code symbols to be deferred + * until use. + * [Perl: For certain libraries, like DCE, deferred + * binding often causes run time problems. Adding + * BIND_NONFATAL to BIND_IMMEDIATE still allows + * unresolved references in situations like this.] + * BIND_NOSTART - Do not call the initializer for the shared library + * when the library is loaded, nor on a future call to + * shl_unload(). + * BIND_VERBOSE - Print verbose messages concerning possible + * unsatisfied symbols. + * + * hp9000s700/hp9000s800: + * BIND_RESTRICTED - Restrict symbols visible by the library to those + * present at library load time. + * DYNAMIC_PATH - Allow the loader to dynamically search for the + * library specified by the path argument. + */ + +#if !defined(DYNAMIC_PATH) +# define DYNAMIC_PATH 0 +#endif +#if !defined(BIND_RESTRICTED) +# define BIND_RESTRICTED 0 +#endif + +#define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH) + + +/* A function called through the vtable when this loader is no + longer needed by the application. */ +static int +vl_exit (lt_user_data LT__UNUSED loader_data) +{ + vtable = NULL; + return 0; +} + +/* A function called through the vtable to open a module with this + loader. Returns an opaque representation of the newly opened + module for processing with this loader's other vtable functions. */ +static lt_module +vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, + lt_dladvise LT__UNUSED advise) +{ + static shl_t self = (shl_t) 0; + lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L); + + /* Since searching for a symbol against a NULL module handle will also + look in everything else that was already loaded and exported with + the -E compiler flag, we always cache a handle saved before any + modules are loaded. */ + if (!self) + { + void *address; + shl_findsym (&self, "main", TYPE_UNDEFINED, &address); + } + + if (!filename) + { + module = self; + } + else + { + module = shl_load (filename, LT_BIND_FLAGS, 0L); + + if (!module) + { + LT__SETERROR (CANNOT_OPEN); + } + } + + return module; +} + +/* A function called through the vtable when a particular module + should be unloaded. */ +static int +vm_close (lt_user_data LT__UNUSED loader_data, lt_module module) +{ + int errors = 0; + + if (module && (shl_unload ((shl_t) (module)) != 0)) + { + LT__SETERROR (CANNOT_CLOSE); + ++errors; + } + + return errors; +} + + +/* A function called through the vtable to get the address of + a symbol loaded from a particular module. */ +static void * +vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name) +{ + void *address = 0; + + /* sys_shl_open should never return a NULL module handle */ + if (module == (lt_module) 0) + { + LT__SETERROR (INVALID_HANDLE); + } + else if (!shl_findsym((shl_t*) &module, name, TYPE_UNDEFINED, &address)) + { + if (!address) + { + LT__SETERROR (SYMBOL_NOT_FOUND); + } + } + + return address; +} diff --git a/libltdl/lt__alloc.c b/libltdl/lt__alloc.c new file mode 100644 index 0000000..d39e17e --- /dev/null +++ b/libltdl/lt__alloc.c @@ -0,0 +1,95 @@ +/* lt__alloc.c -- internal memory management interface + + Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc. + Written by Gary V. Vaughan, 2004 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "lt__private.h" + +#include <stdio.h> + +#include "lt__alloc.h" + +static void alloc_die_default (void); + +void (*lt__alloc_die) (void) = alloc_die_default; + +/* Unless overridden, exit on memory failure. */ +static void +alloc_die_default (void) +{ + fprintf (stderr, "Out of memory.\n"); + exit (EXIT_FAILURE); +} + +void * +lt__malloc (size_t n) +{ + void *mem; + + if (! (mem = malloc (n))) + (*lt__alloc_die) (); + + return mem; +} + +void * +lt__zalloc (size_t n) +{ + void *mem; + + if ((mem = lt__malloc (n))) + memset (mem, 0, n); + + return mem; +} + +void * +lt__realloc (void *mem, size_t n) +{ + if (! (mem = realloc (mem, n))) + (*lt__alloc_die) (); + + return mem; +} + +void * +lt__memdup (void const *mem, size_t n) +{ + void *newmem; + + if ((newmem = lt__malloc (n))) + return memcpy (newmem, mem, n); + + return 0; +} + +char * +lt__strdup (const char *string) +{ + return (char *) lt__memdup (string, strlen (string) +1); +} diff --git a/libltdl/lt__dirent.c b/libltdl/lt__dirent.c new file mode 100644 index 0000000..30dc072 --- /dev/null +++ b/libltdl/lt__dirent.c @@ -0,0 +1,107 @@ +/* lt__dirent.c -- internal directory entry scanning interface + + Copyright (C) 2001, 2004 Free Software Foundation, Inc. + Written by Bob Friesenhahn, 2001 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "lt__private.h" + +#include <assert.h> +#include <stddef.h> + +#include "lt__dirent.h" + +#if defined(__WINDOWS__) + +void +closedir (DIR *entry) +{ + assert (entry != (DIR *) NULL); + FindClose (entry->hSearch); + free ((void *) entry); +} + + +DIR * +opendir (const char *path) +{ + char file_spec[LT_FILENAME_MAX]; + DIR *entry; + + assert (path != (char *) 0); + if (lt_strlcpy (file_spec, path, sizeof file_spec) >= sizeof file_spec + || lt_strlcat (file_spec, "\\", sizeof file_spec) >= sizeof file_spec) + return (DIR *) 0; + entry = (DIR *) malloc (sizeof(DIR)); + if (entry != (DIR *) 0) + { + entry->firsttime = TRUE; + entry->hSearch = FindFirstFile (file_spec, &entry->Win32FindData); + + if (entry->hSearch == INVALID_HANDLE_VALUE) + { + if (lt_strlcat (file_spec, "\\*.*", sizeof file_spec) < sizeof file_spec) + { + entry->hSearch = FindFirstFile (file_spec, &entry->Win32FindData); + } + + if (entry->hSearch == INVALID_HANDLE_VALUE) + { + entry = (free (entry), (DIR *) 0); + } + } + } + + return entry; +} + + +struct dirent * +readdir (DIR *entry) +{ + int status; + + if (entry == (DIR *) 0) + return (struct dirent *) 0; + + if (!entry->firsttime) + { + status = FindNextFile (entry->hSearch, &entry->Win32FindData); + if (status == 0) + return (struct dirent *) 0; + } + + entry->firsttime = FALSE; + if (lt_strlcpy (entry->file_info.d_name, entry->Win32FindData.cFileName, + sizeof entry->file_info.d_name) >= sizeof entry->file_info.d_name) + return (struct dirent *) 0; + entry->file_info.d_namlen = strlen (entry->file_info.d_name); + + return &entry->file_info; +} + +#endif /*defined(__WINDOWS__)*/ diff --git a/libltdl/lt__strl.c b/libltdl/lt__strl.c new file mode 100644 index 0000000..c2cee58 --- /dev/null +++ b/libltdl/lt__strl.c @@ -0,0 +1,127 @@ +/* lt__strl.c -- size-bounded string copying and concatenation + + Copyright (C) 2004 Free Software Foundation, Inc. + Written by Bob Friesenhahn, 2004 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <assert.h> +#include <string.h> + +#include "lt__strl.h" + +/* + lt_strlcat appends the NULL-terminated string src to the end of dst. + It will append at most dstsize - strlen(dst) - 1 bytes, + NULL-terminating the result. The total length of the string which + would have been created given sufficient buffer size (may be longer + than dstsize) is returned. This function substitutes for strlcat() + which is available under NetBSD, FreeBSD and Solaris 9. + + Buffer overflow can be checked as follows: + + if (lt_strlcat(dst, src, dstsize) >= dstsize) + return -1; +*/ +#if !defined(HAVE_STRLCAT) +size_t +lt_strlcat(char *dst, const char *src, const size_t dstsize) +{ + size_t length; + char *p; + const char *q; + + assert(dst != NULL); + assert(src != (const char *) NULL); + assert(dstsize >= 1); + + length=strlen(dst); + + /* + Copy remaining characters from src while constraining length to + size - 1. + */ + for ( p = dst + length, q = src; + (*q != 0) && (length < dstsize - 1) ; + length++, p++, q++ ) + *p = *q; + + dst[length]='\0'; + + /* + Add remaining length of src to length. + */ + while (*q++) + length++; + + return length; +} +#endif /* !defined(HAVE_STRLCAT) */ + +/* + lt_strlcpy copies up to dstsize - 1 characters from the NULL-terminated + string src to dst, NULL-terminating the result. The total length of + the string which would have been created given sufficient buffer + size (may be longer than dstsize) is returned. This function + substitutes for strlcpy() which is available under OpenBSD, FreeBSD + and Solaris 9. + + Buffer overflow can be checked as follows: + + if (lt_strlcpy(dst, src, dstsize) >= dstsize) + return -1; +*/ +#if !defined(HAVE_STRLCPY) +size_t +lt_strlcpy(char *dst, const char *src, const size_t dstsize) +{ + size_t length=0; + char *p; + const char *q; + + assert(dst != NULL); + assert(src != (const char *) NULL); + assert(dstsize >= 1); + + /* + Copy src to dst within bounds of size-1. + */ + for ( p=dst, q=src, length=0 ; + (*q != 0) && (length < dstsize-1) ; + length++, p++, q++ ) + *p = *q; + + dst[length]='\0'; + + /* + Add remaining length of src to length. + */ + while (*q++) + length++; + + return length; +} +#endif /* !defined(HAVE_STRLCPY) */ diff --git a/libltdl/lt_dlloader.c b/libltdl/lt_dlloader.c new file mode 100644 index 0000000..2c99a22 --- /dev/null +++ b/libltdl/lt_dlloader.c @@ -0,0 +1,210 @@ +/* lt_dlloader.c -- dynamic library loader interface + + Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. + Written by Gary V. Vaughan, 2004 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "lt__private.h" +#include "lt_dlloader.h" + +#define RETURN_SUCCESS 0 +#define RETURN_FAILURE 1 + +static void * loader_callback (SList *item, void *userdata); + +/* A list of all the dlloaders we know about, each stored as a boxed + SList item: */ +static SList *loaders = 0; + + +/* Return NULL, unless the loader in this ITEM has a matching name, + in which case we return the matching item so that its address is + passed back out (for possible freeing) by slist_remove. */ +static void * +loader_callback (SList *item, void *userdata) +{ + const lt_dlvtable *vtable = (const lt_dlvtable *) item->userdata; + const char * name = (const char *) userdata; + + assert (vtable); + + return streq (vtable->name, name) ? (void *) item : NULL; +} + + +/* Hook VTABLE into our global LOADERS list according to its own + PRIORITY field value. */ +int +lt_dlloader_add (const lt_dlvtable *vtable) +{ + SList *item; + + if ((vtable == 0) /* diagnose invalid vtable fields */ + || (vtable->module_open == 0) + || (vtable->module_close == 0) + || (vtable->find_sym == 0) + || ((vtable->priority != LT_DLLOADER_PREPEND) && + (vtable->priority != LT_DLLOADER_APPEND))) + { + LT__SETERROR (INVALID_LOADER); + return RETURN_FAILURE; + } + + item = slist_box (vtable); + if (!item) + { + (*lt__alloc_die) (); + + /* Let the caller know something went wrong if lt__alloc_die + doesn't abort. */ + return RETURN_FAILURE; + } + + if (vtable->priority == LT_DLLOADER_PREPEND) + { + loaders = slist_cons (item, loaders); + } + else + { + assert (vtable->priority == LT_DLLOADER_APPEND); + loaders = slist_concat (loaders, item); + } + + return RETURN_SUCCESS; +} + +#ifdef LT_DEBUG_LOADERS +static void * +loader_dump_callback (SList *item, void *userdata) +{ + const lt_dlvtable *vtable = (const lt_dlvtable *) item->userdata; + fprintf (stderr, ", %s", (vtable && vtable->name) ? vtable->name : "(null)"); + return 0; +} + +void +lt_dlloader_dump (void) +{ + fprintf (stderr, "loaders: "); + if (!loaders) + { + fprintf (stderr, "(empty)"); + } + else + { + const lt_dlvtable *head = (const lt_dlvtable *) loaders->userdata; + fprintf (stderr, "%s", (head && head->name) ? head->name : "(null)"); + if (slist_tail (loaders)) + slist_foreach (slist_tail (loaders), loader_dump_callback, NULL); + } + fprintf (stderr, "\n"); +} +#endif + +/* An iterator for the global loader list: if LOADER is NULL, then + return the first element, otherwise the following element. */ +lt_dlloader +lt_dlloader_next (lt_dlloader loader) +{ + SList *item = (SList *) loader; + return (lt_dlloader) (item ? item->next : loaders); +} + + +/* Non-destructive unboxing of a loader. */ +const lt_dlvtable * +lt_dlloader_get (lt_dlloader loader) +{ + return (const lt_dlvtable *) (loader ? ((SList *) loader)->userdata : NULL); +} + + +/* Return the contents of the first item in the global loader list + with a matching NAME after removing it from that list. If there + was no match, return NULL; if there is an error, return NULL and + set an error for lt_dlerror; do not set an error if only resident + modules need this loader; in either case, the loader list is not + changed if NULL is returned. */ +lt_dlvtable * +lt_dlloader_remove (const char *name) +{ + const lt_dlvtable * vtable = lt_dlloader_find (name); + static const char id_string[] = "lt_dlloader_remove"; + lt_dlinterface_id iface; + lt_dlhandle handle = 0; + int in_use = 0; + int in_use_by_resident = 0; + + if (!vtable) + { + LT__SETERROR (INVALID_LOADER); + return 0; + } + + /* Fail if there are any open modules which use this loader. */ + iface = lt_dlinterface_register (id_string, NULL); + while ((handle = lt_dlhandle_iterate (iface, handle))) + { + lt_dlhandle cur = handle; + if (cur->vtable == vtable) + { + in_use = 1; + if (lt_dlisresident (handle)) + in_use_by_resident = 1; + } + } + lt_dlinterface_free (iface); + if (in_use) + { + if (!in_use_by_resident) + LT__SETERROR (REMOVE_LOADER); + return 0; + } + + /* Call the loader finalisation function. */ + if (vtable && vtable->dlloader_exit) + { + if ((*vtable->dlloader_exit) (vtable->dlloader_data) != 0) + { + /* If there is an exit function, and it returns non-zero + then it must set an error, and we will not remove it + from the list. */ + return 0; + } + } + + /* If we got this far, remove the loader from our global list. */ + return (lt_dlvtable *) + slist_unbox ((SList *) slist_remove (&loaders, loader_callback, (void *) name)); +} + + +const lt_dlvtable * +lt_dlloader_find (const char *name) +{ + return lt_dlloader_get (slist_find (loaders, loader_callback, (void *) name)); +} diff --git a/libltdl/lt_error.c b/libltdl/lt_error.c new file mode 100644 index 0000000..d7af36d --- /dev/null +++ b/libltdl/lt_error.c @@ -0,0 +1,110 @@ +/* lt_error.c -- error propogation interface + + Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007 Free Software Foundation, Inc. + Written by Thomas Tanner, 1999 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "lt__private.h" +#include "lt_error.h" + +static const char *last_error = 0; +static const char error_strings[LT_ERROR_MAX][LT_ERROR_LEN_MAX + 1] = + { +#define LT_ERROR(name, diagnostic) diagnostic, + lt_dlerror_table +#undef LT_ERROR + }; + +static const char **user_error_strings = 0; +static int errorcount = LT_ERROR_MAX; + +int +lt_dladderror (const char *diagnostic) +{ + int errindex = 0; + int result = -1; + const char **temp = (const char **) 0; + + assert (diagnostic); + + errindex = errorcount - LT_ERROR_MAX; + temp = REALLOC (const char *, user_error_strings, 1 + errindex); + if (temp) + { + user_error_strings = temp; + user_error_strings[errindex] = diagnostic; + result = errorcount++; + } + + return result; +} + +int +lt_dlseterror (int errindex) +{ + int errors = 0; + + if (errindex >= errorcount || errindex < 0) + { + /* Ack! Error setting the error message! */ + LT__SETERROR (INVALID_ERRORCODE); + ++errors; + } + else if (errindex < LT_ERROR_MAX) + { + /* No error setting the error message! */ + LT__SETERRORSTR (error_strings[errindex]); + } + else + { + /* No error setting the error message! */ + LT__SETERRORSTR (user_error_strings[errindex - LT_ERROR_MAX]); + } + + return errors; +} + +const char * +lt__error_string (int errorcode) +{ + assert (errorcode >= 0); + assert (errorcode < LT_ERROR_MAX); + + return error_strings[errorcode]; +} + +const char * +lt__get_last_error (void) +{ + return last_error; +} + +const char * +lt__set_last_error (const char *errormsg) +{ + return last_error = errormsg; +} diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c new file mode 100644 index 0000000..01853e0 --- /dev/null +++ b/libltdl/ltdl.c @@ -0,0 +1,2464 @@ +/* ltdl.c -- system independent dlopen wrapper + + Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006, + 2007, 2008, 2011 Free Software Foundation, Inc. + Written by Thomas Tanner, 1998 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "lt__private.h" +#include "lt_system.h" +#include "lt_dlloader.h" + + +/* --- MANIFEST CONSTANTS --- */ + + +/* Standard libltdl search path environment variable name */ +#undef LTDL_SEARCHPATH_VAR +#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH" + +/* Standard libtool archive file extension. */ +#undef LT_ARCHIVE_EXT +#define LT_ARCHIVE_EXT ".la" + +/* max. filename length */ +#if !defined(LT_FILENAME_MAX) +# define LT_FILENAME_MAX 1024 +#endif + +#if !defined(LT_LIBEXT) +# define LT_LIBEXT "a" +#endif + +#if !defined(LT_LIBPREFIX) +# define LT_LIBPREFIX "lib" +#endif + +/* This is the maximum symbol size that won't require malloc/free */ +#undef LT_SYMBOL_LENGTH +#define LT_SYMBOL_LENGTH 128 + +/* This accounts for the _LTX_ separator */ +#undef LT_SYMBOL_OVERHEAD +#define LT_SYMBOL_OVERHEAD 5 + +/* Various boolean flags can be stored in the flags field of an + lt_dlhandle... */ +#define LT_DLIS_RESIDENT(handle) ((handle)->info.is_resident) +#define LT_DLIS_SYMGLOBAL(handle) ((handle)->info.is_symglobal) +#define LT_DLIS_SYMLOCAL(handle) ((handle)->info.is_symlocal) + + +static const char objdir[] = LT_OBJDIR; +static const char archive_ext[] = LT_ARCHIVE_EXT; +static const char libext[] = LT_LIBEXT; +static const char libprefix[] = LT_LIBPREFIX; +#if defined(LT_MODULE_EXT) +static const char shlib_ext[] = LT_MODULE_EXT; +#endif +/* If the loadable module suffix is not the same as the linkable + * shared library suffix, this will be defined. */ +#if defined(LT_SHARED_EXT) +static const char shared_ext[] = LT_SHARED_EXT; +#endif +#if defined(LT_DLSEARCH_PATH) +static const char sys_dlsearch_path[] = LT_DLSEARCH_PATH; +#endif + + + + +/* --- DYNAMIC MODULE LOADING --- */ + + +/* The type of a function used at each iteration of foreach_dirinpath(). */ +typedef int foreach_callback_func (char *filename, void *data1, + void *data2); +/* foreachfile_callback itself calls a function of this type: */ +typedef int file_worker_func (const char *filename, void *data); + + +static int foreach_dirinpath (const char *search_path, + const char *base_name, + foreach_callback_func *func, + void *data1, void *data2); +static int find_file_callback (char *filename, void *data1, + void *data2); +static int find_handle_callback (char *filename, void *data, + void *ignored); +static int foreachfile_callback (char *filename, void *data1, + void *data2); + + +static int canonicalize_path (const char *path, char **pcanonical); +static int argzize_path (const char *path, + char **pargz, size_t *pargz_len); +static FILE *find_file (const char *search_path, + const char *base_name, char **pdir); +static lt_dlhandle *find_handle (const char *search_path, + const char *base_name, + lt_dlhandle *handle, + lt_dladvise advise); +static int find_module (lt_dlhandle *handle, const char *dir, + const char *libdir, const char *dlname, + const char *old_name, int installed, + lt_dladvise advise); +static int has_library_ext (const char *filename); +static int load_deplibs (lt_dlhandle handle, char *deplibs); +static int trim (char **dest, const char *str); +static int try_dlopen (lt_dlhandle *handle, + const char *filename, const char *ext, + lt_dladvise advise); +static int tryall_dlopen (lt_dlhandle *handle, + const char *filename, + lt_dladvise padvise, + const lt_dlvtable *vtable); +static int unload_deplibs (lt_dlhandle handle); +static int lt_argz_insert (char **pargz, size_t *pargz_len, + char *before, const char *entry); +static int lt_argz_insertinorder (char **pargz, size_t *pargz_len, + const char *entry); +static int lt_argz_insertdir (char **pargz, size_t *pargz_len, + const char *dirnam, struct dirent *dp); +static int lt_dlpath_insertdir (char **ppath, char *before, + const char *dir); +static int list_files_by_dir (const char *dirnam, + char **pargz, size_t *pargz_len); +static int file_not_found (void); + +#ifdef HAVE_LIBDLLOADER +static int loader_init_callback (lt_dlhandle handle); +#endif /* HAVE_LIBDLLOADER */ + +static int loader_init (lt_get_vtable *vtable_func, + lt_user_data data); + +static char *user_search_path= 0; +static lt_dlhandle handles = 0; +static int initialized = 0; + +/* Our memory failure callback sets the error message to be passed back + up to the client, so we must be careful to return from mallocation + callers if allocation fails (as this callback returns!!). */ +void +lt__alloc_die_callback (void) +{ + LT__SETERROR (NO_MEMORY); +} + +#ifdef HAVE_LIBDLLOADER +/* This function is called to initialise each preloaded module loader, + and hook it into the list of loaders to be used when attempting to + dlopen an application module. */ +static int +loader_init_callback (lt_dlhandle handle) +{ + lt_get_vtable *vtable_func = (lt_get_vtable *) lt_dlsym (handle, "get_vtable"); + return loader_init (vtable_func, 0); +} +#endif /* HAVE_LIBDLLOADER */ + +static int +loader_init (lt_get_vtable *vtable_func, lt_user_data data) +{ + const lt_dlvtable *vtable = 0; + int errors = 0; + + if (vtable_func) + { + vtable = (*vtable_func) (data); + } + + /* lt_dlloader_add will LT__SETERROR if it fails. */ + errors += lt_dlloader_add (vtable); + + assert (errors || vtable); + + if ((!errors) && vtable->dlloader_init) + { + if ((*vtable->dlloader_init) (vtable->dlloader_data)) + { + LT__SETERROR (INIT_LOADER); + ++errors; + } + } + + return errors; +} + +/* Bootstrap the loader loading with the preopening loader. */ +#define get_vtable preopen_LTX_get_vtable +#define preloaded_symbols LT_CONC3(lt_, LTDLOPEN, _LTX_preloaded_symbols) + +LT_BEGIN_C_DECLS +LT_SCOPE const lt_dlvtable * get_vtable (lt_user_data data); +LT_END_C_DECLS +#ifdef HAVE_LIBDLLOADER +extern LT_DLSYM_CONST lt_dlsymlist preloaded_symbols[]; +#endif + +/* Initialize libltdl. */ +int +lt_dlinit (void) +{ + int errors = 0; + + /* Initialize only at first call. */ + if (++initialized == 1) + { + lt__alloc_die = lt__alloc_die_callback; + handles = 0; + user_search_path = 0; /* empty search path */ + + /* First set up the statically loaded preload module loader, so + we can use it to preopen the other loaders we linked in at + compile time. */ + errors += loader_init (get_vtable, 0); + + /* Now open all the preloaded module loaders, so the application + can use _them_ to lt_dlopen its own modules. */ +#ifdef HAVE_LIBDLLOADER + if (!errors) + { + errors += lt_dlpreload (preloaded_symbols); + } + + if (!errors) + { + errors += lt_dlpreload_open (LT_STR(LTDLOPEN), loader_init_callback); + } +#endif /* HAVE_LIBDLLOADER */ + } + +#ifdef LT_DEBUG_LOADERS + lt_dlloader_dump(); +#endif + + return errors; +} + +int +lt_dlexit (void) +{ + /* shut down libltdl */ + lt_dlloader *loader = 0; + lt_dlhandle handle = handles; + int errors = 0; + + if (!initialized) + { + LT__SETERROR (SHUTDOWN); + ++errors; + goto done; + } + + /* shut down only at last call. */ + if (--initialized == 0) + { + int level; + + while (handles && LT_DLIS_RESIDENT (handles)) + { + handles = handles->next; + } + + /* close all modules */ + for (level = 1; handle; ++level) + { + lt_dlhandle cur = handles; + int saw_nonresident = 0; + + while (cur) + { + lt_dlhandle tmp = cur; + cur = cur->next; + if (!LT_DLIS_RESIDENT (tmp)) + { + saw_nonresident = 1; + if (tmp->info.ref_count <= level) + { + if (lt_dlclose (tmp)) + { + ++errors; + } + /* Make sure that the handle pointed to by 'cur' still exists. + lt_dlclose recursively closes dependent libraries which removes + them from the linked list. One of these might be the one + pointed to by 'cur'. */ + if (cur) + { + for (tmp = handles; tmp; tmp = tmp->next) + if (tmp == cur) + break; + if (! tmp) + cur = handles; + } + } + } + } + /* done if only resident modules are left */ + if (!saw_nonresident) + break; + } + + /* When removing loaders, we can only find out failure by testing + the error string, so avoid a spurious one from an earlier + failed command. */ + if (!errors) + LT__SETERRORSTR (0); + + /* close all loaders */ + for (loader = (lt_dlloader *) lt_dlloader_next (NULL); loader;) + { + lt_dlloader *next = (lt_dlloader *) lt_dlloader_next (loader); + lt_dlvtable *vtable = (lt_dlvtable *) lt_dlloader_get (loader); + + if ((vtable = lt_dlloader_remove ((char *) vtable->name))) + { + FREE (vtable); + } + else + { + /* ignore errors due to resident modules */ + const char *err; + LT__GETERROR (err); + if (err) + ++errors; + } + + loader = next; + } + + FREE(user_search_path); + } + + done: + return errors; +} + + +/* Try VTABLE or, if VTABLE is NULL, all available loaders for FILENAME. + If the library is not successfully loaded, return non-zero. Otherwise, + the dlhandle is stored at the address given in PHANDLE. */ +static int +tryall_dlopen (lt_dlhandle *phandle, const char *filename, + lt_dladvise advise, const lt_dlvtable *vtable) +{ + lt_dlhandle handle = handles; + const char * saved_error = 0; + int errors = 0; + +#ifdef LT_DEBUG_LOADERS + fprintf (stderr, "tryall_dlopen (%s, %s)\n", + filename ? filename : "(null)", + vtable ? vtable->name : "(ALL)"); +#endif + + LT__GETERROR (saved_error); + + /* check whether the module was already opened */ + for (;handle; handle = handle->next) + { + if ((handle->info.filename == filename) /* dlopen self: 0 == 0 */ + || (handle->info.filename && filename + && streq (handle->info.filename, filename))) + { + break; + } + } + + if (handle) + { + ++handle->info.ref_count; + *phandle = handle; + goto done; + } + + handle = *phandle; + if (filename) + { + /* Comment out the check of file permissions using access. + This call seems to always return -1 with error EACCES. + */ + /* We need to catch missing file errors early so that + file_not_found() can detect what happened. + if (access (filename, R_OK) != 0) + { + LT__SETERROR (FILE_NOT_FOUND); + ++errors; + goto done; + } */ + + handle->info.filename = lt__strdup (filename); + if (!handle->info.filename) + { + ++errors; + goto done; + } + } + else + { + handle->info.filename = 0; + } + + { + lt_dlloader loader = lt_dlloader_next (0); + const lt_dlvtable *loader_vtable; + + do + { + if (vtable) + loader_vtable = vtable; + else + loader_vtable = lt_dlloader_get (loader); + +#ifdef LT_DEBUG_LOADERS + fprintf (stderr, "Calling %s->module_open (%s)\n", + (loader_vtable && loader_vtable->name) ? loader_vtable->name : "(null)", + filename ? filename : "(null)"); +#endif + handle->module = (*loader_vtable->module_open) (loader_vtable->dlloader_data, + filename, advise); +#ifdef LT_DEBUG_LOADERS + fprintf (stderr, " Result: %s\n", + handle->module ? "Success" : "Failed"); +#endif + + if (handle->module != 0) + { + if (advise) + { + handle->info.is_resident = advise->is_resident; + handle->info.is_symglobal = advise->is_symglobal; + handle->info.is_symlocal = advise->is_symlocal; + } + break; + } + } + while (!vtable && (loader = lt_dlloader_next (loader))); + + /* If VTABLE was given but couldn't open the module, or VTABLE wasn't + given but we exhausted all loaders without opening the module, bail + out! */ + if ((vtable && !handle->module) + || (!vtable && !loader)) + { + FREE (handle->info.filename); + ++errors; + goto done; + } + + handle->vtable = loader_vtable; + } + + LT__SETERRORSTR (saved_error); + + done: + return errors; +} + + +static int +tryall_dlopen_module (lt_dlhandle *handle, const char *prefix, + const char *dirname, const char *dlname, + lt_dladvise advise) +{ + int error = 0; + char *filename = 0; + size_t filename_len = 0; + size_t dirname_len = LT_STRLEN (dirname); + + assert (handle); + assert (dirname); + assert (dlname); +#if defined(LT_DIRSEP_CHAR) + /* Only canonicalized names (i.e. with DIRSEP chars already converted) + should make it into this function: */ + assert (strchr (dirname, LT_DIRSEP_CHAR) == 0); +#endif + + if (dirname_len > 0) + if (dirname[dirname_len -1] == '/') + --dirname_len; + filename_len = dirname_len + 1 + LT_STRLEN (dlname); + + /* Allocate memory, and combine DIRNAME and MODULENAME into it. + The PREFIX (if any) is handled below. */ + filename = MALLOC (char, filename_len + 1); + if (!filename) + return 1; + + sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname); + + /* Now that we have combined DIRNAME and MODULENAME, if there is + also a PREFIX to contend with, simply recurse with the arguments + shuffled. Otherwise, attempt to open FILENAME as a module. */ + if (prefix) + { + error += tryall_dlopen_module (handle, (const char *) 0, + prefix, filename, advise); + } + else if (tryall_dlopen (handle, filename, advise, 0) != 0) + { + ++error; + } + + FREE (filename); + return error; +} + +static int +find_module (lt_dlhandle *handle, const char *dir, const char *libdir, + const char *dlname, const char *old_name, int installed, + lt_dladvise advise) +{ + /* Try to open the old library first; if it was dlpreopened, + we want the preopened version of it, even if a dlopenable + module is available. */ + if (old_name && tryall_dlopen (handle, old_name, + advise, lt_dlloader_find ("lt_preopen") ) == 0) + { + return 0; + } + + /* Try to open the dynamic library. */ + if (dlname) + { + /* try to open the installed module */ + if (installed && libdir) + { + if (tryall_dlopen_module (handle, (const char *) 0, + libdir, dlname, advise) == 0) + return 0; + } + + /* try to open the not-installed module */ + if (!installed) + { + if (tryall_dlopen_module (handle, dir, objdir, + dlname, advise) == 0) + return 0; + } + + /* maybe it was moved to another directory */ + { + if (dir && (tryall_dlopen_module (handle, (const char *) 0, + dir, dlname, advise) == 0)) + return 0; + } + } + + return 1; +} + + +static int +canonicalize_path (const char *path, char **pcanonical) +{ + char *canonical = 0; + + assert (path && *path); + assert (pcanonical); + + canonical = MALLOC (char, 1+ LT_STRLEN (path)); + if (!canonical) + return 1; + + { + size_t dest = 0; + size_t src; + for (src = 0; path[src] != LT_EOS_CHAR; ++src) + { + /* Path separators are not copied to the beginning or end of + the destination, or if another separator would follow + immediately. */ + if (path[src] == LT_PATHSEP_CHAR) + { + if ((dest == 0) + || (path[1+ src] == LT_PATHSEP_CHAR) + || (path[1+ src] == LT_EOS_CHAR)) + continue; + } + + /* Anything other than a directory separator is copied verbatim. */ + if ((path[src] != '/') +#if defined(LT_DIRSEP_CHAR) + && (path[src] != LT_DIRSEP_CHAR) +#endif + ) + { + canonical[dest++] = path[src]; + } + /* Directory separators are converted and copied only if they are + not at the end of a path -- i.e. before a path separator or + NULL terminator. */ + else if ((path[1+ src] != LT_PATHSEP_CHAR) + && (path[1+ src] != LT_EOS_CHAR) +#if defined(LT_DIRSEP_CHAR) + && (path[1+ src] != LT_DIRSEP_CHAR) +#endif + && (path[1+ src] != '/')) + { + canonical[dest++] = '/'; + } + } + + /* Add an end-of-string marker at the end. */ + canonical[dest] = LT_EOS_CHAR; + } + + /* Assign new value. */ + *pcanonical = canonical; + + return 0; +} + +static int +argzize_path (const char *path, char **pargz, size_t *pargz_len) +{ + error_t error; + + assert (path); + assert (pargz); + assert (pargz_len); + + if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len))) + { + switch (error) + { + case ENOMEM: + LT__SETERROR (NO_MEMORY); + break; + default: + LT__SETERROR (UNKNOWN); + break; + } + + return 1; + } + + return 0; +} + +/* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element + of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns + non-zero or all elements are exhausted. If BASE_NAME is non-NULL, + it is appended to each SEARCH_PATH element before FUNC is called. */ +static int +foreach_dirinpath (const char *search_path, const char *base_name, + foreach_callback_func *func, void *data1, void *data2) +{ + int result = 0; + size_t filenamesize = 0; + size_t lenbase = LT_STRLEN (base_name); + size_t argz_len = 0; + char *argz = 0; + char *filename = 0; + char *canonical = 0; + + if (!search_path || !*search_path) + { + LT__SETERROR (FILE_NOT_FOUND); + goto cleanup; + } + + if (canonicalize_path (search_path, &canonical) != 0) + goto cleanup; + + if (argzize_path (canonical, &argz, &argz_len) != 0) + goto cleanup; + + { + char *dir_name = 0; + while ((dir_name = argz_next (argz, argz_len, dir_name))) + { + size_t lendir = LT_STRLEN (dir_name); + + if (1+ lendir + lenbase >= filenamesize) + { + FREE (filename); + filenamesize = 1+ lendir + 1+ lenbase; /* "/d" + '/' + "f" + '\0' */ + filename = MALLOC (char, filenamesize); + if (!filename) + goto cleanup; + } + + assert (filenamesize > lendir); + strcpy (filename, dir_name); + + if (base_name && *base_name) + { + if (filename[lendir -1] != '/') + filename[lendir++] = '/'; + strcpy (filename +lendir, base_name); + } + + if ((result = (*func) (filename, data1, data2))) + { + break; + } + } + } + + cleanup: + FREE (argz); + FREE (canonical); + FREE (filename); + + return result; +} + +/* If FILEPATH can be opened, store the name of the directory component + in DATA1, and the opened FILE* structure address in DATA2. Otherwise + DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */ +static int +find_file_callback (char *filename, void *data1, void *data2) +{ + char **pdir = (char **) data1; + FILE **pfile = (FILE **) data2; + int is_done = 0; + + assert (filename && *filename); + assert (pdir); + assert (pfile); + + if ((*pfile = fopen (filename, LT_READTEXT_MODE))) + { + char *dirend = strrchr (filename, '/'); + + if (dirend > filename) + *dirend = LT_EOS_CHAR; + + FREE (*pdir); + *pdir = lt__strdup (filename); + is_done = (*pdir == 0) ? -1 : 1; + } + + return is_done; +} + +static FILE * +find_file (const char *search_path, const char *base_name, char **pdir) +{ + FILE *file = 0; + + foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file); + + return file; +} + +static int +find_handle_callback (char *filename, void *data, void *data2) +{ + lt_dlhandle *phandle = (lt_dlhandle *) data; + int notfound = access (filename, R_OK); + lt_dladvise advise = (lt_dladvise) data2; + + /* Bail out if file cannot be read... */ + if (notfound) + return 0; + + /* Try to dlopen the file, but do not continue searching in any + case. */ + if (tryall_dlopen (phandle, filename, advise, 0) != 0) + *phandle = 0; + + return 1; +} + +/* If HANDLE was found return it, otherwise return 0. If HANDLE was + found but could not be opened, *HANDLE will be set to 0. */ +static lt_dlhandle * +find_handle (const char *search_path, const char *base_name, + lt_dlhandle *phandle, lt_dladvise advise) +{ + if (!search_path) + return 0; + + if (!foreach_dirinpath (search_path, base_name, find_handle_callback, + phandle, advise)) + return 0; + + return phandle; +} + +#if !defined(LTDL_DLOPEN_DEPLIBS) +static int +load_deplibs (lt_dlhandle handle, char * LT__UNUSED deplibs) +{ + handle->depcount = 0; + return 0; +} + +#else /* defined(LTDL_DLOPEN_DEPLIBS) */ +static int +load_deplibs (lt_dlhandle handle, char *deplibs) +{ + char *p, *save_search_path = 0; + int depcount = 0; + int i; + char **names = 0; + int errors = 0; + + handle->depcount = 0; + + if (!deplibs) + { + return errors; + } + ++errors; + + if (user_search_path) + { + save_search_path = lt__strdup (user_search_path); + if (!save_search_path) + goto cleanup; + } + + /* extract search paths and count deplibs */ + p = deplibs; + while (*p) + { + if (!isspace ((unsigned char) *p)) + { + char *end = p+1; + while (*end && !isspace((unsigned char) *end)) + { + ++end; + } + + if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0) + { + char save = *end; + *end = 0; /* set a temporary string terminator */ + if (lt_dladdsearchdir(p+2)) + { + goto cleanup; + } + *end = save; + } + else + { + ++depcount; + } + + p = end; + } + else + { + ++p; + } + } + + + if (!depcount) + { + errors = 0; + goto cleanup; + } + + names = MALLOC (char *, depcount); + if (!names) + goto cleanup; + + /* now only extract the actual deplibs */ + depcount = 0; + p = deplibs; + while (*p) + { + if (isspace ((unsigned char) *p)) + { + ++p; + } + else + { + char *end = p+1; + while (*end && !isspace ((unsigned char) *end)) + { + ++end; + } + + if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0) + { + char *name; + char save = *end; + *end = 0; /* set a temporary string terminator */ + if (strncmp(p, "-l", 2) == 0) + { + size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2); + name = MALLOC (char, 1+ name_len); + if (name) + sprintf (name, "lib%s", p+2); + } + else + name = lt__strdup(p); + + if (!name) + goto cleanup_names; + + names[depcount++] = name; + *end = save; + } + p = end; + } + } + + /* load the deplibs (in reverse order) + At this stage, don't worry if the deplibs do not load correctly, + they may already be statically linked into the loading application + for instance. There will be a more enlightening error message + later on if the loaded module cannot resolve all of its symbols. */ + if (depcount) + { + lt_dlhandle cur = handle; + int j = 0; + + cur->deplibs = MALLOC (lt_dlhandle, depcount); + if (!cur->deplibs) + goto cleanup_names; + + for (i = 0; i < depcount; ++i) + { + cur->deplibs[j] = lt_dlopenext(names[depcount-1-i]); + if (cur->deplibs[j]) + { + ++j; + } + } + + cur->depcount = j; /* Number of successfully loaded deplibs */ + errors = 0; + } + + cleanup_names: + for (i = 0; i < depcount; ++i) + { + FREE (names[i]); + } + + cleanup: + FREE (names); + /* restore the old search path */ + if (save_search_path) { + MEMREASSIGN (user_search_path, save_search_path); + } + + return errors; +} +#endif /* defined(LTDL_DLOPEN_DEPLIBS) */ + +static int +unload_deplibs (lt_dlhandle handle) +{ + int i; + int errors = 0; + lt_dlhandle cur = handle; + + if (cur->depcount) + { + for (i = 0; i < cur->depcount; ++i) + { + if (!LT_DLIS_RESIDENT (cur->deplibs[i])) + { + errors += lt_dlclose (cur->deplibs[i]); + } + } + FREE (cur->deplibs); + } + + return errors; +} + +static int +trim (char **dest, const char *str) +{ + /* remove the leading and trailing "'" from str + and store the result in dest */ + const char *end = strrchr (str, '\''); + size_t len = LT_STRLEN (str); + char *tmp; + + FREE (*dest); + + if (!end || end == str) + return 1; + + if (len > 3 && str[0] == '\'') + { + tmp = MALLOC (char, end - str); + if (!tmp) + return 1; + + memcpy(tmp, &str[1], (end - str) - 1); + tmp[(end - str) - 1] = LT_EOS_CHAR; + *dest = tmp; + } + else + { + *dest = 0; + } + + return 0; +} + +/* Read the .la file FILE. */ +static int +parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs, + char **old_name, int *installed) +{ + int errors = 0; + size_t line_len = LT_FILENAME_MAX; + char * line = MALLOC (char, line_len); + + if (!line) + { + LT__SETERROR (FILE_NOT_FOUND); + return 1; + } + + while (!feof (file)) + { + line[line_len-2] = '\0'; + if (!fgets (line, (int) line_len, file)) + { + break; + } + + /* Handle the case where we occasionally need to read a line + that is longer than the initial buffer size. + Behave even if the file contains NUL bytes due to corruption. */ + while (line[line_len-2] != '\0' && line[line_len-2] != '\n' && !feof (file)) + { + line = REALLOC (char, line, line_len *2); + if (!line) + { + ++errors; + goto cleanup; + } + line[line_len * 2 - 2] = '\0'; + if (!fgets (&line[line_len -1], (int) line_len +1, file)) + { + break; + } + line_len *= 2; + } + + if (line[0] == '\n' || line[0] == '#') + { + continue; + } + +#undef STR_DLNAME +#define STR_DLNAME "dlname=" + if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) + { + errors += trim (dlname, &line[sizeof (STR_DLNAME) - 1]); + } + +#undef STR_OLD_LIBRARY +#define STR_OLD_LIBRARY "old_library=" + else if (strncmp (line, STR_OLD_LIBRARY, + sizeof (STR_OLD_LIBRARY) - 1) == 0) + { + errors += trim (old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); + } + + /* Windows native tools do not understand the POSIX paths we store + in libdir. */ +#undef STR_LIBDIR +#define STR_LIBDIR "libdir=" + else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) + { + errors += trim (libdir, &line[sizeof(STR_LIBDIR) - 1]); +#ifdef __WINDOWS__ + /* Disallow following unix-style paths on MinGW. */ + if (*libdir && (**libdir == '/' || **libdir == '\\')) + **libdir = '\0'; +#endif + } + +#undef STR_DL_DEPLIBS +#define STR_DL_DEPLIBS "dependency_libs=" + else if (strncmp (line, STR_DL_DEPLIBS, + sizeof (STR_DL_DEPLIBS) - 1) == 0) + { + errors += trim (deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); + } + else if (streq (line, "installed=yes\n")) + { + *installed = 1; + } + else if (streq (line, "installed=no\n")) + { + *installed = 0; + } + +#undef STR_LIBRARY_NAMES +#define STR_LIBRARY_NAMES "library_names=" + else if (!*dlname && strncmp (line, STR_LIBRARY_NAMES, + sizeof (STR_LIBRARY_NAMES) - 1) == 0) + { + char *last_libname; + errors += trim (dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); + if (!errors + && *dlname + && (last_libname = strrchr (*dlname, ' ')) != 0) + { + last_libname = lt__strdup (last_libname + 1); + if (!last_libname) + { + ++errors; + goto cleanup; + } + MEMREASSIGN (*dlname, last_libname); + } + } + + if (errors) + break; + } +cleanup: + FREE (line); + return errors; +} + + +/* Try to open FILENAME as a module. */ +static int +try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext, + lt_dladvise advise) +{ + const char * saved_error = 0; + char * archive_name = 0; + char * canonical = 0; + char * base_name = 0; + char * dir = 0; + char * name = 0; + char * attempt = 0; + int errors = 0; + lt_dlhandle newhandle; + + assert (phandle); + assert (*phandle == 0); + +#ifdef LT_DEBUG_LOADERS + fprintf (stderr, "try_dlopen (%s, %s)\n", + filename ? filename : "(null)", + ext ? ext : "(null)"); +#endif + + LT__GETERROR (saved_error); + + /* dlopen self? */ + if (!filename) + { + *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle)); + if (*phandle == 0) + return 1; + + newhandle = *phandle; + + /* lt_dlclose()ing yourself is very bad! Disallow it. */ + newhandle->info.is_resident = 1; + + if (tryall_dlopen (&newhandle, 0, advise, 0) != 0) + { + FREE (*phandle); + return 1; + } + + goto register_handle; + } + + assert (filename && *filename); + + if (ext) + { + attempt = MALLOC (char, LT_STRLEN (filename) + LT_STRLEN (ext) + 1); + if (!attempt) + return 1; + + sprintf(attempt, "%s%s", filename, ext); + } + else + { + attempt = lt__strdup (filename); + if (!attempt) + return 1; + } + + /* Doing this immediately allows internal functions to safely + assume only canonicalized paths are passed. */ + if (canonicalize_path (attempt, &canonical) != 0) + { + ++errors; + goto cleanup; + } + + /* If the canonical module name is a path (relative or absolute) + then split it into a directory part and a name part. */ + base_name = strrchr (canonical, '/'); + if (base_name) + { + size_t dirlen = (1+ base_name) - canonical; + + dir = MALLOC (char, 1+ dirlen); + if (!dir) + { + ++errors; + goto cleanup; + } + + strncpy (dir, canonical, dirlen); + dir[dirlen] = LT_EOS_CHAR; + + ++base_name; + } + else + MEMREASSIGN (base_name, canonical); + + assert (base_name && *base_name); + + ext = strrchr (base_name, '.'); + if (!ext) + { + ext = base_name + LT_STRLEN (base_name); + } + + /* extract the module name from the file name */ + name = MALLOC (char, ext - base_name + 1); + if (!name) + { + ++errors; + goto cleanup; + } + + /* canonicalize the module name */ + { + int i; + for (i = 0; i < ext - base_name; ++i) + { + if (isalnum ((unsigned char)(base_name[i]))) + { + name[i] = base_name[i]; + } + else + { + name[i] = '_'; + } + } + name[ext - base_name] = LT_EOS_CHAR; + } + + /* Before trawling through the filesystem in search of a module, + check whether we are opening a preloaded module. */ + if (!dir) + { + const lt_dlvtable *vtable = lt_dlloader_find ("lt_preopen"); + + if (vtable) + { + /* libprefix + name + "." + libext + NULL */ + archive_name = MALLOC (char, strlen (libprefix) + LT_STRLEN (name) + strlen (libext) + 2); + *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle)); + + if ((*phandle == NULL) || (archive_name == NULL)) + { + ++errors; + goto cleanup; + } + newhandle = *phandle; + + /* Preloaded modules are always named according to their old + archive name. */ + if (strncmp(name, "lib", 3) == 0) + { + sprintf (archive_name, "%s%s.%s", libprefix, name + 3, libext); + } + else + { + sprintf (archive_name, "%s.%s", name, libext); + } + + if (tryall_dlopen (&newhandle, archive_name, advise, vtable) == 0) + { + goto register_handle; + } + + /* If we're still here, there was no matching preloaded module, + so put things back as we found them, and continue searching. */ + FREE (*phandle); + newhandle = NULL; + } + } + + /* If we are allowing only preloaded modules, and we didn't find + anything yet, give up on the search here. */ + if (advise && advise->try_preload_only) + { + goto cleanup; + } + + /* Check whether we are opening a libtool module (.la extension). */ + if (ext && streq (ext, archive_ext)) + { + /* this seems to be a libtool module */ + FILE * file = 0; + char * dlname = 0; + char * old_name = 0; + char * libdir = 0; + char * deplibs = 0; + + /* if we can't find the installed flag, it is probably an + installed libtool archive, produced with an old version + of libtool */ + int installed = 1; + + /* Now try to open the .la file. If there is no directory name + component, try to find it first in user_search_path and then other + prescribed paths. Otherwise (or in any case if the module was not + yet found) try opening just the module name as passed. */ + if (!dir) + { + const char *search_path = user_search_path; + + if (search_path) + file = find_file (user_search_path, base_name, &dir); + + if (!file) + { + search_path = getenv (LTDL_SEARCHPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } + +#if defined(LT_MODULE_PATH_VAR) + if (!file) + { + search_path = getenv (LT_MODULE_PATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } +#endif +#if defined(LT_DLSEARCH_PATH) + if (!file && *sys_dlsearch_path) + { + file = find_file (sys_dlsearch_path, base_name, &dir); + } +#endif + } + else + { + file = fopen (attempt, LT_READTEXT_MODE); + } + + /* If we didn't find the file by now, it really isn't there. Set + the status flag, and bail out. */ + if (!file) + { + LT__SETERROR (FILE_NOT_FOUND); + ++errors; + goto cleanup; + } + + /* read the .la file */ + if (parse_dotla_file(file, &dlname, &libdir, &deplibs, + &old_name, &installed) != 0) + ++errors; + + fclose (file); + + /* allocate the handle */ + *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle)); + if (*phandle == 0) + ++errors; + + if (errors) + { + FREE (dlname); + FREE (old_name); + FREE (libdir); + FREE (deplibs); + FREE (*phandle); + goto cleanup; + } + + assert (*phandle); + + if (load_deplibs (*phandle, deplibs) == 0) + { + newhandle = *phandle; + /* find_module may replace newhandle */ + if (find_module (&newhandle, dir, libdir, dlname, old_name, + installed, advise)) + { + unload_deplibs (*phandle); + ++errors; + } + } + else + { + ++errors; + } + + FREE (dlname); + FREE (old_name); + FREE (libdir); + FREE (deplibs); + + if (errors) + { + FREE (*phandle); + goto cleanup; + } + + if (*phandle != newhandle) + { + unload_deplibs (*phandle); + } + } + else + { + /* not a libtool module */ + *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle)); + if (*phandle == 0) + { + ++errors; + goto cleanup; + } + + newhandle = *phandle; + + /* If the module has no directory name component, try to find it + first in user_search_path and then other prescribed paths. + Otherwise (or in any case if the module was not yet found) try + opening just the module name as passed. */ + if ((dir || (!find_handle (user_search_path, base_name, + &newhandle, advise) + && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name, + &newhandle, advise) +#if defined(LT_MODULE_PATH_VAR) + && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name, + &newhandle, advise) +#endif +#if defined(LT_DLSEARCH_PATH) + && !find_handle (sys_dlsearch_path, base_name, + &newhandle, advise) +#endif + ))) + { + if (tryall_dlopen (&newhandle, attempt, advise, 0) != 0) + { + newhandle = NULL; + } + } + + if (!newhandle) + { + FREE (*phandle); + ++errors; + goto cleanup; + } + } + + register_handle: + MEMREASSIGN (*phandle, newhandle); + + if ((*phandle)->info.ref_count == 0) + { + (*phandle)->info.ref_count = 1; + MEMREASSIGN ((*phandle)->info.name, name); + + (*phandle)->next = handles; + handles = *phandle; + } + + LT__SETERRORSTR (saved_error); + + cleanup: + FREE (dir); + FREE (attempt); + FREE (name); + if (!canonical) /* was MEMREASSIGNed */ + FREE (base_name); + FREE (canonical); + FREE (archive_name); + + return errors; +} + + +/* If the last error message stored was `FILE_NOT_FOUND', then return + non-zero. */ +static int +file_not_found (void) +{ + const char *error = 0; + + LT__GETERROR (error); + if (error == LT__STRERROR (FILE_NOT_FOUND)) + return 1; + + return 0; +} + + +/* Unless FILENAME already bears a suitable library extension, then + return 0. */ +static int +has_library_ext (const char *filename) +{ + const char * ext = 0; + + assert (filename); + + ext = strrchr (filename, '.'); + + if (ext && ((streq (ext, archive_ext)) +#if defined(LT_MODULE_EXT) + || (streq (ext, shlib_ext)) +#endif +#if defined(LT_SHARED_EXT) + || (streq (ext, shared_ext)) +#endif + )) + { + return 1; + } + + return 0; +} + + +/* Initialise and configure a user lt_dladvise opaque object. */ + +int +lt_dladvise_init (lt_dladvise *padvise) +{ + lt_dladvise advise = (lt_dladvise) lt__zalloc (sizeof (struct lt__advise)); + *padvise = advise; + return (advise ? 0 : 1); +} + +int +lt_dladvise_destroy (lt_dladvise *padvise) +{ + if (padvise) + FREE(*padvise); + return 0; +} + +int +lt_dladvise_ext (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + (*padvise)->try_ext = 1; + return 0; +} + +int +lt_dladvise_resident (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + (*padvise)->is_resident = 1; + return 0; +} + +int +lt_dladvise_local (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + (*padvise)->is_symlocal = 1; + return 0; +} + +int +lt_dladvise_global (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + (*padvise)->is_symglobal = 1; + return 0; +} + +int +lt_dladvise_preload (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + (*padvise)->try_preload_only = 1; + return 0; +} + +/* Libtool-1.5.x interface for loading a new module named FILENAME. */ +lt_dlhandle +lt_dlopen (const char *filename) +{ + return lt_dlopenadvise (filename, NULL); +} + + +/* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to + open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, + and if a file is still not found try again with MODULE_EXT appended + instead. */ +lt_dlhandle +lt_dlopenext (const char *filename) +{ + lt_dlhandle handle = 0; + lt_dladvise advise; + + if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise)) + handle = lt_dlopenadvise (filename, advise); + + lt_dladvise_destroy (&advise); + return handle; +} + + +lt_dlhandle +lt_dlopenadvise (const char *filename, lt_dladvise advise) +{ + lt_dlhandle handle = 0; + int errors = 0; + const char * saved_error = 0; + + LT__GETERROR (saved_error); + + /* Can't have symbols hidden and visible at the same time! */ + if (advise && advise->is_symlocal && advise->is_symglobal) + { + LT__SETERROR (CONFLICTING_FLAGS); + return 0; + } + + if (!filename + || !advise + || !advise->try_ext + || has_library_ext (filename)) + { + /* Just incase we missed a code path in try_dlopen() that reports + an error, but forgot to reset handle... */ + if (try_dlopen (&handle, filename, NULL, advise) != 0) + return 0; + + return handle; + } + else if (filename && *filename) + { + + /* First try appending ARCHIVE_EXT. */ + errors += try_dlopen (&handle, filename, archive_ext, advise); + + /* If we found FILENAME, stop searching -- whether we were able to + load the file as a module or not. If the file exists but loading + failed, it is better to return an error message here than to + report FILE_NOT_FOUND when the alternatives (foo.so etc) are not + in the module search path. */ + if (handle || ((errors > 0) && !file_not_found ())) + return handle; + +#if defined(LT_MODULE_EXT) + /* Try appending SHLIB_EXT. */ + LT__SETERRORSTR (saved_error); + errors = try_dlopen (&handle, filename, shlib_ext, advise); + + /* As before, if the file was found but loading failed, return now + with the current error message. */ + if (handle || ((errors > 0) && !file_not_found ())) + return handle; +#endif + +#if defined(LT_SHARED_EXT) + /* Try appending SHARED_EXT. */ + LT__SETERRORSTR (saved_error); + errors = try_dlopen (&handle, filename, shared_ext, advise); + + /* As before, if the file was found but loading failed, return now + with the current error message. */ + if (handle || ((errors > 0) && !file_not_found ())) + return handle; +#endif + } + + /* Still here? Then we really did fail to locate any of the file + names we tried. */ + LT__SETERROR (FILE_NOT_FOUND); + return 0; +} + + +static int +lt_argz_insert (char **pargz, size_t *pargz_len, char *before, + const char *entry) +{ + error_t error; + + /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz, + pargz_len, NULL, entry) failed with EINVAL. */ + if (before) + error = argz_insert (pargz, pargz_len, before, entry); + else + error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry)); + + if (error) + { + switch (error) + { + case ENOMEM: + LT__SETERROR (NO_MEMORY); + break; + default: + LT__SETERROR (UNKNOWN); + break; + } + return 1; + } + + return 0; +} + +static int +lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry) +{ + char *before = 0; + + assert (pargz); + assert (pargz_len); + assert (entry && *entry); + + if (*pargz) + while ((before = argz_next (*pargz, *pargz_len, before))) + { + int cmp = strcmp (entry, before); + + if (cmp < 0) break; + if (cmp == 0) return 0; /* No duplicates! */ + } + + return lt_argz_insert (pargz, pargz_len, before, entry); +} + +static int +lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam, + struct dirent *dp) +{ + char *buf = 0; + size_t buf_len = 0; + char *end = 0; + size_t end_offset = 0; + size_t dir_len = 0; + int errors = 0; + + assert (pargz); + assert (pargz_len); + assert (dp); + + dir_len = LT_STRLEN (dirnam); + end = dp->d_name + D_NAMLEN(dp); + + /* Ignore version numbers. */ + { + char *p; + for (p = end; p -1 > dp->d_name; --p) + if (strchr (".0123456789", p[-1]) == 0) + break; + + if (*p == '.') + end = p; + } + + /* Ignore filename extension. */ + { + char *p; + for (p = end -1; p > dp->d_name; --p) + if (*p == '.') + { + end = p; + break; + } + } + + /* Prepend the directory name. */ + end_offset = end - dp->d_name; + buf_len = dir_len + 1+ end_offset; + buf = MALLOC (char, 1+ buf_len); + if (!buf) + return ++errors; + + assert (buf); + + strcpy (buf, dirnam); + strcat (buf, "/"); + strncat (buf, dp->d_name, end_offset); + buf[buf_len] = LT_EOS_CHAR; + + /* Try to insert (in order) into ARGZ/ARGZ_LEN. */ + if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0) + ++errors; + + FREE (buf); + + return errors; +} + +static int +list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len) +{ + DIR *dirp = 0; + int errors = 0; + + assert (dirnam && *dirnam); + assert (pargz); + assert (pargz_len); + assert (dirnam[LT_STRLEN(dirnam) -1] != '/'); + + dirp = opendir (dirnam); + if (dirp) + { + struct dirent *dp = 0; + + while ((dp = readdir (dirp))) + if (dp->d_name[0] != '.') + if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp)) + { + ++errors; + break; + } + + closedir (dirp); + } + else + ++errors; + + return errors; +} + + +/* If there are any files in DIRNAME, call the function passed in + DATA1 (with the name of each file and DATA2 as arguments). */ +static int +foreachfile_callback (char *dirname, void *data1, void *data2) +{ + file_worker_func *func = *(file_worker_func **) data1; + + int is_done = 0; + char *argz = 0; + size_t argz_len = 0; + + if (list_files_by_dir (dirname, &argz, &argz_len) != 0) + goto cleanup; + if (!argz) + goto cleanup; + + { + char *filename = 0; + while ((filename = argz_next (argz, argz_len, filename))) + if ((is_done = (*func) (filename, data2))) + break; + } + + cleanup: + FREE (argz); + + return is_done; +} + + +/* Call FUNC for each unique extensionless file in SEARCH_PATH, along + with DATA. The filenames passed to FUNC would be suitable for + passing to lt_dlopenext. The extensions are stripped so that + individual modules do not generate several entries (e.g. libfoo.la, + libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL, + then the same directories that lt_dlopen would search are examined. */ +int +lt_dlforeachfile (const char *search_path, + int (*func) (const char *filename, void *data), + void *data) +{ + int is_done = 0; + file_worker_func **fpptr = &func; + + if (search_path) + { + /* If a specific path was passed, search only the directories + listed in it. */ + is_done = foreach_dirinpath (search_path, 0, + foreachfile_callback, fpptr, data); + } + else + { + /* Otherwise search the default paths. */ + is_done = foreach_dirinpath (user_search_path, 0, + foreachfile_callback, fpptr, data); + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0, + foreachfile_callback, fpptr, data); + } + +#if defined(LT_MODULE_PATH_VAR) + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0, + foreachfile_callback, fpptr, data); + } +#endif +#if defined(LT_DLSEARCH_PATH) + if (!is_done && *sys_dlsearch_path) + { + is_done = foreach_dirinpath (sys_dlsearch_path, 0, + foreachfile_callback, fpptr, data); + } +#endif + } + + return is_done; +} + +int +lt_dlclose (lt_dlhandle handle) +{ + lt_dlhandle cur, last; + int errors = 0; + + /* check whether the handle is valid */ + last = cur = handles; + while (cur && handle != cur) + { + last = cur; + cur = cur->next; + } + + if (!cur) + { + LT__SETERROR (INVALID_HANDLE); + ++errors; + goto done; + } + + cur = handle; + cur->info.ref_count--; + + /* Note that even with resident modules, we must track the ref_count + correctly incase the user decides to reset the residency flag + later (even though the API makes no provision for that at the + moment). */ + if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur)) + { + lt_user_data data = cur->vtable->dlloader_data; + + if (cur != handles) + { + last->next = cur->next; + } + else + { + handles = cur->next; + } + + errors += cur->vtable->module_close (data, cur->module); + errors += unload_deplibs (handle); + + /* It is up to the callers to free the data itself. */ + FREE (cur->interface_data); + + FREE (cur->info.filename); + FREE (cur->info.name); + FREE (cur); + + goto done; + } + + if (LT_DLIS_RESIDENT (handle)) + { + LT__SETERROR (CLOSE_RESIDENT_MODULE); + ++errors; + } + + done: + return errors; +} + +void * +lt_dlsym (lt_dlhandle place, const char *symbol) +{ + size_t lensym; + char lsym[LT_SYMBOL_LENGTH]; + char *sym; + void *address; + lt_user_data data; + lt_dlhandle handle; + + if (!place) + { + LT__SETERROR (INVALID_HANDLE); + return 0; + } + + handle = place; + + if (!symbol) + { + LT__SETERROR (SYMBOL_NOT_FOUND); + return 0; + } + + lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->vtable->sym_prefix) + + LT_STRLEN (handle->info.name); + + if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH) + { + sym = lsym; + } + else + { + sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1); + if (!sym) + { + LT__SETERROR (BUFFER_OVERFLOW); + return 0; + } + } + + data = handle->vtable->dlloader_data; + if (handle->info.name) + { + const char *saved_error; + + LT__GETERROR (saved_error); + + /* this is a libtool module */ + if (handle->vtable->sym_prefix) + { + strcpy(sym, handle->vtable->sym_prefix); + strcat(sym, handle->info.name); + } + else + { + strcpy(sym, handle->info.name); + } + + strcat(sym, "_LTX_"); + strcat(sym, symbol); + + /* try "modulename_LTX_symbol" */ + address = handle->vtable->find_sym (data, handle->module, sym); + if (address) + { + if (sym != lsym) + { + FREE (sym); + } + return address; + } + LT__SETERRORSTR (saved_error); + } + + /* otherwise try "symbol" */ + if (handle->vtable->sym_prefix) + { + strcpy(sym, handle->vtable->sym_prefix); + strcat(sym, symbol); + } + else + { + strcpy(sym, symbol); + } + + address = handle->vtable->find_sym (data, handle->module, sym); + if (sym != lsym) + { + FREE (sym); + } + + return address; +} + +const char * +lt_dlerror (void) +{ + const char *error; + + LT__GETERROR (error); + LT__SETERRORSTR (0); + + return error; +} + +static int +lt_dlpath_insertdir (char **ppath, char *before, const char *dir) +{ + int errors = 0; + char *canonical = 0; + char *argz = 0; + size_t argz_len = 0; + + assert (ppath); + assert (dir && *dir); + + if (canonicalize_path (dir, &canonical) != 0) + { + ++errors; + goto cleanup; + } + + assert (canonical && *canonical); + + /* If *PPATH is empty, set it to DIR. */ + if (*ppath == 0) + { + assert (!before); /* BEFORE cannot be set without PPATH. */ + assert (dir); /* Without DIR, don't call this function! */ + + *ppath = lt__strdup (dir); + if (*ppath == 0) + ++errors; + + goto cleanup; + } + + assert (ppath && *ppath); + + if (argzize_path (*ppath, &argz, &argz_len) != 0) + { + ++errors; + goto cleanup; + } + + /* Convert BEFORE into an equivalent offset into ARGZ. This only works + if *PPATH is already canonicalized, and hence does not change length + with respect to ARGZ. We canonicalize each entry as it is added to + the search path, and don't call this function with (uncanonicalized) + user paths, so this is a fair assumption. */ + if (before) + { + assert (*ppath <= before); + assert ((int) (before - *ppath) <= (int) strlen (*ppath)); + + before = before - *ppath + argz; + } + + if (lt_argz_insert (&argz, &argz_len, before, dir) != 0) + { + ++errors; + goto cleanup; + } + + argz_stringify (argz, argz_len, LT_PATHSEP_CHAR); + MEMREASSIGN(*ppath, argz); + + cleanup: + FREE (argz); + FREE (canonical); + + return errors; +} + +int +lt_dladdsearchdir (const char *search_dir) +{ + int errors = 0; + + if (search_dir && *search_dir) + { + if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0) + ++errors; + } + + return errors; +} + +int +lt_dlinsertsearchdir (const char *before, const char *search_dir) +{ + int errors = 0; + + if (before) + { + if ((before < user_search_path) + || (before >= user_search_path + LT_STRLEN (user_search_path))) + { + LT__SETERROR (INVALID_POSITION); + return 1; + } + } + + if (search_dir && *search_dir) + { + if (lt_dlpath_insertdir (&user_search_path, + (char *) before, search_dir) != 0) + { + ++errors; + } + } + + return errors; +} + +int +lt_dlsetsearchpath (const char *search_path) +{ + int errors = 0; + + FREE (user_search_path); + + if (!search_path || !LT_STRLEN (search_path)) + { + return errors; + } + + if (canonicalize_path (search_path, &user_search_path) != 0) + ++errors; + + return errors; +} + +const char * +lt_dlgetsearchpath (void) +{ + const char *saved_path; + + saved_path = user_search_path; + + return saved_path; +} + +int +lt_dlmakeresident (lt_dlhandle handle) +{ + int errors = 0; + + if (!handle) + { + LT__SETERROR (INVALID_HANDLE); + ++errors; + } + else + { + handle->info.is_resident = 1; + } + + return errors; +} + +int +lt_dlisresident (lt_dlhandle handle) +{ + if (!handle) + { + LT__SETERROR (INVALID_HANDLE); + return -1; + } + + return LT_DLIS_RESIDENT (handle); +} + + + +/* --- MODULE INFORMATION --- */ + +typedef struct { + const char *id_string; + lt_dlhandle_interface *iface; +} lt__interface_id; + +lt_dlinterface_id +lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface) +{ + lt__interface_id *interface_id = (lt__interface_id *) lt__malloc (sizeof *interface_id); + + /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which + can then be detected with lt_dlerror() if we return 0. */ + if (interface_id) + { + interface_id->id_string = lt__strdup (id_string); + if (!interface_id->id_string) + FREE (interface_id); + else + interface_id->iface = iface; + } + + return (lt_dlinterface_id) interface_id; +} + +void lt_dlinterface_free (lt_dlinterface_id key) +{ + lt__interface_id *interface_id = (lt__interface_id *)key; + FREE (interface_id->id_string); + FREE (interface_id); +} + +void * +lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data) +{ + int n_elements = 0; + void *stale = (void *) 0; + lt_dlhandle cur = handle; + int i; + + if (cur->interface_data) + while (cur->interface_data[n_elements].key) + ++n_elements; + + for (i = 0; i < n_elements; ++i) + { + if (cur->interface_data[i].key == key) + { + stale = cur->interface_data[i].data; + break; + } + } + + /* Ensure that there is enough room in this handle's interface_data + array to accept a new element (and an empty end marker). */ + if (i == n_elements) + { + lt_interface_data *temp + = REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements); + + if (!temp) + { + stale = 0; + goto done; + } + + cur->interface_data = temp; + + /* We only need this if we needed to allocate a new interface_data. */ + cur->interface_data[i].key = key; + cur->interface_data[1+ i].key = 0; + } + + cur->interface_data[i].data = data; + + done: + return stale; +} + +void * +lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle) +{ + void *result = (void *) 0; + lt_dlhandle cur = handle; + + /* Locate the index of the element with a matching KEY. */ + if (cur->interface_data) + { + int i; + for (i = 0; cur->interface_data[i].key; ++i) + { + if (cur->interface_data[i].key == key) + { + result = cur->interface_data[i].data; + break; + } + } + } + + return result; +} + +const lt_dlinfo * +lt_dlgetinfo (lt_dlhandle handle) +{ + if (!handle) + { + LT__SETERROR (INVALID_HANDLE); + return 0; + } + + return &(handle->info); +} + + +lt_dlhandle +lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place) +{ + lt_dlhandle handle = place; + lt__interface_id *iterator = (lt__interface_id *) iface; + + assert (iface); /* iface is a required argument */ + + if (!handle) + handle = handles; + else + handle = handle->next; + + /* advance while the interface check fails */ + while (handle && iterator->iface + && ((*iterator->iface) (handle, iterator->id_string) != 0)) + { + handle = handle->next; + } + + return handle; +} + + +lt_dlhandle +lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name) +{ + lt_dlhandle handle = 0; + + assert (iface); /* iface is a required argument */ + + while ((handle = lt_dlhandle_iterate (iface, handle))) + { + lt_dlhandle cur = handle; + if (cur && cur->info.name && streq (cur->info.name, module_name)) + break; + } + + return handle; +} + + +int +lt_dlhandle_map (lt_dlinterface_id iface, + int (*func) (lt_dlhandle handle, void *data), void *data) +{ + lt__interface_id *iterator = (lt__interface_id *) iface; + lt_dlhandle cur = handles; + + assert (iface); /* iface is a required argument */ + + while (cur) + { + int errorcode = 0; + + /* advance while the interface check fails */ + while (cur && iterator->iface + && ((*iterator->iface) (cur, iterator->id_string) != 0)) + { + cur = cur->next; + } + + if ((errorcode = (*func) (cur, data)) != 0) + return errorcode; + } + + return 0; +} diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h new file mode 100644 index 0000000..749a54d --- /dev/null +++ b/libltdl/ltdl.h @@ -0,0 +1,163 @@ +/* ltdl.h -- generic dlopen functions + + Copyright (C) 1998-2000, 2004, 2005, + 2007, 2008 Free Software Foundation, Inc. + Written by Thomas Tanner, 1998 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/* Only include this header file once. */ +#if !defined(LTDL_H) +#define LTDL_H 1 + +#include <libltdl/lt_system.h> +#include <libltdl/lt_error.h> +#include <libltdl/lt_dlloader.h> + +LT_BEGIN_C_DECLS + + +/* LT_STRLEN can be used safely on NULL pointers. */ +#define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) + + +/* --- DYNAMIC MODULE LOADING API --- */ + + +typedef struct lt__handle *lt_dlhandle; /* A loaded module. */ + +/* Initialisation and finalisation functions for libltdl. */ +LT_SCOPE int lt_dlinit (void); +LT_SCOPE int lt_dlexit (void); + +/* Module search path manipulation. */ +LT_SCOPE int lt_dladdsearchdir (const char *search_dir); +LT_SCOPE int lt_dlinsertsearchdir (const char *before, + const char *search_dir); +LT_SCOPE int lt_dlsetsearchpath (const char *search_path); +LT_SCOPE const char *lt_dlgetsearchpath (void); +LT_SCOPE int lt_dlforeachfile ( + const char *search_path, + int (*func) (const char *filename, void *data), + void *data); + +/* User module loading advisors. */ +LT_SCOPE int lt_dladvise_init (lt_dladvise *advise); +LT_SCOPE int lt_dladvise_destroy (lt_dladvise *advise); +LT_SCOPE int lt_dladvise_ext (lt_dladvise *advise); +LT_SCOPE int lt_dladvise_resident (lt_dladvise *advise); +LT_SCOPE int lt_dladvise_local (lt_dladvise *advise); +LT_SCOPE int lt_dladvise_global (lt_dladvise *advise); +LT_SCOPE int lt_dladvise_preload (lt_dladvise *advise); + +/* Portable libltdl versions of the system dlopen() API. */ +LT_SCOPE lt_dlhandle lt_dlopen (const char *filename); +LT_SCOPE lt_dlhandle lt_dlopenext (const char *filename); +LT_SCOPE lt_dlhandle lt_dlopenadvise (const char *filename, + lt_dladvise advise); +LT_SCOPE void * lt_dlsym (lt_dlhandle handle, const char *name); +LT_SCOPE const char *lt_dlerror (void); +LT_SCOPE int lt_dlclose (lt_dlhandle handle); + + + +/* --- PRELOADED MODULE SUPPORT --- */ + + +/* A preopened symbol. Arrays of this type comprise the exported + symbols for a dlpreopened module. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; + +typedef int lt_dlpreload_callback_func (lt_dlhandle handle); + +LT_SCOPE int lt_dlpreload (const lt_dlsymlist *preloaded); +LT_SCOPE int lt_dlpreload_default (const lt_dlsymlist *preloaded); +LT_SCOPE int lt_dlpreload_open (const char *originator, + lt_dlpreload_callback_func *func); + +#define lt_preloaded_symbols lt__PROGRAM__LTX_preloaded_symbols +/* Ensure C linkage. */ +extern LT_DLSYM_CONST lt_dlsymlist lt__PROGRAM__LTX_preloaded_symbols[]; + +#define LTDL_SET_PRELOADED_SYMBOLS() \ + lt_dlpreload_default(lt_preloaded_symbols) + + + + +/* --- MODULE INFORMATION --- */ + + +/* Associating user data with loaded modules. */ +typedef void * lt_dlinterface_id; +typedef int lt_dlhandle_interface (lt_dlhandle handle, const char *id_string); + +LT_SCOPE lt_dlinterface_id lt_dlinterface_register (const char *id_string, + lt_dlhandle_interface *iface); +LT_SCOPE void lt_dlinterface_free (lt_dlinterface_id key); +LT_SCOPE void * lt_dlcaller_set_data (lt_dlinterface_id key, + lt_dlhandle handle, void *data); +LT_SCOPE void * lt_dlcaller_get_data (lt_dlinterface_id key, + lt_dlhandle handle); + + +/* Read only information pertaining to a loaded module. */ +typedef struct { + char * filename; /* file name */ + char * name; /* module name */ + int ref_count; /* number of times lt_dlopened minus + number of times lt_dlclosed. */ + unsigned int is_resident:1; /* module can't be unloaded. */ + unsigned int is_symglobal:1; /* module symbols can satisfy + subsequently loaded modules. */ + unsigned int is_symlocal:1; /* module symbols are only available + locally. */ +} lt_dlinfo; + +LT_SCOPE const lt_dlinfo *lt_dlgetinfo (lt_dlhandle handle); + +LT_SCOPE lt_dlhandle lt_dlhandle_iterate (lt_dlinterface_id iface, + lt_dlhandle place); +LT_SCOPE lt_dlhandle lt_dlhandle_fetch (lt_dlinterface_id iface, + const char *module_name); +LT_SCOPE int lt_dlhandle_map (lt_dlinterface_id iface, + int (*func) (lt_dlhandle handle, void *data), + void *data); + + + +/* Deprecated module residency management API. */ +LT_SCOPE int lt_dlmakeresident (lt_dlhandle handle); +LT_SCOPE int lt_dlisresident (lt_dlhandle handle); + +#define lt_ptr void * + +LT_END_C_DECLS + +#endif /*!defined(LTDL_H)*/ diff --git a/libltdl/slist.c b/libltdl/slist.c new file mode 100644 index 0000000..25906a4 --- /dev/null +++ b/libltdl/slist.c @@ -0,0 +1,379 @@ +/* slist.c -- generalised singly linked lists + + Copyright (C) 2000, 2004, 2007, 2008, 2009 Free Software Foundation, Inc. + Written by Gary V. Vaughan, 2000 + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. + +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <assert.h> + +#include "slist.h" +#include <stddef.h> +#include <stdlib.h> + +static SList * slist_sort_merge (SList *left, SList *right, + SListCompare *compare, void *userdata); + + +/* Call DELETE repeatedly on each element of HEAD. + + CAVEAT: If you call this when HEAD is the start of a list of boxed + items, you must remember that each item passed back to your + DELETE function will be a boxed item that must be slist_unbox()ed + before operating on its contents. + + e.g. void boxed_delete (void *item) { item_free (slist_unbox (item)); } + ... + slist = slist_delete (slist, boxed_delete); + ... +*/ +SList * +slist_delete (SList *head, void (*delete_fct) (void *item)) +{ + assert (delete_fct); + + while (head) + { + SList *next = head->next; + (*delete_fct) (head); + head = next; + } + + return 0; +} + +/* Call FIND repeatedly with MATCHDATA and each item of *PHEAD, until + FIND returns non-NULL, or the list is exhausted. If a match is found + the matching item is destructively removed from *PHEAD, and the value + returned by the matching call to FIND is returned. + + CAVEAT: To avoid memory leaks, unless you already have the address of + the stale item, you should probably return that from FIND if + it makes a successful match. Don't forget to slist_unbox() + every item in a boxed list before operating on its contents. */ +SList * +slist_remove (SList **phead, SListCallback *find, void *matchdata) +{ + SList *stale = 0; + void *result = 0; + + assert (find); + + if (!phead || !*phead) + return 0; + + /* Does the head of the passed list match? */ + result = (*find) (*phead, matchdata); + if (result) + { + stale = *phead; + *phead = stale->next; + } + /* what about the rest of the elements? */ + else + { + SList *head; + for (head = *phead; head->next; head = head->next) + { + result = (*find) (head->next, matchdata); + if (result) + { + stale = head->next; + head->next = stale->next; + break; + } + } + } + + return (SList *) result; +} + +/* Call FIND repeatedly with each element of SLIST and MATCHDATA, until + FIND returns non-NULL, or the list is exhausted. If a match is found + the value returned by the matching call to FIND is returned. */ +void * +slist_find (SList *slist, SListCallback *find, void *matchdata) +{ + void *result = 0; + + assert (find); + + for (; slist; slist = slist->next) + { + result = (*find) (slist, matchdata); + if (result) + break; + } + + return result; +} + +/* Return a single list, composed by destructively concatenating the + items in HEAD and TAIL. The values of HEAD and TAIL are undefined + after calling this function. + + CAVEAT: Don't mix boxed and unboxed items in a single list. + + e.g. slist1 = slist_concat (slist1, slist2); */ +SList * +slist_concat (SList *head, SList *tail) +{ + SList *last; + + if (!head) + { + return tail; + } + + last = head; + while (last->next) + last = last->next; + + last->next = tail; + + return head; +} + +/* Return a single list, composed by destructively appending all of + the items in SLIST to ITEM. The values of ITEM and SLIST are undefined + after calling this function. + + CAVEAT: Don't mix boxed and unboxed items in a single list. + + e.g. slist1 = slist_cons (slist_box (data), slist1); */ +SList * +slist_cons (SList *item, SList *slist) +{ + if (!item) + { + return slist; + } + + assert (!item->next); + + item->next = slist; + return item; +} + +/* Return a list starting at the second item of SLIST. */ +SList * +slist_tail (SList *slist) +{ + return slist ? slist->next : NULL; +} + +/* Return a list starting at the Nth item of SLIST. If SLIST is less + than N items long, NULL is returned. Just to be confusing, list items + are counted from 1, to get the 2nd element of slist: + + e.g. shared_list = slist_nth (slist, 2); */ +SList * +slist_nth (SList *slist, size_t n) +{ + for (;n > 1 && slist; n--) + slist = slist->next; + + return slist; +} + +/* Return the number of items in SLIST. We start counting from 1, so + the length of a list with no items is 0, and so on. */ +size_t +slist_length (SList *slist) +{ + size_t n; + + for (n = 0; slist; ++n) + slist = slist->next; + + return n; +} + +/* Destructively reverse the order of items in SLIST. The value of SLIST + is undefined after calling this function. + + CAVEAT: You must store the result of this function, or you might not + be able to get all the items except the first one back again. + + e.g. slist = slist_reverse (slist); */ +SList * +slist_reverse (SList *slist) +{ + SList *result = 0; + SList *next; + + while (slist) + { + next = slist->next; + slist->next = result; + result = slist; + slist = next; + } + + return result; +} + +/* Call FOREACH once for each item in SLIST, passing both the item and + USERDATA on each call. */ +void * +slist_foreach (SList *slist, SListCallback *foreach, void *userdata) +{ + void *result = 0; + + assert (foreach); + + while (slist) + { + SList *next = slist->next; + result = (*foreach) (slist, userdata); + + if (result) + break; + + slist = next; + } + + return result; +} + +/* Destructively merge the items of two ordered lists LEFT and RIGHT, + returning a single sorted list containing the items of both -- Part of + the quicksort algorithm. The values of LEFT and RIGHT are undefined + after calling this function. + + At each iteration, add another item to the merged list by taking the + lowest valued item from the head of either LEFT or RIGHT, determined + by passing those items and USERDATA to COMPARE. COMPARE should return + less than 0 if the head of LEFT has the lower value, greater than 0 if + the head of RIGHT has the lower value, otherwise 0. */ +static SList * +slist_sort_merge (SList *left, SList *right, SListCompare *compare, + void *userdata) +{ + SList merged, *insert; + + insert = &merged; + + while (left && right) + { + if ((*compare) (left, right, userdata) <= 0) + { + insert = insert->next = left; + left = left->next; + } + else + { + insert = insert->next = right; + right = right->next; + } + } + + insert->next = left ? left : right; + + return merged.next; +} + +/* Perform a destructive quicksort on the items in SLIST, by repeatedly + calling COMPARE with a pair of items from SLIST along with USERDATA + at every iteration. COMPARE is a function as defined above for + slist_sort_merge(). The value of SLIST is undefined after calling + this function. + + e.g. slist = slist_sort (slist, compare, 0); */ +SList * +slist_sort (SList *slist, SListCompare *compare, void *userdata) +{ + SList *left, *right; + + if (!slist) + return slist; + + /* Be sure that LEFT and RIGHT never contain the same item. */ + left = slist; + right = slist->next; + + if (!right) + return left; + + /* Skip two items with RIGHT and one with SLIST, until RIGHT falls off + the end. SLIST must be about half way along. */ + while (right && (right = right->next)) + { + if (!right || !(right = right->next)) + break; + slist = slist->next; + } + right = slist->next; + slist->next = 0; + + /* Sort LEFT and RIGHT, then merge the two. */ + return slist_sort_merge (slist_sort (left, compare, userdata), + slist_sort (right, compare, userdata), + compare, userdata); +} + + +/* Aside from using the functions above to manage chained structures of + any type that has a NEXT pointer as its first field, SLISTs can + be comprised of boxed items. The boxes are chained together in + that case, so there is no need for a NEXT field in the item proper. + Some care must be taken to slist_box and slist_unbox each item in + a boxed list at the appropriate points to avoid leaking the memory + used for the boxes. It us usually a very bad idea to mix boxed and + non-boxed items in a single list. */ + +/* Return a `boxed' freshly mallocated 1 element list containing + USERDATA. */ +SList * +slist_box (const void *userdata) +{ + SList *item = (SList *) malloc (sizeof *item); + + if (item) + { + item->next = 0; + item->userdata = userdata; + } + + return item; +} + +/* Return the contents of a `boxed' ITEM, recycling the box itself. */ +void * +slist_unbox (SList *item) +{ + void *userdata = 0; + + if (item) + { + /* Strip the const, because responsibility for this memory + passes to the caller on return. */ + userdata = (void *) item->userdata; + free (item); + } + + return userdata; +} diff --git a/ltmain.sh b/ltmain.sh new file mode 100755 index 0000000..63ae69d --- /dev/null +++ b/ltmain.sh @@ -0,0 +1,9655 @@ + +# libtool (GNU libtool) 2.4.2 +# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010, 2011 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. + +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --no-quiet, --no-silent +# print informational messages (default) +# --no-warn don't display warning messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print more informational messages than default +# --no-verbose don't print the extra informational messages +# --version print version information +# -h, --help, --help-all print short, long, or detailed help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. When passed as first option, +# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.4.2 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to <bug-libtool@gnu.org>. +# GNU libtool home page: <http://www.gnu.org/software/libtool/>. +# General help using GNU software: <http://www.gnu.org/gethelp/>. + +PROGRAM=libtool +PACKAGE=libtool +VERSION=2.4.2 +TIMESTAMP="" +package_revision=1.3337 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# NLS nuisances: We save the old values to restore during execute mode. +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL + +$lt_unset CDPATH + + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} # func_dirname may be replaced by extended shell implementation + + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} # func_basename may be replaced by extended shell implementation + + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` +} # func_dirname_and_basename may be replaced by extended shell implementation + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname may be replaced by extended shell implementation + + +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar='s,^/\([^/]*\).*$,\1,' +pathcdr='s,^/[^/]*,,' +removedotparts=':dotsl + s@/\./@/@g + t dotsl + s,/\.$,/,' +collapseslashes='s@/\{1,\}@/@g' +finalslash='s,/*$,/,' + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + +# The name of this program: +func_dirname_and_basename "$progpath" +progname=$func_basename_result + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + +# func_tr_sh +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $opt_debug + + $SED -n '/(C)/!b go + :more + /\./!{ + N + s/\n# / / + b more + } + :go + /^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $opt_debug + + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $opt_debug + + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ + p + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $opt_debug + + func_error "missing argument for $1." + exit_cmd=exit +} + + +# func_split_short_opt shortopt +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +func_split_short_opt () +{ + my_sed_short_opt='1s/^\(..\).*$/\1/;q' + my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + + func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` + func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` +} # func_split_short_opt may be replaced by extended shell implementation + + +# func_split_long_opt longopt +# Set func_split_long_opt_name and func_split_long_opt_arg shell +# variables after splitting LONGOPT at the `=' sign. +func_split_long_opt () +{ + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + + func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` + func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` +} # func_split_long_opt may be replaced by extended shell implementation + +exit_cmd=: + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +nonopt= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "${1}=\$${1}\${2}" +} # func_append may be replaced by extended shell implementation + +# func_append_quoted var value +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +func_append_quoted () +{ + func_quote_for_eval "${2}" + eval "${1}=\$${1}\\ \$func_quote_for_eval_result" +} # func_append_quoted may be replaced by extended shell implementation + + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "${@}"` +} # func_arith may be replaced by extended shell implementation + + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` +} # func_len may be replaced by extended shell implementation + + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} # func_lo2o may be replaced by extended shell implementation + + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} # func_xform may be replaced by extended shell implementation + + +# func_fatal_configuration arg... +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func_error ${1+"$@"} + func_error "See the $PACKAGE documentation for more information." + func_fatal_error "Fatal configuration error." +} + + +# func_config +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# func_enable_tag tagname +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname="$1" + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf="/$re_begincf/,/$re_endcf/p" + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# Shorthand for --mode=foo, only valid as the first argument +case $1 in +clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; +compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; +execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; +finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; +install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; +link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; +uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; +esac + + + +# Option defaults: +opt_debug=: +opt_dry_run=false +opt_config=false +opt_preserve_dup_deps=false +opt_features=false +opt_finish=false +opt_help=false +opt_help_all=false +opt_silent=: +opt_warning=: +opt_verbose=: +opt_silent=false +opt_verbose=false + + +# Parse options once, thoroughly. This comes as soon as possible in the +# script to make things like `--version' happen as quickly as we can. +{ + # this just eases exit handling + while test $# -gt 0; do + opt="$1" + shift + case $opt in + --debug|-x) opt_debug='set -x' + func_echo "enabling shell trace mode" + $opt_debug + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" + shift + ;; + --preserve-dup-deps) + opt_preserve_dup_deps=: + ;; + --features) + opt_features=: +func_features + ;; + --finish) + opt_finish=: +set dummy --mode finish ${1+"$@"}; shift + ;; + --help) + opt_help=: + ;; + --help-all) + opt_help_all=: +opt_help=': help-all' + ;; + --mode) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_mode="$optarg" +case $optarg in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; +esac + shift + ;; + --no-silent|--no-quiet) + opt_silent=false +func_append preserve_args " $opt" + ;; + --no-warning|--no-warn) + opt_warning=false +func_append preserve_args " $opt" + ;; + --no-verbose) + opt_verbose=false +func_append preserve_args " $opt" + ;; + --silent|--quiet) + opt_silent=: +func_append preserve_args " $opt" + opt_verbose=false + ;; + --verbose|-v) + opt_verbose=: +func_append preserve_args " $opt" +opt_silent=false + ;; + --tag) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_tag="$optarg" +func_append preserve_args " $opt $optarg" +func_enable_tag "$optarg" + shift + ;; + + -\?|-h) func_usage ;; + --help) func_help ;; + --version) func_version ;; + + # Separate optargs to long options: + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-n*|-v*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set dummy "$opt" ${1+"$@"}; shift; break ;; + esac + done + + # Validate options: + + # save first non-option argument + if test "$#" -gt 0; then + nonopt="$opt" + shift + fi + + # preserve --debug + test "$opt_debug" = : || func_append preserve_args " --debug" + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test "$opt_mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } + + + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} + + + + +## ----------- ## +## Main. ## +## ----------- ## + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case "$lt_sysroot:$1" in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result="=$func_stripname_result" + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T <<EOF +# $write_libobj - a libtool object file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. +pic_object=$write_lobj + +# Name of the non-PIC object +non_pic_object=$write_oldobj + +EOF + $MV "${write_libobj}T" "${write_libobj}" + } +} + + +################################################## +# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS # +################################################## + +# func_convert_core_file_wine_to_w32 ARG +# Helper function used by file name conversion functions when $build is *nix, +# and $host is mingw, cygwin, or some other w32 environment. Relies on a +# correctly configured wine environment available, with the winepath program +# in $build's $PATH. +# +# ARG is the $build file name to be converted to w32 format. +# Result is available in $func_convert_core_file_wine_to_w32_result, and will +# be empty on error (or when ARG is empty) +func_convert_core_file_wine_to_w32 () +{ + $opt_debug + func_convert_core_file_wine_to_w32_result="$1" + if test -n "$1"; then + # Unfortunately, winepath does not exit with a non-zero error code, so we + # are forced to check the contents of stdout. On the other hand, if the + # command is not found, the shell will set an exit code of 127 and print + # *an error message* to stdout. So we must check for both error code of + # zero AND non-empty stdout, which explains the odd construction: + func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null` + if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$lt_sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $opt_debug + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result="" + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $opt_debug + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $opt_debug + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $opt_debug + if test -z "$2" && test -n "$1" ; then + func_error "Could not determine host file name corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result="$1" + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $opt_debug + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " \`$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result="$3" + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $opt_debug + case $4 in + $1 ) func_to_host_path_result="$3$func_to_host_path_result" + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via `$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $opt_debug + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $opt_debug + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result="$1" +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result="$func_convert_core_msys_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via `$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $opt_debug + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd="func_convert_path_${func_stripname_result}" + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $opt_debug + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result="$1" +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_append_quoted lastarg "$arg" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with \`-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj="$func_basename_result" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$opt_mode'" + ;; + esac + + echo + $ECHO "Try \`$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test "$opt_help" = :; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | sed -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "\`$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument \`$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test "$opt_mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename="" + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname" ; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename="$func_basename_result" + else + # no lafile. user explicitly requested -dlpreopen <import library>. + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename" ; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 </dev/null >/dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $opt_debug + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $opt_debug + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive which possess that section. Heuristic: eliminate + # all those which have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $opt_debug + if func_cygming_gnu_implib_p "$1" ; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1" ; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result="" + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + if test "$lock_old_archive_extraction" = yes; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test "$lock_old_archive_extraction" = yes; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat <<EOF + +/* $cwrappersource - temporary wrapper executable for $objdir/$outputname + Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION + + The $output program cannot be directly executed until all the libtool + libraries that it depends on are installed. + + This wrapper executable should never be moved out of the build directory. + If it is, it will not operate correctly. +*/ +EOF + cat <<"EOF" +#ifdef _MSC_VER +# define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#include <stdio.h> +#include <stdlib.h> +#ifdef _MSC_VER +# include <direct.h> +# include <process.h> +# include <io.h> +#else +# include <unistd.h> +# include <stdint.h> +# ifdef __CYGWIN__ +# include <io.h> +# endif +#endif +#include <malloc.h> +#include <stdarg.h> +#include <assert.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined(__CYGWIN__) +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined (other platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# ifndef _INTPTR_T_DEFINED +# define _INTPTR_T_DEFINED +# define intptr_t int +# endif +#elif defined(__MINGW32__) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined(__CYGWIN__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <<EOF +volatile const char * MAGIC_EXE = "$magic_exe"; +const char * LIB_PATH_VARNAME = "$shlibpath_var"; +EOF + + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + func_to_host_path "$temp_rpath" + cat <<EOF +const char * LIB_PATH_VALUE = "$func_to_host_path_result"; +EOF + else + cat <<"EOF" +const char * LIB_PATH_VALUE = ""; +EOF + fi + + if test -n "$dllsearchpath"; then + func_to_host_path "$dllsearchpath:" + cat <<EOF +const char * EXE_PATH_VARNAME = "PATH"; +const char * EXE_PATH_VALUE = "$func_to_host_path_result"; +EOF + else + cat <<"EOF" +const char * EXE_PATH_VARNAME = ""; +const char * EXE_PATH_VALUE = ""; +EOF + fi + + if test "$fast_install" = yes; then + cat <<EOF +const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */ +EOF + else + cat <<EOF +const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */ +EOF + fi + + + cat <<"EOF" + +#define LTWRAPPER_OPTION_PREFIX "--lt-" + +static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX; +static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script"; +static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug"; + +int +main (int argc, char *argv[]) +{ + char **newargz; + int newargc; + char *tmp_pathspec; + char *actual_cwrapper_path; + char *actual_cwrapper_name; + char *target_name; + char *lt_argv_zero; + intptr_t rval = 127; + + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + newargz = XMALLOC (char *, argc + 1); + + /* very simple arg parsing; don't want to rely on getopt + * also, copy all non cwrapper options to newargz, except + * argz[0], which is handled differently + */ + newargc=0; + for (i = 1; i < argc; i++) + { + if (strcmp (argv[i], dumpscript_opt) == 0) + { +EOF + case "$host" in + *mingw* | *cygwin* ) + # make stdout use "unix" line endings + echo " setmode(1,_O_BINARY);" + ;; + esac + + cat <<"EOF" + lt_dump_script (stdout); + return 0; + } + if (strcmp (argv[i], debug_opt) == 0) + { + lt_debug = 1; + continue; + } + if (strcmp (argv[i], ltwrapper_option_prefix) == 0) + { + /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX + namespace, but it is not one of the ones we know about and + have already dealt with, above (inluding dump-script), then + report an error. Otherwise, targets might begin to believe + they are allowed to use options in the LTWRAPPER_OPTION_PREFIX + namespace. The first time any user complains about this, we'll + need to make LTWRAPPER_OPTION_PREFIX a configure-time option + or a configure.ac-settable value. + */ + lt_fatal (__FILE__, __LINE__, + "unrecognized %s option: '%s'", + ltwrapper_option_prefix, argv[i]); + } + /* otherwise ... */ + newargz[++newargc] = xstrdup (argv[i]); + } + newargz[++newargc] = NULL; + +EOF + cat <<EOF + /* The GNU banner must be the first non-error debug message */ + lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n"); +EOF + cat <<"EOF" + lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]); + lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name); + + tmp_pathspec = find_executable (argv[0]); + if (tmp_pathspec == NULL) + lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]); + lt_debugprintf (__FILE__, __LINE__, + "(main) found exe (before symlink chase) at: %s\n", + tmp_pathspec); + + actual_cwrapper_path = chase_symlinks (tmp_pathspec); + lt_debugprintf (__FILE__, __LINE__, + "(main) found exe (after symlink chase) at: %s\n", + actual_cwrapper_path); + XFREE (tmp_pathspec); + + actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path)); + strendzap (actual_cwrapper_path, actual_cwrapper_name); + + /* wrapper name transforms */ + strendzap (actual_cwrapper_name, ".exe"); + tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1); + XFREE (actual_cwrapper_name); + actual_cwrapper_name = tmp_pathspec; + tmp_pathspec = 0; + + /* target_name transforms -- use actual target program name; might have lt- prefix */ + target_name = xstrdup (base_name (TARGET_PROGRAM_NAME)); + strendzap (target_name, ".exe"); + tmp_pathspec = lt_extend_str (target_name, ".exe", 1); + XFREE (target_name); + target_name = tmp_pathspec; + tmp_pathspec = 0; + + lt_debugprintf (__FILE__, __LINE__, + "(main) libtool target name: %s\n", + target_name); +EOF + + cat <<EOF + newargz[0] = + XMALLOC (char, (strlen (actual_cwrapper_path) + + strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1)); + strcpy (newargz[0], actual_cwrapper_path); + strcat (newargz[0], "$objdir"); + strcat (newargz[0], "/"); +EOF + + cat <<"EOF" + /* stop here, and copy so we don't have to do this twice */ + tmp_pathspec = xstrdup (newargz[0]); + + /* do NOT want the lt- prefix here, so use actual_cwrapper_name */ + strcat (newargz[0], actual_cwrapper_name); + + /* DO want the lt- prefix here if it exists, so use target_name */ + lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1); + XFREE (tmp_pathspec); + tmp_pathspec = NULL; +EOF + + case $host_os in + mingw*) + cat <<"EOF" + { + char* p; + while ((p = strchr (newargz[0], '\\')) != NULL) + { + *p = '/'; + } + while ((p = strchr (lt_argv_zero, '\\')) != NULL) + { + *p = '/'; + } + } +EOF + ;; + esac + + cat <<"EOF" + XFREE (target_name); + XFREE (actual_cwrapper_path); + XFREE (actual_cwrapper_name); + + lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */ + lt_setenv ("DUALCASE", "1"); /* for MSK sh */ + /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must + be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath) + because on Windows, both *_VARNAMEs are PATH but uninstalled + libraries must come first. */ + lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE); + lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE); + + lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n", + nonnull (lt_argv_zero)); + for (i = 0; i < newargc; i++) + { + lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n", + i, nonnull (newargz[i])); + } + +EOF + + case $host_os in + mingw*) + cat <<"EOF" + /* execv doesn't actually work on mingw as expected on unix */ + newargz = prepare_spawn (newargz); + rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); + if (rval == -1) + { + /* failed to start process */ + lt_debugprintf (__FILE__, __LINE__, + "(main) failed to launch target \"%s\": %s\n", + lt_argv_zero, nonnull (strerror (errno))); + return 127; + } + return rval; +EOF + ;; + *) + cat <<"EOF" + execv (lt_argv_zero, newargz); + return rval; /* =127, but avoids unused variable warning */ +EOF + ;; + esac + + cat <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void *p = (void *) malloc (num); + if (!p) + lt_fatal (__FILE__, __LINE__, "memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), + string) : NULL; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char) name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable (const char *path) +{ + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps ; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + else + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test "$prefer_static_libs" = yes || + test "$prefer_static_libs,$installed" = "built,no"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib="$l" + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$lt_sysroot$libdir" + absdir="$lt_sysroot$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + case "$host" in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$opt_mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$absdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$opt_mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|qnx|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + func_append verstring ":${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + func_append libobjs " $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$opt_mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c <<EOF + int main() { return 0; } +EOF + $opt_dry_run || $RM conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then + ldd_output=`ldd conftest` + for i in $deplibs; do + case $i in + -l*) + func_stripname -l '' "$i" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $i "*) + func_append newdeplibs " $i" + i="" + ;; + esac + fi + if test -n "$i" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` + set dummy $deplib_matches; shift + deplib_match=$1 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + func_append newdeplibs " $i" + else + droppeddeps=yes + echo + $ECHO "*** Warning: dynamic linker does not accept needed library $i." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which I believe you do not have" + echo "*** because a test_compile did reveal that the linker did not use it for" + echo "*** its dynamic dependency list that programs get resolved with at runtime." + fi + fi + ;; + *) + func_append newdeplibs " $i" + ;; + esac + done + else + # Error occurred in the first compile. Let's try to salvage + # the situation: Compile a separate program for each library. + for i in $deplibs; do + case $i in + -l*) + func_stripname -l '' "$i" + name=$func_stripname_result + $opt_dry_run || $RM conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $i; then + ldd_output=`ldd conftest` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $i "*) + func_append newdeplibs " $i" + i="" + ;; + esac + fi + if test -n "$i" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` + set dummy $deplib_matches; shift + deplib_match=$1 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + func_append newdeplibs " $i" + else + droppeddeps=yes + echo + $ECHO "*** Warning: dynamic linker does not accept needed library $i." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because a test_compile did reveal that the linker did not use this one" + echo "*** as a dynamic dependency that programs can get resolved with at runtime." + fi + fi + else + droppeddeps=yes + echo + $ECHO "*** Warning! Library $i is needed by this library but I was not able to" + echo "*** make it link in! You will probably need to install it or some" + echo "*** library that it depends on before this library will be fully" + echo "*** functional. Installing it before continuing would be even better." + fi + ;; + *) + func_append newdeplibs " $i" + ;; + esac + done + fi + ;; + file_magic*) + set dummy $deplibs_check_method; shift + file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + if test -n "$file_magic_glob"; then + libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob` + else + libnameglob=$libname + fi + test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + if test "$want_nocaseglob" = yes; then + shopt -s nocaseglob + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + # Remove ${wl} instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd1 in $cmds; do + IFS="$save_ifs" + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test "$try_normal_branch" = yes \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=${output_objdir}/${output_la}.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + func_append oldobjs " $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + func_resolve_sysroot "$deplib" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + odir="$objdir" + else + odir="$dir/$objdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$opt_mode" = uninstall && odir="$dir" + + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case "$opt_mode" in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$opt_mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + func_append rmfiles " $odir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$opt_mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/messages/Makefile.am b/messages/Makefile.am new file mode 100644 index 0000000..5490cc5 --- /dev/null +++ b/messages/Makefile.am @@ -0,0 +1,21 @@ +AUTOMAKE_OPTIONS = foreign +messagesdir = $(pkgdatadir)/messages + +dist_messages_DATA = ayb.lang \ + custom.lang \ + ircd-brazilian_pt.lang \ + ircd-bulgarian.lang \ + ircd-croatian.lang \ + ircd-danish.lang \ + ircd-dutch.lang \ + ircd-french.lang \ + ircd-german.lang \ + ircd-italian.lang \ + ircd-norwegian.lang \ + ircd-polish.lang \ + ircd-romanian.lang \ + ircd-russian.lang \ + ircd-spanish.lang \ + ircd-swedish.lang + +messages: $(dist_messages_DATA) diff --git a/messages/Makefile.in b/messages/Makefile.in new file mode 100644 index 0000000..15f362b --- /dev/null +++ b/messages/Makefile.in @@ -0,0 +1,482 @@ +# Makefile.in generated by automake 1.12.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = messages +DIST_COMMON = README $(dist_messages_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(messagesdir)" +DATA = $(dist_messages_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBDIR = @LIBDIR@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PREFIX = @PREFIX@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +messagesdir = $(pkgdatadir)/messages +dist_messages_DATA = ayb.lang \ + custom.lang \ + ircd-brazilian_pt.lang \ + ircd-bulgarian.lang \ + ircd-croatian.lang \ + ircd-danish.lang \ + ircd-dutch.lang \ + ircd-french.lang \ + ircd-german.lang \ + ircd-italian.lang \ + ircd-norwegian.lang \ + ircd-polish.lang \ + ircd-romanian.lang \ + ircd-russian.lang \ + ircd-spanish.lang \ + ircd-swedish.lang + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign messages/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign messages/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-dist_messagesDATA: $(dist_messages_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_messages_DATA)'; test -n "$(messagesdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(messagesdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(messagesdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(messagesdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(messagesdir)" || exit $$?; \ + done + +uninstall-dist_messagesDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_messages_DATA)'; test -n "$(messagesdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(messagesdir)'; $(am__uninstall_files_from_dir) +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(messagesdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-dist_messagesDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_messagesDATA + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_messagesDATA \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am uninstall uninstall-am uninstall-dist_messagesDATA + + +messages: $(dist_messages_DATA) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/messages/README b/messages/README new file mode 100644 index 0000000..b62a162 --- /dev/null +++ b/messages/README @@ -0,0 +1,45 @@ +Translated message files (user/admin submitted) + +There are user submitted message files for ircd-hybrid-8. Read the +example file in this directory (ircd-standard.example.lang) and the file +doc/messages.txt to learn how to create, install, and possibly submit +your own .lang files. + +At the present time, the following languages are supported: + +brazilian portuguese - maintained by Marcelo Lipienski <und3rl1n3d@gmail.com> +swedish - maintained by trbz - Chris C <chris@mircscripter.com> +croatian - maintained by Martin - Vid Strpic <strpic@bofhlet.net> +french - maintained by joshk - Joshua Kwan <joshk@triplehelix.org> +german - maintained by dmalloc - Darian Lanx <bio@gmx.net> +italian - maintained by Afaa - Federico Giovannini <afaa@ircd-hybrid.it> +norwegian - maintained by inglish - Stephen Olsen <inglish@sol.no> +danish - maintained by Xride - Soren Straarup Andersen <xride@eit.ihk-edu.dk> +spanish - maintained by ermak - anonymous <ermak@cyberdude.com> +dutch - maintained by Riedel - Dennis Vink <vink@vuurwerk.nl> +polish - maintained by adx - Piotr Nizynski <adx@irc7.pl> +russian - maintained by Ilya - Ilya Shtift <ishtift@tagil.svrw.ru> +romanian - maintained by Bogdan Mintoi <bogdomania@yahoo.com> + +All of the files are installed into the prefix directory, under messages. +Each is installed into a different directory, prefixed by ircd-. + +The message locale is settable at runtime with /quote SET MSGLOCALE language, +ex. /quote SET MSGLOCALE ircd-german + +and via the message_locale="language"; in the general block of the ircd.conf. +ex. message_locale="ircd-german"; + +-- +The ircd-hybrid team is not accountable for any mistakes, mistranslations, or +accidental insults from the use of one of the included translations. All +translations are done by individuals who have given their time and skills to +provide localized users with pre-built translations. The ircd-hybrid team +will try, but cannot guarantee that the translations are up to date with the +rest of the source tree, and with the "customized" messages. + +Contributions are welcome, at present time please send contributed translations +to bugs@ircd-hybrid.org, hybrid@ircd-hybrid.org, or directly to one of the people +who work with the translations. + +$Id$ diff --git a/messages/ayb.lang b/messages/ayb.lang new file mode 100644 index 0000000..4dfc928 --- /dev/null +++ b/messages/ayb.lang @@ -0,0 +1,29 @@ +; ircd-hybrid-7 custom message file +; Copyright (C) 2000 +; David Taylor <davidt@yadt.co.uk>, 2000. +; $Id$ + +RPL_WELCOME: :%s 001 %s :ALL YOUR BASE ARE BELONG TO %s, %s!!! +RPL_CREATED: :%s 003 %s :Someone set up us the server %s +RPL_ISUPPORT: :%s 005 %s %s :are moved for great justice +RPL_REDIR: :%s 010 %s %s %d :You have no chance to survive make this Server/Port instead. Ha ha ha. +RPL_STATSUPTIME: :%s 242 %s :Someone set up us the bomb %d days, %d:%02d:%02d ago +RPL_LUSERCLIENT: :%s 251 %s :There are %d minor Zigs and %d invisible on %d servers +RPL_LUSEROP: :%s 252 %s %d :Zigs online +RPL_LUSERME: :%s 255 %s :%d clients and %d servers are belong to me +RPL_LOAD2HI: :%s 263 %s :What you say!?? The server is moving too many zigs.. +RPL_LOCALUSERS: :%s 265 %s :%d users (max %d) are belong to me +RPL_GLOBALUSERS: :%s 266 %s :%d users (max %d) are belong to the network +RPL_UNAWAY: :%s 305 %s :OK, you're not /away anymore. Did you move Zig for great justice? +RPL_NOWAWAY: :%s 306 %s :OK, you're /away now. Hurry back! +RPL_YOUREOPER: :%s 381 %s :SOMEONE SET YOU UP THE /KILL FOR GREAT JUSTICE! +ERR_NOSUCHNICK: :%s 401 %s %s :No such Zig +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Too many channels are belong to you +ERR_WASNOSUCHNICK: :%s 406 %s %s :There was no such Zig +ERR_TOOMANYTARGETS: :%s 407 %s %s :Too many recipients. Your message is only belong to %d +ERR_NORECIPIENT: :%s 411 %s :No Zigs Moved (%s) +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :THAT COMMAND IS NOT BELONG TO ME!!! +ERR_NOMOTD: :%s 422 %s :MOTD file is not belong to me +ERR_NICKNAMEINUSE: :%s 433 %s %s :Zig is belong to someone else. +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :You know what you doing, you need +o +ERR_CANTKILLSERVER: :%s 483 %s :You have no chance to kill a SERVER make your time. diff --git a/messages/custom.lang b/messages/custom.lang new file mode 100644 index 0000000..c644d97 --- /dev/null +++ b/messages/custom.lang @@ -0,0 +1,20 @@ +; A compilation of original h5/h6/bsdnet numerics +; $Id$ + +RPL_CREATED: :%s 003 %s :This server rose from the ashes %s +RPL_STATSUPTIME: :%s 242 %s :Dianora hasn't messed with the server code now in %d days, %d:%02d:%02d +RPL_LUSEROP: :%s 252 %s %d :Smurf Targets (IRC Operators) online +RPL_LOAD2HI: :%s 263 %s :Hold your horses... the server load is temporarily too heavy. Try again later, ok? +RPL_UNAWAY: :%s 305 %s :OK, you're not /away anymore. Did you have fun? +RPL_NOWAWAY: :%s 306 %s :OK, you're /away now. Hurry back! +RPL_WHOISOPERATOR: :%s 313 %s %s :is a Smurf Target (IRC Operator) +RPL_WHOISADMIN: :%s 313 %s %s :is a Smurf Magnet (IRC Administrator) +RPL_YOUREOPER: :%s 381 %s :You have the phorce. Use it wisely. +RPL_REHASHING: :%s 382 %s %s :it slices, dices, and even reloads config files! Rehashing config file, mang. +ERR_PASSWDMISMATCH: :%s 464 %s :BZZZT!! Wrong password, dewd. Are you sure you know what you're doing? +ERR_YOUREBANNEDCREEP: :%s 465 %s :You are BANNED from this server - %s +ERR_NOPRIVILEGES: :%s 481 %s :UHHH, I don't THINK so, dewd... you ain't got those mad l33+ sk1llz. (IRC Operator) +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :You can't do that thing, when you don't have that swing (You're not channel operator) +ERR_CANTKILLSERVER: :%s 483 %s :Don't be an idiot - you can't kill a SERVER, fool. +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :Unknown MODE flag - you smokin' something? +ERR_USERSDONTMATCH: :%s 502 %s :You can't change user modes for other users, silly - check that nickname again. diff --git a/messages/ircd-brazilian_pt.lang b/messages/ircd-brazilian_pt.lang new file mode 100644 index 0000000..204b0de --- /dev/null +++ b/messages/ircd-brazilian_pt.lang @@ -0,0 +1,127 @@ +; ircd-hybrid-7 custom message file +; Copyright (C) 2003 +; Marcelo Lipienski <und3rl1n3d@gmail.com> +; $Id$ + +RPL_WELCOME: :%s 001 %s :Bem-vindo a %s Internet Relay Chat Network %s +RPL_YOURHOST: :%s 002 %s :Você está no servidor %s, rodando a versão %s +RPL_CREATED: :%s 003 %s :Este servidor foi criado %s +RPL_ISUPPORT: :%s 005 %s %s :são suportados por este servidor +RPL_REDIR: :%s 010 %s %s %d :Por favor use este Servidor/Porta +RPL_MAPEND: :%s 017 %s :Fim do /MAP +RPL_YOURID: :%s 042 %s %s :seu ID +RPL_TRACELINK: :%s 200 %s Link %s %s %s +RPL_TRACECONNECTING: :%s 201 %s Tente. %s %s +RPL_TRACEHANDSHAKE: :%s 202 %s H.S. %s %s +RPL_TRACEUNKNOWN: :%s 203 %s ???? %s %s (%s) %d +RPL_TRACEOPERATOR: :%s 204 %s Oper %s %s (%s) %lu %lu +RPL_TRACEUSER: :%s 205 %s Usuário %s %s (%s) %lu %lu +RPL_TRACESERVER: :%s 206 %s Serv %s %dS %dC %s %s!%s@%s %lu +RPL_TRACENEWTYPE: :%s 208 %s <novo tipo> 0 %s +RPL_TRACECLASS: :%s 209 %s Classe %s %d +RPL_ENDOFSTATS: :%s 219 %s %c :Fim do relatório do /STATS +RPL_STATSUPTIME: :%s 242 %s :Servidor ligado %d dias, %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :Máximo de conexões: %d (%d clientes) (%llu conexões recebidas) +RPL_LUSERCLIENT: :%s 251 %s :Existem %d usuários e %d invisíveis em %d servidores +RPL_LUSEROP: :%s 252 %s %d :Operadores do IRC conectados +RPL_LUSERUNKNOWN: :%s 253 %s %d :conexão(ões) desconhecidas +RPL_LUSERCHANNELS: :%s 254 %s %d :canais criados +RPL_LUSERME: :%s 255 %s :Eu tenho %d clientes e %d servidores +RPL_ADMINME: :%s 256 %s :Informações administrativas sobre %s +RPL_ENDOFTRACE: :%s 262 %s %s :Fim do /TRACE +RPL_LOAD2HI: :%s 263 %s :O servidor está temporariamente sobrecarregado. Por favor aguarde e tente novamente. +RPL_LOCALUSERS: :%s 265 %s :Usuários locais atualmente: %d Máximo: %d +RPL_GLOBALUSERS: :%s 266 %s :Usuários globais atualmente: %d Máximo: %d +RPL_ENDOFACCEPT: :%s 282 %s :Fim da lista /ACCEPT. +RPL_UNAWAY: :%s 305 %s :Você não está mais marcado como away +RPL_NOWAWAY: :%s 306 %s :Você foi marcado como estando away +RPL_WHOISADMIN: :%s 313 %s %s :é um Administrador do Servidor +RPL_WHOISOPERATOR: :%s 313 %s %s :é um Operador do IRC +RPL_ENDOFWHO: :%s 315 %s %s :Fim do /WHO. +RPL_WHOISIDLE: :%s 317 %s %s %d %d :segundos inativo +RPL_ENDOFWHOIS: :%s 318 %s %s :Fim do /WHOIS. +RPL_LISTSTART: :%s 321 %s Canal :Usuário Nome +RPL_LISTEND: :%s 323 %s :Fim do /LIST +RPL_NOTOPIC: :%s 331 %s %s :Nenhum tópico setado. +RPL_WHOISACTUALLY: :%s 338 %s %s %s :servidor atualmente sendo usado +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Fim da lista de convidados do canal +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Fim da lista de exceções do canal +RPL_CLOSING: :%s 362 %s %s :Fechado. Status = %d +RPL_CLOSEEND: :%s 363 %s %d: Conexões fechadas +RPL_ENDOFLINKS: :%s 365 %s %s :Fim do /LINKS. +RPL_ENDOFNAMES: :%s 366 %s %s :Fim do /NAMES. +RPL_ENDOFBANLIST: :%s 368 %s %s :Fim da lista de banidos do canal +RPL_ENDOFWHOWAS: :%s 369 %s %s :Fim do /WHOWAS +RPL_INFOSTART: :%s 373 %s :Informações do servidor +RPL_ENDOFINFO: :%s 374 %s :Fim do /INFO +RPL_MOTDSTART: :%s 375 %s :- %s Mensagem do dia - +RPL_ENDOFMOTD: :%s 376 %s :Fim do /MOTD. +RPL_YOUREOPER: :%s 381 %s :Você entrou... na Zona do Crepúsculo! +RPL_REHASHING: :%s 382 %s %s :Recarregando +RPL_HOSTHIDDEN: :%s 396 %s :agora seu host está escondido +ERR_NOSUCHNICK: :%s 401 %s %s :Nenhum canal/nick +ERR_NOSUCHSERVER: :%s 402 %s %s :Nenhum servidor +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Nenhum canal +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Não pode enviar para o canal +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Você está em muitos canais +ERR_WASNOSUCHNICK: :%s 406 %s %s :Não existe este nick +ERR_TOOMANYTARGETS: :%s 407 %s %s :Muitos destinos. Somente %d processados +ERR_NOORIGIN: :%s 409 %s :Nenhuma origem especificada +ERR_NORECIPIENT: :%s 411 %s :Nenhum destino especificado (%s) +ERR_NOTEXTTOSEND: :%s 412 %s :Nenhum texto para mandar +ERR_NOTOPLEVEL: :%s 413 %s %s :Nenhum domínio de nível auto especificado +ERR_WILDTOPLEVEL: :%s 414 %s %s :Coringa no domínio de nível auto +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Comando desconhecido +ERR_NOMOTD: :%s 422 %s :Arquivo MOTD faltando +ERR_NOADMININFO: :%s 423 %s %s :Nenhuma informação administrativa +ERR_NONICKNAMEGIVEN: :%s 431 %s :Nenhum nick informado +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Nick errado +ERR_NICKNAMEINUSE: :%s 433 %s %s :Nick já está em uso. +ERR_NICKCOLLISION: :%s 436 %s %s :Colisão de nicks KILL +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Nick/canal está temporariamente indisponível +ERR_NICKTOOFAST: :%s 438 %s %s %s :Mudança de nick muito rápida. Por favor, espere %d segundos. +ERR_SERVICESDOWN: :%s 440 %s :Serviços estão atualmente fora do ar. +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :Eles não estão naquele canal +ERR_NOTONCHANNEL: :%s 442 %s %s :Você não está naquele canal +ERR_USERONCHANNEL: :%s 443 %s %s %s :já está no canal +ERR_NOTREGISTERED: :%s 451 %s :Você não está registrado +ERR_ACCEPTFULL: :%s 456 %s :Lista de aceitos está cheia +ERR_ACCEPTEXIST: :%s 457 %s %s :já está na sua lista de aceitos +ERR_ACCEPTNOT: :%s 458 %s %s :não está em sua lista de aceitos +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Parâmetros insuficientes +ERR_ALREADYREGISTRED: :%s 462 %s :Você não deve se re-registrar +ERR_PASSWDMISMATCH: :%s 464 %s :Senha incorreta +ERR_YOUREBANNEDCREEP: :%s 465 %s :Você está banido deste servidor- %s +ERR_CHANNELISFULL: :%s 471 %s %s :Não pode entrar no canal (+l) +ERR_UNKNOWNMODE: :%s 472 %s %c :é um modo desconhecido para mim +ERR_INVITEONLYCHAN: :%s 473 %s %s :Não pode entrar no canal (+i) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Não pode entrar no canal (+b) +ERR_BADCHANNELKEY: :%s 475 %s %s :Não pode entrar no canal (+k) +ERR_BANLISTFULL: :%s 478 %s %s %s :Lista de banidos do canal está cheia +ERR_BADCHANNAME: :%s 479 %s %s :Nome de canal ilegal +ERR_NOPRIVILEGES: :%s 481 %s :Permissão negada - Você não é um Operador de IRC +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Você não é um operador do canal +ERR_CANTKILLSERVER: :%s 483 %s :Você não pode dar KILL em um servidor! +ERR_RESTRICTED: :%s 484 %s :Você está restrito +ERR_NOOPERHOST: :%s 491 %s :Só alguns meros mortais devem tentar entrar na Zona do Crepúsculo +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :Parâmetro do MODE desconhecida +ERR_USERSDONTMATCH: :%s 502 %s :Não pode alterar os modos de outros usuários +ERR_GHOSTEDCLIENT: :%s 503 %s :Mensagem não pode ser entregue para %s +ERR_USERNOTONSERV: :%s 504 %s %s :Usuário não está neste servidor +ERR_WRONGPONG: :%s 513 %s :Para conectar, digite /QUOTE PONG %lu +ERR_LISTSYNTAX: :%s 521 %s :Sintaxe má formada para lista +ERR_HELPNOTFOUND: :%s 524 %s %s :Ajuda não encontrada +RPL_WHOISSECURE: :%s 671 %s %s :é conectado via SSL (link seguro) +RPL_ENDOFMODLIST: :%s 703 %s :Fim de /MODLIST. +RPL_ENDOFHELP: :%s 706 %s %s :Fim de /HELP. +RPL_KNOCK: :%s 710 %s %s %s!%s@%s :pediu por um convite. +RPL_KNOCKDLVR: :%s 711 %s %s :Seu KNOCK foi enviado. +ERR_TOOMANYKNOCK: :%s 712 %s %s :Muitos KNOCKs (%s). +ERR_CHANOPEN: :%s 713 %s %s :Canal está aberto. +ERR_KNOCKONCHAN: :%s 714 %s %s :Você já está no canal. +RPL_TARGUMODEG: :%s 716 %s :%s está com o modo +g (lado do servidor ignora.) +RPL_TARGNOTIFY: :%s 717 %s :%s foram informados que você enviou uma mensagem para eles. +RPL_UMODEGMSG: :%s 718 %s %s :está mandando uma mensagem para você, e você está com o modo +g. +ERR_NOPRIVS: :%s 723 %s %s :Privilégios de oper insuficientes. +RPL_TESTMASK: :%s 724 %s %s!%s@%s %u %u :Clientes local/remote batem. +RPL_NOTESTLINE: :%s 726 %s %s :Não encontrado diff --git a/messages/ircd-bulgarian.lang b/messages/ircd-bulgarian.lang new file mode 100644 index 0000000..45b39af --- /dev/null +++ b/messages/ircd-bulgarian.lang @@ -0,0 +1,99 @@ +; ircd-hybrid-7 custom message file +; Copyright (C) 2010 Bulgarian interface +; Borislav Borisov <VoodooServ@mail.bg>, 2010. +; $Id$ + +RPL_WELCOME: :%s 001 %s :Äîáðe äîøúë â %s ìðåæàòà %s +RPL_YOURHOST: :%s 002 %s :Âàøèÿ ñúðâúð %s, âåðñèÿ %s +RPL_CREATED: :%s 003 %s :Ñúðâúðà å ñúçäàäåí %s +RPL_ISUPPORT: :%s 005 %s %s :ñúâìåñòèì +RPL_REDIR: :%s 010 %s %s %d :Æåëàòåëíî å äà ïîëçâàòå òîçè ñúðâúð/ïîðò +RPL_MAPEND: :%s 017 %s :Êðàé íà /MAP +RPL_YOURID: :%s 042 %s %s :âàøèÿò óíèêàëåí ID +RPL_ENDOFSTATS: :%s 219 %s %c :Êðàé íà îò÷åòà /STATS +RPL_STATSUPTIME: :%s 242 %s :Ñúðâúðà ðàáîòè %d äåíà, %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :Íàé ãîëÿìî êîëè÷åñòâî ñâúðçàíè: %d (%d êëèåíòè) (%llu âõîäÿùè ñâúðçâàíèÿ) +RPL_LUSERCLIENT: :%s 251 %s : ìîìåíòà èìà %d ïîòðåáèòåëÿ %d íåâèäèìè íà %d ñúðâúðà +RPL_LUSEROP: :%s 252 %s %d :IRC Îïúðè íà ëèíèÿ +RPL_LUSERUNKNOWN: :%s 253 %s %d :íåèçâåñòíè ñâðúçêè +RPL_LUSERCHANNELS: :%s 254 %s %d :ñôîðìèðàíè êàíàëè +RPL_LUSERME: :%s 255 %s :Ñúðâúðà èìà %d êëèåíòè è %d ñúðâúðè +RPL_ADMINME: :%s 256 %s :Èíôîðìàöèÿ çà àäìèíèñòðàòîðà íà %s +RPL_ENDOFTRACE: :%s 262 %s %s :Çàâúðøâàíå íà TRACE +RPL_LOAD2HI: :%s 263 %s :Ñúðâúðà âðåìåííî å ïðåòîâàðåí. Ìîëÿ èç÷àêàéòå ìîìåíò è îïèòàèòå îòíîâî. +RPL_LOCALUSERS: :%s 265 %s :Òåêóùî êîëè÷åñòâî ëîêàëíè ïîòðåáèòåëè: %d Ìàêñèìàëíî: %d +RPL_GLOBALUSERS: :%s 266 %s :Òåêóùî êîëè÷åñòâî ãëîáàëíè ïîòðåáèòåëè: %d Ìàêñèìàëíî: %d +RPL_UNAWAY: :%s 305 %s :Âå÷å íå ñòå ìàðêèðàí êàòî away +RPL_NOWAWAY: :%s 306 %s :Ìàðêèðàí ñòå êàòî away +RPL_WHOISADMIN: :%s 313 %s %s :å Ñúðâúð Àäìèíèñòðàòîð +RPL_ENDOFWHO: :%s 315 %s %s :Êðàé íà ñïèñúêà /WHO +RPL_WHOISIDLE: :%s 317 %s %s %d %d :ñåêóíäè ìúë÷è (IDLE). +RPL_ENDOFWHOIS: :%s 318 %s %s :Êðàé íà ñïèñúêà /WHOIS. +RPL_LISTEND: :%s 323 %s :Êðàé íà ñïèñúêà /LIST +RPL_NOTOPIC: :%s 331 %s %s :Íÿìà ïîñòàâåí òîïèê. +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Êðàé íà ñïèñúêà íà ïîêàíåíè â êàíàëà. +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Êðàé íà ñïèñúêà ñ èçêëþ÷åíèÿ â êàíàëà. +RPL_CLOSING: :%s 362 %s %s :Çàòâîðåí. Ñòàòóñ = %d +RPL_CLOSEEND: :%s 363 %s %d :Âðúçêàòà çàòâîðåíà +RPL_ENDOFLINKS: :%s 365 %s %s :Êðàé íà ñïèñúêà /LINKS. +RPL_ENDOFNAMES: :%s 366 %s %s :Êðàé íà ñïèñúêà /NAMES. +RPL_ENDOFBANLIST: :%s 368 %s %s :Êðàé íà ñïèñúêà íà áàííàòè â Êàíàëà +RPL_ENDOFWHOWAS: :%s 369 %s %s :Êðàé íà WHOWAS +RPL_ENDOFINFO: :%s 374 %s :Êðàé íà ñïèñúêà /INFO +RPL_MOTDSTART: :%s 375 %s :- %s Èíôî çà äåíÿ - +RPL_ENDOFMOTD: :%s 376 %s :Êðàé íà /MOTD. +RPL_YOUREOPER: :%s 381 %s :Âèå âëåçíàõòå â ... Çîíàòà Íà Çäðà÷à! +RPL_REHASHING: :%s 382 %s %s :Ïðåïðî÷èòàíå íà ôàéëà ñ íàñòðîéêè íà ñúðâúðà. +ERR_NOSUCHNICK: :%s 401 %s %s :Íèê/êàíàë íå å íàìåðåí +ERR_NOSUCHSERVER: :%s 402 %s %s :Ñúðâúðà íå å íàìåðåí +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Êàíàëà íå å íàìåðåí +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Íåâúçìîæíî äà ñå ïðàòè â êàíàëà +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Âèå ñòå âëåçëè â ïðåêàëåíî ãîëÿìî êîëè÷åñòâî êàíàëè +ERR_WASNOSUCHNICK: :%s 406 %s %s :Íå å îòêðèò òàêúâ íèê +ERR_NOORIGIN: :%s 409 %s :Èñòî÷íèêà íå å èçâåñòåí +ERR_NOTEXTTOSEND: :%s 412 %s :Íÿìà òåêñò çà ïðàùàíå +ERR_NOTOPLEVEL: :%s 413 %s %s :Íå å óêàçàí äîìåí... +ERR_WILDTOPLEVEL: :%s 414 %s %s :Wildcard ñèìâîë â äîìåíà íå ñúîòâåòñòâà +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Íåèçâåñíà êîìàíäà +ERR_NOMOTD: :%s 422 %s :Ôàéë MOTD íå å íàìåðåí +ERR_NOADMININFO: :%s 423 %s %s :Èíôîðìàöèÿ çà àäìèíà íå å äîñòúïíà +ERR_NONICKNAMEGIVEN: :%s 431 %s :Íÿìà èíôî çà íèêà +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Íåâåðåí íèê +ERR_NICKNAMEINUSE: :%s 433 %s %s :Òîçè íèê â ìîìåíòà ñå ïîëçâà. +ERR_NICKCOLLISION: :%s 436 %s %s :Ñúâïàäåíèå íà íèêà KILL +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Íèê/êàíàë âðåìåííî íåäîñòúïåí +ERR_SERVICESDOWN: :%s 440 %s :Services âðåìåíî íå ñà íà ëèíèÿ. +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :Ïîòðåáèòåëÿ íå ñå íàìèðà â òîçè êàíàë +ERR_NOTONCHANNEL: :%s 442 %s %s :Íå ñòå â òîçè êàíàë +ERR_USERONCHANNEL: :%s 443 %s %s %s :âèå âå÷å ñòå â òîçè êàíàë +ERR_NOTREGISTERED: :%s 451 %s :Âèå íå ñòå ðåãèñòðèðàí +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Íåäîñòàòú÷íî ïàðàìåòðè +ERR_ALREADYREGISTRED: :%s 462 %s :Âèå íå ìîæåòå äà ñå ðåãèñòðèðàòå +ERR_PASSWDMISMATCH: :%s 464 %s :Íåâÿðíà ïàðîëà +ERR_YOUREBANNEDCREEP: :%s 465 %s :Íà âàñ âè å çàáàíåí òîçè ñúðâúð- %s +ERR_CHANNELISFULL: :%s 471 %s %s :Íåâúçìîæíî å âëèçàíåòî â êàíàëà (+l) +ERR_UNKNOWNMODE: :%s 472 %s %c :íåèçâåñòåí ñèìâîë íà ðåæèì +ERR_INVITEONLYCHAN: :%s 473 %s %s :Íåâúçìîæíî å âëèçàíåòî â êàíàëà (+i) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Íåâúçìîæíî å âëèçàíåòî â êàíàëà (+b) +ERR_BADCHANNELKEY: :%s 475 %s %s :Íåâúçìîæíî å âëèçàíåòî â êàíàëà (+k) +ERR_BANLISTFULL: :%s 478 %s %s %s :Áàí ëèñòà â êàíàëà å ïåðåïúëíåí +ERR_BADCHANNAME: :%s 479 %s %s :Íåäîïóñòèìî èìå íà êàíàëà +ERR_NOPRIVILEGES: :%s 481 %s :Äîñòúï îòêàçàí - Âèå íÿìàòå ñòàòóò íà IRC îïåðàòîð +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Âèå íå ñòå îïåðàòîð íà êàíàëà +ERR_CANTKILLSERVER: :%s 483 %s :Âèå íå ìîæåòå äà óáèåòå ñúðâúðà! +ERR_RESTRICTED: :%s 484 %s :Âèå ñòå îãðàíè÷åí (RESTRICTED). +ERR_NOOPERHOST: :%s 491 %s :Ñàìî ìàëöèíà ñìúðòíè ìîãàò äà ñå îïèòàò äà âëåçíàò â çîíàòà íà çäðà÷à +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :Íåèçâåñòåí MODE ôëàã +ERR_USERSDONTMATCH: :%s 502 %s :Íå ìîæåòå äà ïðîìåíÿòå ðåæèìà íà äðóãèòå ïîòðåáèòåëè +ERR_GHOSTEDCLIENT: :%s 503 %s :Èíôîòî íå ìîæå äà ñå äîñòàâè äî %s +ERR_USERNOTONSERV: :%s 504 %s %s :Ïîòðåáèòåëÿ íå ñå íàìèðà íà òîçè ñúðâúð +ERR_WRONGPONG: :%s 513 %s :Çà äà ñå ñâúðæèø íàïèøè /QUOTE PONG %lu +ERR_HELPNOTFOUND: :%s 524 %s %s :Ôàéëà ñ ïîìîùíà èíôîðìàöèÿ íå å íàìåðåí +RPL_WHOISSECURE: :%s 671 %s %s :å ñâúçðàí ïðåç SSL (øèôðîâàíà âðúçêà) +RPL_ENDOFMODLIST: :%s 703 %s :Êðàé íà ëèñòà /MODLIST. +RPL_ENDOFHELP :%s 706 %s %s :Êðàé íà ëèñò-à /HELP. +RPL_KNOCK: :%s 710 %s %s %s!%s@%s :ïèòà çà ïîêàíà. +RPL_KNOCKDLVR: :%s 711 %s %s :Âàøèÿ KNOCK å äîñòàâåí. +ERR_TOOMANYKNOCK: :%s 712 %s %s :Òâúðäå ìíîãî KNOCKs (%s). +ERR_CHANOPEN: :%s 713 %s %s :Êàíàëà å îòâîðåí. +ERR_KNOCKONCHAN: :%s 714 %s %s :Âèå âå÷å ñòå â òîçè êàíàë. diff --git a/messages/ircd-croatian.lang b/messages/ircd-croatian.lang new file mode 100644 index 0000000..d18f665 --- /dev/null +++ b/messages/ircd-croatian.lang @@ -0,0 +1,94 @@ +; ircd-hybrid-7 custom message file +; Copyright (C) 2000 +; David Taylor <davidt@yadt.co.uk>, 2000. +; $Id$ + +RPL_WELCOME: :%s 001 %s :Dobro do¹li na %s Internet Relay Chat Network %s +RPL_YOURHOST: :%s 002 %s :Va¹ host je %s, i koristi verziju %s +RPL_CREATED: :%s 003 %s :Ovaj server je postavljen %s +RPL_ISUPPORT: :%s 005 %s %s :su podr¾ani na ovom serveru +RPL_REDIR: :%s 010 %s %s %d :Molim Vas, koristite ovaj server/port +RPL_TRACECONNECTING: :%s 201 %s Poku¹ajte. %s %s +RPL_TRACEUSER: :%s 205 %s Korisnik %s %s (%s) %lu %lu +RPL_TRACESERVER: :%s 206 %s Server %s %dS %dC %s %s!%s@%s %lu +RPL_TRACENEWTYPE: :%s 208 %s <novi tip> 0 %s +RPL_TRACECLASS: :%s 209 %s Klasa %s %d +RPL_ENDOFSTATS: :%s 219 %s %c :Kraj /STATS izvje¹taja +RPL_STATSUPTIME: :%s 242 %s :Server radi %d dana, %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :Najveæi broj veza: %d (%d klijenata) (%llu veza zaprimljeno)) +RPL_LUSERCLIENT: :%s 251 %s :Ima %d korisnika i %d nevidljivih na %d servera +RPL_LUSEROP: :%s 252 %s %d :IRC Operatora na vezi +RPL_LUSERUNKNOWN: :%s 253 %s %d :nepoznatih veza +RPL_LUSERCHANNELS: :%s 254 %s %d :kanala formirano +RPL_LUSERME: :%s 255 %s :Imam %d klijenata i %d servera +RPL_ADMINME: :%s 256 %s :Administrativne informacije o %s +RPL_ENDOFTRACE: :%s 262 %s %s :Kraj TRACEa +RPL_LOAD2HI: :%s 263 %s :Prièekajte, server je trenutno preoptereæen. +RPL_LOCALUSERS: :%s 265 %s :Trenutno lokalnih korisnika: %d Maks: %d +RPL_GLOBALUSERS: :%s 266 %s :Trenutno globalnih korisnika: %d Maks: %d +RPL_UNAWAY: :%s 305 %s :OK, nisi vi¹e /away. Je li bilo zabavno? +RPL_NOWAWAY: :%s 306 %s :OK, sad si /away. Po¾uri!! +RPL_ENDOFWHO: :%s 315 %s %s :Kraj /WHO liste. +RPL_WHOISIDLE: :%s 317 %s %s %d %d :sekundi neaktivan, vrijeme prijave +RPL_ENDOFWHOIS: :%s 318 %s %s :Kraj /WHOIS liste. +RPL_LISTSTART: :%s 321 %s Kanal :Korisnici Ime +RPL_LISTEND: :%s 323 %s :Kraj /LIST-a +RPL_NOTOPIC: :%s 331 %s %s :Topic nije postavljen. +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Kraj liste pozvanih na kanal +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Kraj liste iznimaka za kanal +RPL_CLOSING: :%s 362 %s %s :Zatvoren. Status = %d +RPL_CLOSEEND: :%s 363 %s %d: Zatvorenih veza +RPL_ENDOFLINKS: :%s 365 %s %s :Kraj /LINKS liste. +RPL_ENDOFNAMES: :%s 366 %s %s :Kraj /NAMES liste. +RPL_ENDOFBANLIST: :%s 368 %s %s :Kraj liste banova za kanal +RPL_ENDOFWHOWAS: :%s 369 %s %s :Kraj WHOWAS-a +RPL_ENDOFINFO: :%s 374 %s :Kraj /INFO liste. +RPL_MOTDSTART: :%s 375 %s :- %s Poruka dana - +RPL_ENDOFMOTD: :%s 376 %s :Kraj /MOTD komande. +RPL_YOUREOPER: :%s 381 %s :Au, sad si veliki jebaè! :). +RPL_REHASHING: :%s 382 %s %s :Uèitavam promijenjenu konfiguraciju +ERR_NOSUCHNICK: :%s 401 %s %s :Nema takvog nicka/kanala +ERR_NOSUCHSERVER: :%s 402 %s %s :Nema takvog servera +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Nema takvog kanala +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Ne mo¾e¹ poslati ni¹ta na kanal +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Joinao si se na previ¹e kanala +ERR_WASNOSUCHNICK: :%s 406 %s %s :Nije bilo takvog nicka. +ERR_TOOMANYTARGETS: :%s 407 %s %s :Previ¹e odredi¹ta - samo %d procesirano +ERR_NOORIGIN: :%s 409 %s :Izvori¹te nije specificirano +ERR_NORECIPIENT: :%s 411 %s :Nije specificiran primatelj (%s) +ERR_NOTEXTTOSEND: :%s 412 %s :Nema teksta koji bih poslao. +ERR_NOTOPLEVEL: :%s 413 %s %s :Nije specificirana vr¹na domena +ERR_WILDTOPLEVEL: :%s 414 %s %s :Nedovoljno precizno definirana vr¹na domena +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Nepoznata komanda +ERR_NOMOTD: :%s 422 %s :MOTD spis ne postoji +ERR_NOADMININFO: :%s 423 %s %s :Nema administrativnih informacija +ERR_NONICKNAMEGIVEN: :%s 431 %s :Nisi naveo nick +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Pogre¹an nick. +ERR_NICKNAMEINUSE: :%s 433 %s %s :Nick je veæ u upotrebi. +ERR_NICKCOLLISION: :%s 436 %s %s :Nick kolizija, KILL +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Nick/kanal trenutno nije na raspolaganju +ERR_NICKTOOFAST: :%s 438 %s %s %s :Prebrza promjena nicka. Molim, prièekaj %d sekundi +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :Nije na tom kanalu +ERR_NOTONCHANNEL: :%s 442 %s %s :Nisi na tom kanalu +ERR_USERONCHANNEL: :%s 443 %s %s %s :je veæ na kanalu +ERR_NOTREGISTERED: :%s 451 %s :Nisi se registrirao/la +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Nedovoljno parametara +ERR_ALREADYREGISTRED: :%s 462 %s :Ne mo¾e¹ se ponovo registrirati +ERR_PASSWDMISMATCH: :%s 464 %s :Kriva lozinka - poku¹aj ponovo! +ERR_YOUREBANNEDCREEP: :%s 465 %s :Zabranjen ti je pristup ovom serveru- %s +ERR_CHANNELISFULL: :%s 471 %s %s :Ne mo¾e¹ uæi na kanal (+l) +ERR_UNKNOWNMODE: :%s 472 %s %c :je meni nepoznata oznaka moda +ERR_INVITEONLYCHAN: :%s 473 %s %s :Ne mo¾e¹ uæi na kanal (+i) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Ne mo¾e¹ uæi na kanal (+b) +ERR_BADCHANNELKEY: :%s 475 %s %s :Ne mo¾e¹ uæi na kanal (+k) +ERR_BANLISTFULL: :%s 478 %s %s %s :Lista banova na kanalu je puna +ERR_BADCHANNAME: :%s 479 %s %s :Krivo ime kanala +ERR_NOPRIVILEGES: :%s 481 %s :Nije ti dozvoljeno, ¾ao mi je, nisi IRC operator +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Ne mo¾e¹ to napraviti, nisi operator na kanalu. +ERR_CANTKILLSERVER: :%s 483 %s :Ne budi blesav, ne mo¾e¹ /KILL-ati server :) +ERR_RESTRICTED: :%s 484 %s :Na ogranièenoj si vezi +ERR_NOOPERHOST: :%s 491 %s :®ao mi je, ne mo¾e¹ se /OPER-ati ovdje. +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :Nepoznata MODE oznaka +ERR_USERSDONTMATCH: :%s 502 %s :Ne mo¾e¹ mijenjati modove drugim korisnicima +ERR_GHOSTEDCLIENT: :%s 503 %s :Poruku nije moguæe dostaviti na %s +ERR_USERNOTONSERV: :%s 504 %s %s :Korisnik nije na ovom serveru diff --git a/messages/ircd-danish.lang b/messages/ircd-danish.lang new file mode 100644 index 0000000..0bdb497 --- /dev/null +++ b/messages/ircd-danish.lang @@ -0,0 +1,93 @@ +; ircd-hybrid-7 custom message file for danish use +; Copyright (C) YEAR Free Software Foundation, Inc. +; Xride +; Soren Straarup <xride@x12.dk>, 2001. +; $Id$ + +RPL_WELCOME: :%s 001 %s :Velkommen til %s Internet Rel‘ Netv‘rket %s +RPL_YOURHOST: :%s 002 %s :Din v‘rt er %s, k›rer version %s +RPL_CREATED: :%s 003 %s :Denne server var lavet %s +RPL_ISUPPORT: :%s 005 %s %s :er supporteret af denne server +RPL_REDIR: :%s 010 %s %s %d :Brug venligst denne Server/Port isteddet +RPL_TRACELINK: :%s 200 %s Forbindelse %s %s %s +RPL_TRACECONNECTING: :%s 201 %s Pr›v. %s %s +RPL_TRACEUSER: :%s 205 %s Bruger %s %s (%s) %lu %lu +RPL_TRACECLASS: :%s 209 %s Klasse %s %d +RPL_ENDOFSTATS: :%s 219 %s %c :Slutningen p† /STATS rapporten +RPL_STATSUPTIME: :%s 242 %s :Server oppe %d dag(e), %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :H›jeste forbindelser antal: %d (%d brugere) (%llu forbindelser modtaget) +RPL_LUSERCLIENT: :%s 251 %s :Der er %d brugere og %d usynlige p† %d servere +RPL_LUSEROP: :%s 252 %s %d :IRC Operatorer er her +RPL_LUSERUNKNOWN: :%s 253 %s %d :ukendt forbindelse(r) +RPL_LUSERCHANNELS: :%s 254 %s %d :rum er etableret +RPL_LUSERME: :%s 255 %s :Jeg har %d brugere og %d serverer +RPL_ADMINME: :%s 256 %s :Adminstrativ info om %s +RPL_ENDOFTRACE: :%s 262 %s %s :Slutningen p† TRACE +RPL_LOAD2HI: :%s 263 %s :Server forbruget er midlertidigt for stort. Vent venligst lidt og pr›v s† igen. +RPL_LOCALUSERS: :%s 265 %s :Nuv†rende lokale brugere: %d Max: %d +RPL_GLOBALUSERS: :%s 266 %s :Nuv†rende globale brugere: %d Max: %d +RPL_UNAWAY: :%s 305 %s :Du er ikke l‘ngere markeret som v‘rende v‘k +RPL_NOWAWAY: :%s 306 %s :Du er markeret som v‘rende v‘k +RPL_ENDOFWHO: :%s 315 %s %s :Slutningen p† /WHO listen. +RPL_WHOISIDLE: :%s 317 %s %s %d %d :sekunders stilhed, ankomst tidspunkt +RPL_ENDOFWHOIS: :%s 318 %s %s :Slutningen p† /WHOIS listen. +RPL_LISTSTART: :%s 321 %s Rum :Brugers Navne +RPL_LISTEND: :%s 323 %s :Slutnigen p† /LIST +RPL_NOTOPIC: :%s 331 %s %s :Ingen overskrift er bestemt. +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Slutningen p† Rummets Invitations Liste +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Slutningen p† Rummets Undtagelses Liste +RPL_CLOSING: :%s 362 %s %s :Lukket. Status = %d +RPL_CLOSEEND: :%s 365 %s %d: Forbindelser afbrudt +RPL_ENDOFLINKS: :%s 365 %s %s :Slutningen p† /LINKS listen. +RPL_ENDOFNAMES: :%s 366 %s %s :Slutningen p† /NAMES listen. +RPL_ENDOFBANLIST: :%s 368 %s %s :Slutningen p† Rummets Ban liste +RPL_ENDOFWHOWAS: :%s 369 %s %s :Slutningen p† WHOWAS +RPL_ENDOFINFO: :%s 374 %s :Slutningen p† /INFO listen. +RPL_MOTDSTART: :%s 375 %s :- %s Dagens besked - +RPL_ENDOFMOTD: :%s 376 %s :Slutningen p† /MOTD kommandoen +RPL_YOUREOPER: :%s 381 %s :Du har tr†dt ind i .. tusm›rket.. +RPL_REHASHING: :%s 382 %s %s :Genindldser konfigurations filerne +ERR_NOSUCHNICK: :%s 401 %s %s :Intet nick/rum blev fundet +ERR_NOSUCHSERVER: :%s 402 %s %s :Igen s†dan server blev fundet +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Rummet findes ikke +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Kan ikke sende til Rummet +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Du er i for mange rum +ERR_WASNOSUCHNICK: :%s 406 %s %s :nicket findes ikke +ERR_TOOMANYTARGETS: :%s 407 %s %s :For mange modtagere. kun %d blev udf›rt +ERR_NOORIGIN: :%s 409 %s :Intet start punkt er angivet +ERR_NORECIPIENT: :%s 411 %s :Ingen modtagere er (%s) +ERR_NOTEXTTOSEND: :%s 412 %s :Ingen tekst til at sende +ERR_NOTOPLEVEL: :%s 413 %s %s :Intet toplevel domain er specificeret +ERR_WILDTOPLEVEL: :%s 414 %s %s :Wildcard i toplevel Domain +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Ukendt kommando +ERR_NOMOTD: :%s 422 %s :MOTD Filen findes ikke +ERR_NOADMININFO: :%s 423 %s %s :Ingen adminstrative info er tilg‘ngelige +ERR_NONICKNAMEGIVEN: :%s 431 %s :Intet nick er angivet +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Fejl i nick +ERR_NICKNAMEINUSE: :%s 433 %s %s :Nick allerede i brug. +ERR_NICKCOLLISION: :%s 436 %s %s :Nick kollition KILL (drabt) +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Nick/rum er midlertidig ikke tilg‘ngelig +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :De er ikke i rummet +ERR_NOTONCHANNEL: :%s 442 %s %s :Du er ikke i det rum +ERR_USERONCHANNEL: :%s 443 %s %s %s :er allerede i rummet +ERR_NOTREGISTERED: :%s 451 %s :Du er ikke registreret +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Ikke nok paramtre +ERR_ALREADYREGISTRED: :%s 462 %s :Du m† ikke genregistrerer +ERR_PASSWDMISMATCH: :%s 464 %s :Forkert kodeord +ERR_YOUREBANNEDCREEP: :%s 456 %s :Du er udelukket fra denne server- %s +ERR_CHANNELISFULL: :%s 471 %s %s :Kan ikke deltage i rummet (+l) +ERR_UNKNOWNMODE: :%s 472 %s %c :er ukendt mode bogstav for mig +ERR_INVITEONLYCHAN: :%s 473 %s %s :Kan ikke deltage i rummet (+i) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Kan ikke deltage i rummet (+b) +ERR_BADCHANNELKEY: :%s 475 %s %s :Kan ikke deltage i rummet (+k) +ERR_BANLISTFULL: :%s 478 %s %s %s :Rummets ban liste er fuld +ERR_BADCHANNAME: :%s 479 %s %s :Illegalt navn for et Rum +ERR_NOPRIVILEGES: :%s 481 %s :Udf›relse N‘gtet - Du er ikke en IRC operator +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Du er ikke operator i dette rum +ERR_CANTKILLSERVER: :%s 483 %s :Du kan ikke KILL (dr‘be) en server! +ERR_RESTRICTED: :%s 484 %s :Du er begr‘nset +ERR_NOOPERHOST: :%s 491 %s :Kun f† d›delige kan pr›ve at tr‘de ind i tudsm›rket +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :Ukendt MODE flag +ERR_USERSDONTMATCH: :%s 502 %s :Kan ikke ‘ndre mode for andre brugere +ERR_GHOSTEDCLIENT: :%s 503 %s :Beskeden kunne ikke blive leveret til %s +ERR_USERNOTONSERV: :%s 504 %s %s :Brugeren er ikke p† denne server diff --git a/messages/ircd-dutch.lang b/messages/ircd-dutch.lang new file mode 100644 index 0000000..0056e90 --- /dev/null +++ b/messages/ircd-dutch.lang @@ -0,0 +1,123 @@ +; ircd-hybrid-7 standard message file - Dutch language +; Copyright (C) 2005 Kenneth Pang <nexu.jin@gmail.com> +; $Id$ + +RPL_WELCOME: :%s 001 %s :Welkom op het %s Internet Relay Netwerk %s +RPL_YOURHOST: :%s 002 %s :Jouw host is %s, werkend met versie %s +RPL_CREATED: :%s 003 %s :Deze server is gecreerd op %s +RPL_ISUPPORT: :%s 005 %s %s :zijn ondersteund door deze server +RPL_REDIR: :%s 010 %s %s %d :Gebruik deze Server/Poort A.U.B. +RPL_MAPEND: :%s 017 %s :Einde van /MAP +RPL_YOURID: :%s 042 %s %s :jouw unieke ID +RPL_TRACELINK: :%s 200 %s Link %s %s %s +RPL_TRACECONNECTING: :%s 201 %s Probeer. %s %s +RPL_TRACEOPERATOR: :%s 204 %s Operator %s %s (%s) %lu %lu +RPL_TRACEUSER: :%s 205 %s Gebruiker %s %s (%s) %lu %lu +RPL_TRACESERVER: :%s 206 %s Serv %s %dS %dC %s %s!%s@%s %lu +RPL_TRACENEWTYPE: :%s 208 %s <nieuwtype> 0 %s +RPL_TRACECLASS: :%s 209 %s Klasse %s %d +RPL_ENDOFSTATS: :%s 219 %s %c :Einde van /STATS rapportage +RPL_STATSUPTIME: :%s 242 %s :Server is al %d dagen up, %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :Hoogst aantal connecties: %d (%d clients) (%llu connecties ontvangen) +RPL_LUSERCLIENT: :%s 251 %s :Er zijn %d zichtbare -en %d onzichtbare gebruikers op %d servers +RPL_LUSEROP: :%s 252 %s %d :IRC Operators verbonden +RPL_LUSERUNKNOWN: :%s 253 %s %d :onbekende connectie(s) +RPL_LUSERCHANNELS: :%s 254 %s %d :kanalen gevormd +RPL_LUSERME: :%s 255 %s :Ik heb %d gebruikers en %d servers +RPL_ADMINME: :%s 256 %s :Administratieve informatie over %s +RPL_ENDOFTRACE: :%s 262 %s %s :Einde van TRACE +RPL_LOAD2HI: :%s 263 %s :Server is tijdelijk overbelast. Wacht even en probeer het opnieuw. +RPL_LOCALUSERS: :%s 265 %s :Huidige lokale gebruikers: %d Max: %d +RPL_GLOBALUSERS: :%s 266 %s :Huidige globale gebruikers: %d Max: %d +RPL_ENDOFACCEPT: :%s 282 %s :Einde van /ACCEPT lijst. +RPL_UNAWAY: :%s 305 %s :Je bent niet langer gemarkeerd als afwezig +RPL_NOWAWAY: :%s 306 %s :Je bent nu gemarkeerd als afwezig +RPL_WHOISADMIN: :%s 313 %s %s :is een Server Administrator +RPL_WHOISOPERATOR: :%s 313 %s %s :is een IRC Operator +RPL_ENDOFWHO: :%s 315 %s %s :Einde van /WHO lijst. +RPL_WHOISIDLE: :%s 317 %s %s %d %d :seconden niks uitgevoerd +RPL_ENDOFWHOIS: :%s 318 %s %s :Einde van /WHOIS lijst. +RPL_LISTSTART: :%s 321 %s Kanaal :Gebruikers Naam +RPL_LISTEND: :%s 323 %s :Einde van /LIST +RPL_NOTOPIC: :%s 331 %s %s :Er is geen onderwerp gezet +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Einde van Kanaal Uitnodigings-lijst +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Einde van Kanaal Uitzondering-lijst +RPL_CLOSING: :%s 362 %s %s :Gesloten. Status = %d +RPL_CLOSEEND: :%s 363 :%s %d: Verbindingen Gesloten +RPL_ENDOFLINKS: :%s 365 %s %s :Einde van /LINKS lijst. +RPL_ENDOFNAMES: :%s 366 %s %s :Einde van /NAMES lijst. +RPL_ENDOFBANLIST: :%s 368 %s %s :Einde van Kanaal Verbannen Lijst +RPL_ENDOFWHOWAS: :%s 369 %s %s :Einde van WHOWAS +RPL_INFOSTART: :%s 373 %s :Server INFO +RPL_ENDOFINFO: :%s 374 %s :Einde van /INFO lijst +RPL_MOTDSTART: :%s 375 %s :- %s Bericht van de Dag - +RPL_ENDOFMOTD: :%s 376 %s :Einde van /MOTD commando. +RPL_YOUREOPER: :%s 381 %s :Je bent nu volwaardig lid van De Harde Kern!. +RPL_REHASHING: :%s 382 %s %s :Rehasjing +RPL_HOSTHIDDEN: :%s 396 %s :is nu jouw verborgen host +ERR_NOSUCHNICK: :%s 401 %s %s :Onbekende nick/kanaal +ERR_NOSUCHSERVER: :%s 402 %s %s :Onbekende server +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Onbekende kanaal +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Kan niets naar het kanaal verzenden +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Je zit al in te veel kanalen +ERR_WASNOSUCHNICK: :%s 406 %s %s :Die nicknaam bestaat niet +ERR_TOOMANYTARGETS: :%s 407 %s %s :Te veel ontvangers. Slechts %d verwerkt +ERR_NOORIGIN: :%s 409 %s :Geen bron vermeld +ERR_NORECIPIENT: :%s 411 %s :Geen ontvanger gespecificeerd (%s) +ERR_NOTEXTTOSEND: :%s 412 %s :Geen tekst om te verzenden +ERR_NOTOPLEVEL: :%s 413 %s %s :Geen toplevel domein gespecificeerd +ERR_WILDTOPLEVEL: :%s 414 %s %s :Joker in toplevel Domein +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Onbekende commando +ERR_NOMOTD: :%s 422 %s :MOTD bestand bestaat niet +ERR_NOADMININFO: :%s 423 %s %s :Geen administratieve informatie beschikbaar +ERR_NONICKNAMEGIVEN: :%s 431 %s :Geen nicknaam gespecificeerd +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Nicknaam bevat foutieve tekens +ERR_NICKNAMEINUSE: :%s 433 %s %s :Nicknaam is reeds bezet +ERR_NICKCOLLISION: :%s 436 %s %s :Nicknaam botsing KILL +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Nick/kanaal is tijdelijk niet beschikbaar +ERR_NICKTOOFAST: :%s 438 %s %s %s :Nicknaam veranderingen te snel. Wacht A.U.B. %d seconden. +ERR_SERVICESDOWN: :%s 440 %s :Diensten zijn momenteel niet beschikbaar. +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :Die is/zijn niet in dat kanaal +ERR_NOTONCHANNEL: :%s 442 %s %s :Jij bent niet in dat kanaal +ERR_USERONCHANNEL: :%s 443 %s %s %s :is reeds op het kanaal +ERR_NOTREGISTERED: :%s 451 %s :Je bent niet geregistreerd +ERR_ACCEPTFULL: :%s 456 %s :Accepteer lijst is vol +ERR_ACCEPTEXIST: :%s 457 %s %s :is al op jouw accepteer lijst +ERR_ACCEPTNOT: :%s 458 %s %s :is niet op jouw accepteer lijst +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Niet genoeg parameters +ERR_ALREADYREGISTRED: :%s 462 %s :Je mag niet opnieuw registreren +ERR_PASSWDMISMATCH: :%s 464 %s :Foutief Wachtwoord +ERR_YOUREBANNEDCREEP: :%s 465 %s :Je bent verbannen van deze server- %s +ERR_CHANNELISFULL: :%s 471 %s %s :Kan kanaal niet joinen (het zit vol (+l)) +ERR_UNKNOWNMODE: :%s 472 %s %c :is een onbekende mode voor me +ERR_INVITEONLYCHAN: :%s 473 %s %s :Kan het kanaal niet joinen (uitnodiging vereist (+i)) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Kan kanaal niet joinen (verbannen (+b)) +ERR_BADCHANNELKEY: :%s 475 %s %s :Kan kanaal niet joinen (versleuteld (+k)) +ERR_BANLISTFULL: :%s 478 %s %s %s :Kanaal verbannen-lijst zit vol +ERR_BADCHANNAME: :%s 479 %s %s :Foutief kanaal-naam +ERR_NOPRIVILEGES: :%s 481 %s :Toestemming geweigerd - Je bent geen IRC operator +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Je bent geen operator in dit kanaal +ERR_CANTKILLSERVER: :%s 483 %s :Je kunt een server niet killen! +ERR_RESTRICTED: :%s 484 %s :Je mogelijkheden zijn beperkt +ERR_NOOPERHOST: :%s 491 %s :Slechts weinigen van de stervelijken mogen de Harde Kern betreden +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :Onbekende MODE flag +ERR_USERSDONTMATCH: :%s 502 %s :Je kunt een mode niet veranderen voor een andere gebruiker +ERR_GHOSTEDCLIENT: :%s 503 %s :Bericht kon niet worden afgeleverd aan %s +ERR_USERNOTONSERV: :%s 504 %s %s :Gebruiker zit niet op deze server +ERR_WRONGPONG: :%s 513 %s :Om te verbinden type /QUOTE PONG %lu +ERR_LISTSYNTAX: :%s 521 %s :Foutieve lijst syntaxis +ERR_HELPNOTFOUND: :%s 524 %s %s :Hulp niet gevonden en/of beschikbaar +RPL_WHOISSECURE: :%s 671 %s %s :is verbonden via SSL (beveiligd link) +RPL_ENDOFMODLIST: :%s 703 %s :Einde van /MODLIST. +RPL_ENDOFHELP: :%s 706 %s %s :Einde van /HELP. +RPL_KNOCK: :%s 710 %s %s %s!%s@%s :heeft gevraagd om een uitnodiging. +RPL_KNOCKDLVR: :%s 711 %s %s :Jouw KNOCK is afgeleverd. +ERR_TOOMANYKNOCK: :%s 712 %s %s :Te veel KNOCKs (%s). +ERR_CHANOPEN: :%s 713 %s %s :Kanaal is open. +ERR_KNOCKONCHAN: :%s 714 %s %s :Jij bent al in dat kanaal. +RPL_TARGUMODEG: :%s 716 %s %s :is in +g mode (server kant negeer) +RPL_TARGNOTIFY: :%s 717 %s %s :is op het hoogte gesteld van jouw bericht. +RPL_UMODEGMSG: :%s 718 %s %s :stuurde jou een bericht, maar jij bent momenteel in umode +g. +ERR_NOPRIVS: :%s 723 %s %s :Niet voldoende operator privileges. +RPL_TESTMASK: :%s 724 %s %s!%s@%s %u %u :Lokaal/remote clienten zijn gelijk. +RPL_NOTESTLINE: :%s 726 %s %s :Geen gelijken diff --git a/messages/ircd-french.lang b/messages/ircd-french.lang new file mode 100644 index 0000000..91d8b9a --- /dev/null +++ b/messages/ircd-french.lang @@ -0,0 +1,112 @@ +; ircd-hybrid-7 custom message file +; Copyright (C) 2003 +; Joshua Kwan <joshk@triplehelix.org> +; $Id$ + +RPL_LUSEROP: :%s 252 %s %d :opérateurs IRC en ligne +RPL_LOAD2HI: :%s 263 %s :Veuillez patienter, le serveur est trop occupé +RPL_UNAWAY: :%s 305 %s :Vous n'êtes plus marqué 'absent' +RPL_NOWAWAY: :%s 306 %s :Vous êtes maintenant marqué 'absent' +RPL_YOUREOPER: :%s 381 %s :Vous êtes maintenant un opérateur IRC +RPL_REHASHING: :%s 382 %s %s :Le serveur relit le fichier de configuration +RPL_WELCOME: :%s 001 %s :Bienvenue au réseau IRC %s %s +RPL_YOURHOST: :%s 002 %s :Votre serveur est %s, version %s +RPL_CREATED: :%s 003 %s :Ce serveur a été crée %s +RPL_ISUPPORT: :%s 005 %s %s :sont supportés par ce serveur +RPL_REDIR: :%s 010 %s %s %d :Veuillez utiliser ce serveur +RPL_MAPEND: :%s 017 %s :Fin de /MAP +RPL_TRACELINK: :%s 200 %s Lien %s %s %s +RPL_TRACECONNECTING: :%s 201 %s Essai. %s %s +RPL_TRACEOPERATOR: :%s 204 %s Opér %s %s (%s) %lu %lu +RPL_TRACEUSER: :%s 205 %s Client %s %s (%s) %lu %lu +RPL_TRACESERVER: :%s 206 %s Serv. %s %dS %dC %s %s!%s@%s %lu +RPL_TRACENEWTYPE: :%s 208 %s <nouvelletype> 0 %s +RPL_TRACECLASS: :%s 209 %s Classe %s %d +RPL_ENDOFSTATS: :%s 219 %s %c :Fin de reportage /STATS +RPL_STATSUPTIME: :%s 242 %s :Le serveur fonctionne depuis %d jours, %dh %dm %ds +RPL_STATSCONN: :%s 250 %s :Plus grand nombre de connexions simultanées: %d (%d clients) (%llu connexions reçues) +RPL_LUSERCLIENT: :%s 251 %s :Il y a %d clients et %d invisibles sur %d serveurs +RPL_LUSERUNKNOWN: :%s 253 %s %d :connexion(s) inconnue(s) +RPL_LUSERCHANNELS: :%s 254 %s %d :chaînes crées +RPL_LUSERME: :%s 255 %s :J'ai %d clients et %d serveurs +RPL_ADMINME: :%s 256 %s :Renseignements administratives %s +RPL_ENDOFTRACE: :%s 262 %s %s :Fin de TRACE +RPL_LOCALUSERS: :%s 265 %s :Clients locaux: %d Max: %d +RPL_GLOBALUSERS: :%s 266 %s :Clients globaux: %d Max: %d +RPL_ENDOFACCEPT: :%s 282 %s :Fin de liste /ACCEPT. +RPL_ENDOFWHO: :%s 315 %s %s :Fin de liste /WHO. +RPL_WHOISIDLE: :%s 317 %s %s %d %d :silent seconds +RPL_ENDOFWHOIS: :%s 318 %s %s :Fin de liste /WHOIS. +RPL_LISTSTART: :%s 321 %s Chaîne :Clients Nom +RPL_LISTEND: :%s 323 %s :Fin de /LIST +RPL_NOTOPIC: :%s 331 %s %s :Il n'y a pas de sujet +RPL_WHOISACTUALLY: :%s 338 %s %s %s :utilise vraiment l'addresse +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Fin de liste des invités +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Fin de liste des exceptionnés +RPL_CLOSING: :%s 362 %s %s :Fermé. Etat = %d +RPL_CLOSEEND: :%s 363 %s %d: Connexions fermées +RPL_ENDOFLINKS: :%s 365 %s %s :Fin de liste /LINKS. +RPL_ENDOFNAMES: :%s 366 %s %s :Fin de liste /NAMES. +RPL_ENDOFBANLIST: :%s 368 %s %s :Fin de liste des interdits de la chaîne +RPL_ENDOFWHOWAS: :%s 369 %s %s :Fin de WHOWAS +RPL_INFOSTART: :%s 373 %s :INFO Serveur +RPL_ENDOFINFO: :%s 374 %s :Fin de liste /INFO. +RPL_MOTDSTART: :%s 375 %s :- %s Message du jour - +RPL_ENDOFMOTD: :%s 376 %s :Fin de commande /MOTD. +ERR_PASSWDMISMATCH: :%s 464 %s :Faux mot de passe +ERR_NOPRIVILEGES: :%s 481 %s :Vous n'avez pas ce droit puisque vous n'êtes pas un opérateur +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Vous n'avez pas assez de pouvoir dans cette chaîne IRC pour faire ça +ERR_CANTKILLSERVER: :%s 483 %s :Impossible de /KILLer un serveur! +ERR_NOOPERHOST: :%s 491 %s :Vous manquez la bonne addresse ou le bon mot de passe pour devenir un opérateur IRC +ERR_NOSUCHNICK: :%s 401 %s %s :Aucun(e) client/chaîne. +ERR_NOSUCHSERVER: :%s 402 %s %s :Aucun serveur +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Aucune chaîne +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Impossible d'envoyer à la chaîne +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Vous êtes dans trop de chaînes +ERR_WASNOSUCHNICK: :%s 406 %s %s :Il n'y avait pas un tel nom +ERR_TOOMANYTARGETS: :%s 407 %s %s :Trop de destinations. Seulement %d ont été lus. +ERR_NOORIGIN: :%s 409 %s :Vous n'avez pas marqué d'origine +ERR_NORECIPIENT: :%s 411 %s :Vous n'avez pas marqué de destination (%s) +ERR_NOTEXTTOSEND: :%s 412 %s :Pas de texte à envoyer +ERR_NOTOPLEVEL: :%s 413 %s %s :Aucune domaine marqué +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Commande inconnue +ERR_NOMOTD: :%s 422 %s :Fichier de message du jour manquant +ERR_NOADMININFO: :%s 423 %s %s :Il n'y a pas de renseignements administratives +ERR_NONICKNAMEGIVEN: :%s 431 %s :Aucun nom donné +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Nom inapproprié +ERR_NICKNAMEINUSE: :%s 433 %s %s :Ce nom est déjà utilisé. +ERR_NICKCOLLISION: :%s 436 %s %s :Collision de noms KILL +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Client/chaîne temporairement indisponible +ERR_NICKTOOFAST: :%s 438 %s %s %s :Attendez %d secondes avant de changer votre nom encore. +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :Il n'est pas sur cette chaîne +ERR_NOTONCHANNEL: :%s 442 %s %s :Vous n'êtes pas sur cette chaîne +ERR_USERONCHANNEL: :%s 443 %s %s %s :est déjà sur chaîne +ERR_NOTREGISTERED: :%s 451 %s :Vous ne vous êtes pas enregistré +ERR_ACCEPTFULL: :%s 456 %s :Liste d'acceptance pleine +ERR_ACCEPTEXIST: :%s 457 %s %s :est déjà sur votre liste d'acceptance +ERR_ACCEPTNOT: :%s 458 %s %s :n'est pas sur votre liste d'acceptance +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Pas assez de paramètres +ERR_ALREADYREGISTRED: :%s 462 %s :Vous ne pouvez pas vous enregistrer à nouveau +ERR_YOUREBANNEDCREEP: :%s 465 %s :Vous êtes interdit d'utiliser ce serveur %s +ERR_CHANNELISFULL: :%s 471 %s %s :Impossible de joindre (+l) +ERR_UNKNOWNMODE: :%s 472 %s %c :m'est inconnu +ERR_INVITEONLYCHAN: :%s 473 %s %s :Impossible de joindre (+i) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Impossible de joindre (+b) +ERR_BADCHANNELKEY: :%s 475 %s %s :Impossible de joindre (+k) +ERR_BANLISTFULL: :%s 478 %s %s %s :Liste d'interdits est plein +ERR_BADCHANNAME: :%s 479 %s %s :Nom de chaîne illégale +ERR_RESTRICTED: :%s 484 %s :Vous êtes restraint +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :MODE client inconnue +ERR_USERSDONTMATCH: :%s 502 %s :Impossible de modifier la mode des autres clients +ERR_GHOSTEDCLIENT: :%s 503 %s :Le message n'est pas parvenu à %s +ERR_USERNOTONSERV: :%s 504 %s %s :Client n'est pas sur ce serveur +ERR_WRONGPONG: :%s 513 %s :Pour connecter tapez /QUOTE PONG %lu +ERR_LISTSYNTAX: :%s 521 %s :Mauvaise syntaxe /LIST +ERR_HELPNOTFOUND: :%s 524 %s %s :Ce renseignement n'existe pas +RPL_ENDOFMODLIST: :%s 703 %s :Fin de /MODLIST. +RPL_ENDOFHELP: :%s 706 %s %s :Fin de /HELP. +RPL_KNOCK: :%s 710 %s %s %s!%s@%s :a demandé d'être invité +RPL_KNOCKDLVR: :%s 711 %s %s :Votre KNOCK a été envoyé. +ERR_TOOMANYKNOCK: :%s 712 %s %s :Trop de KNOCKs (%s). +ERR_CHANOPEN: :%s 713 %s %s :La chaîne est ouverte. +ERR_KNOCKONCHAN: :%s 714 %s %s :Vous êtes déjà sur cette chaîne. diff --git a/messages/ircd-german.lang b/messages/ircd-german.lang new file mode 100644 index 0000000..ee2cc5c --- /dev/null +++ b/messages/ircd-german.lang @@ -0,0 +1,126 @@ +; ircd-hybrid-7 custom message file +; Copyright (C) 2000-2005 +; David Taylor <davidt@yadt.co.uk>, 2000. +; Markus R. <mxr@chatjunkies.org>, 2005. +; $Id$ + +RPL_WELCOME: :%s 001 %s :Wilkommen im %s Internet Relay Chat Netzwerk, %s! +RPL_YOURHOST: :%s 002 %s :Du bist verbunden mit %s, version %s +RPL_CREATED: :%s 003 %s :Dieser Server wurde erstellt: %s +RPL_ISUPPORT: :%s 005 %s %s :werden von diesem Server unterstützt. +RPL_REDIR: :%s 010 %s %s %d :Bitte benutze stattdessen diesen Server/Port. +RPL_MAPEND: :%s 017 %s :Ende von /MAP. +RPL_YOURID: :%s 042 %s %s :deine eindeutige ID +RPL_TRACELINK: :%s 200 %s verbunden %s %s %s +RPL_TRACECONNECTING: :%s 201 %s Versuche. %s %s +RPL_TRACEOPERATOR: :%s 204 %s Operator %s %s (%s) %lu %lu +RPL_TRACEUSER: :%s 205 %s Benutzer %s %s (%s) %lu %lu +RPL_TRACESERVER: :%s 206 %s Server %s %dS %dC %s %s!%s@%s %lu +RPL_TRACENEWTYPE: :%s 208 %s <neuer Typ> 0 %s +RPL_TRACECLASS: :%s 209 %s Klasse %s %d +RPL_ENDOFSTATS: :%s 219 %s %c :Ende von /STATS. +RPL_STATSUPTIME: :%s 242 %s :Server läuft seit %d Tagen, %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :Rekord an gleichzeitigen Verbindungen: %d (davon %d Benutzer) (%llu Verbindungen) +RPL_LUSERCLIENT: :%s 251 %s :Hier gibt es %d Benutzer, davon %d unsichtbar, auf %d Servern. +RPL_LUSEROP: :%s 252 %s %d :IRC Operatorn sind online. +RPL_LUSERUNKNOWN: :%s 253 %s %d :Unbekannte Verbindungen. +RPL_LUSERCHANNELS: :%s 254 %s %d :Chaträume existieren. +RPL_LUSERME: :%s 255 %s :Ich habe %d Benutzer und %d verbundene Server. +RPL_ADMINME: :%s 256 %s :Administrative Informationen über %s +RPL_ENDOFTRACE: :%s 262 %s %s :Ende von TRACE. +RPL_LOAD2HI: :%s 263 %s :Zur Zeit kann Ihre Anfrage nicht bearbeitet werden. Der Server ist überlastet. +RPL_LOCALUSERS: :%s 265 %s :Anzahl der lokalen User, zur Zeit: %d Maximum: %d +RPL_GLOBALUSERS: :%s 266 %s :Anzahl der globalen User, zur Zeit: %d Maximum: %d +RPL_ENDOFACCEPT: :%s 282 %s :Ende der /ACCEPT-Liste. +RPL_UNAWAY: :%s 305 %s :Du bist nun nicht mehr abwesend (away). +RPL_NOWAWAY: :%s 306 %s :Du bist nun abwesend (away). +RPL_WHOISADMIN: :%s 313 %s %s :ist ein Server Administrator. +RPL_WHOISOPERATOR: :%s 313 %s %s :ist ein IRC Operator. +RPL_ENDOFWHO: :%s 315 %s %s :Ende der /WHO-Liste. +RPL_WHOISIDLE: :%s 317 %s %s %d %d :Sekunden inaktiv +RPL_ENDOFWHOIS: :%s 318 %s %s :Ende der /WHOIS-Liste. +RPL_LISTSTART: :%s 321 %s Raum :Besucher Name +RPL_LISTEND: :%s 323 %s :End von /LIST +RPL_NOTOPIC: :%s 331 %s %s :Kein Thema für diesen Raum gesetzt. +RPL_WHOISACTUALLY: :%s 338 %s %s %s :wirklicher Host: +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Ende der Liste von Einladungen für diesen Raum. +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Ende der Liste von Sperr-Ausnahmen für diesen Raum. +RPL_CLOSING: :%s 362 %s %s :Geschlossen. Status = %d +RPL_CLOSEEND: :%s 363 %s %d:Verbindung getrennt. +RPL_ENDOFLINKS: :%s 365 %s %s :Ende der /LINKS-Liste. +RPL_ENDOFNAMES: :%s 366 %s %s :Ende der /NAMES-Liste. +RPL_ENDOFBANLIST: :%s 368 %s %s :Ende der Sperr-Liste für diesen Raum +RPL_ENDOFWHOWAS: :%s 369 %s %s :Ende von WHOWAS. +RPL_INFOSTART: :%s 373 %s :Server INFO +RPL_ENDOFINFO: :%s 374 %s :Ende der /INFO-Liste. +RPL_MOTDSTART: :%s 375 %s :- %s Nachricht des Tages - +RPL_ENDOFMOTD: :%s 376 %s :Ende von /MOTD. +RPL_YOUREOPER: :%s 381 %s :ich mag starke Persönlichkeiten.. besorgs mir! +RPL_REHASHING: :%s 382 %s %s :Konfiguration wurde erneut eingelesen +RPL_HOSTHIDDEN: :%s 396 %s :ist nun dein sichtbarer Host +ERR_NOSUCHNICK: :%s 401 %s %s :Dieser Benutzer/Raum existiert nicht +ERR_NOSUCHSERVER: :%s 402 %s %s :Dieser Server existiert nicht +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Dieser Raum existiert nicht +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Senden der Nachricht nicht möglich. +ERR_TOOMANYCHANNELS: :%s 405 %s %s :zuviele gleichzeitige Räume +ERR_WASNOSUCHNICK: :%s 406 %s %s :Diesen Benutzer gab es nicht +ERR_TOOMANYTARGETS: :%s 407 %s %s :Die Nachricht wurde an zu viele Benutzer geschickt. Nur %d wurden weitergeleitet +ERR_NOORIGIN: :%s 409 %s :von wem kommt diese Nachricht? +ERR_NORECIPIENT: :%s 411 %s :An wen soll diese Nachricht geschickt werden? (%s) +ERR_NOTEXTTOSEND: :%s 412 %s :Es gibt keine Nachricht zu senden +ERR_NOTOPLEVEL: :%s 413 %s %s :keine TLD (top level domain) angegeben. +ERR_WILDTOPLEVEL: :%s 414 %s %s :Platzhalter in der TLD (top level domain) +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :unbekannter Befehl +ERR_NOMOTD: :%s 422 %s :Keine MOTD Datei gefunden. +ERR_NOADMININFO: :%s 423 %s %s :Es stehen keine Administrativen Informationen zur Verfügung +ERR_NONICKNAMEGIVEN: :%s 431 %s :Kein Benutzer angegeben +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Fehlerhafter Benutzername +ERR_NICKNAMEINUSE: :%s 433 %s %s :Benutzername bereits in verwendung +ERR_NICKCOLLISION: :%s 436 %s %s :Benutzernamen-Kollision, KILL +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Benutzername/Raum vorübergehend nicht verfügbar +ERR_NICKTOOFAST: :%s 438 %s %s %s :Du hast zu schnell Benutzername gewechselt. Bitte warte %d Sekunden. +ERR_SERVICESDOWN: :%s 440 %s :Services sind momentan nicht verfügbar +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :Diese Benutzer sind nicht in diesem Raum +ERR_NOTONCHANNEL: :%s 442 %s %s :Du bist nicht in diesem Raum +ERR_USERONCHANNEL: :%s 443 %s %s %s :ist schon in diesem Raum +ERR_NOTREGISTERED: :%s 451 %s :Du hast Dich noch nicht registriert +ERR_ACCEPTFULL: :%s 456 %s :Accept-Liste ist voll. +ERR_ACCEPTEXIST: :%s 457 %s %s :ist bereits auf Deiner Accept-Liste. +ERR_ACCEPTNOT: :%s 458 %s %s :ist nicht auf Deiner Accept-Liste. +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Nicht genug Parameter +ERR_ALREADYREGISTRED: :%s 462 %s :Erneute Registrierung nicht möglich +ERR_PASSWDMISMATCH: :%s 464 %s :Passwort falsch +ERR_YOUREBANNEDCREEP: :%s 465 %s :Zutritt zu diesem Server verweigert - %s. +ERR_CHANNELISFULL: :%s 471 %s %s :Zutritt zu diesem Raum verweigert - Raum voll (+l). +ERR_UNKNOWNMODE: :%s 472 %s %c :unbekannter Modus +ERR_INVITEONLYCHAN: :%s 473 %s %s :Zutritt zu diesem Raum nur mit Einladung möglich (+i). +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Zutritt zu diesem Raum durch Sperr-Liste verweigert (+b). +ERR_BADCHANNELKEY: :%s 475 %s %s :Zutritt zu diesem Raum nur mit richtigem Passwort möglich (+k). +ERR_BANLISTFULL: :%s 478 %s %s %s :Sperr-Liste des Raums voll. +ERR_BADCHANNAME: :%s 479 %s %s :Raum-Name nicht zulässig. +ERR_NOPRIVILEGES: :%s 481 %s :Zugriff verweigert - nur für IRC Operatoren. +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Zugriff verweigert - nur für Raum-Operatoren. +ERR_CANTKILLSERVER: :%s 483 %s :Ein Server reagiert nicht auf das KILL Kommando. +ERR_RESTRICTED: :%s 484 %s :Verbindung unterliegt Restriktionen. +ERR_NOOPERHOST: :%s 491 %s :netter Versuch - aber nur für IRC Operatoren! +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :unbekannter Modus +ERR_USERSDONTMATCH: :%s 502 %s :Modus-Änderung an anderen Benutzern nicht möglich. +ERR_GHOSTEDCLIENT: :%s 503 %s :Nachricht konnte %s nicht zugestellt werden. +ERR_USERNOTONSERV: :%s 504 %s %s :Benutzer ist nicht auf diesem Server. +ERR_WRONGPONG: :%s 513 %s :Um den Verbindungsaufbau abzuschliessen, gib ein: /QUOTE PONG %lu +ERR_LISTSYNTAX: :%s 521 %s :falscher LIST-Syntax. +ERR_HELPNOTFOUND: :%s 524 %s %s :keine Hilfe verfügbar. +RPL_WHOISSECURE: :%s 671 %s %s :ist über SSL verbunden (verschlüsselt). +RPL_ENDOFMODLIST: :%s 703 %s :Ende von /MODLIST. +RPL_ENDOFHELP: :%s 706 %s %s :Ende von /HELP. +RPL_KNOCK: :%s 710 %s %s %s!%s@%s :fragt nach einer Einladung. +RPL_KNOCKDLVR: :%s 711 %s %s :Dein KNOCK wurde zugestellt. +ERR_TOOMANYKNOCK: :%s 712 %s %s :Zuviele KNOCKs (%s). +ERR_CHANOPEN: :%s 713 %s %s :Raum ist offen. +ERR_KNOCKONCHAN: :%s 714 %s %s :Du bist bereits in diesem Raum. +RPL_TARGUMODEG: :%s 716 %s %s :ist im +g Modus (Serverseitiges Ignorieren) +RPL_TARGNOTIFY: :%s 717 %s %s :wurde über Deine Nachricht informiert. +RPL_UMODEGMSG: :%s 718 %s %s :will Dir eine Nachricht schreiben, Du hast aber Benutzer-Modus +g gesetzt. +ERR_NOPRIVS: :%s 723 %s %s :Operator-Privilegien nicht ausreichend. +RPL_TESTMASK: :%s 724 %s %s!%s@%s %u %u :lokale/entfernte Benutzer stimmen überein. +RPL_NOTESTLINE: :%s 726 %s %s :keine Übereinstimmungen gefunden. diff --git a/messages/ircd-italian.lang b/messages/ircd-italian.lang new file mode 100644 index 0000000..5beccfe --- /dev/null +++ b/messages/ircd-italian.lang @@ -0,0 +1,127 @@ +; ircd-hybrid-7 custom message file +; Copyright (C) 2007 Afaa (http://www.ircd-hybrid.it) +; Federico Giovannini <afaa@ircd-hybrid.it> +; $Id$ + +RPL_WELCOME: :%s 001 %s :Benvenuto su %s Internet Relay Chat Network %s +RPL_YOURHOST: :%s 002 %s :Hostname del server è %s, versione corrente %s +RPL_CREATED: :%s 003 %s :Questo server è stato creato il %s +RPL_ISUPPORT: :%s 005 %s %s :Sono supportati da questo server. +RPL_REDIR: :%s 010 %s %s %d :Per favore usa questo Server/Porta invece +RPL_MAPEND: :%s 017 %s :Fine del /MAP +RPL_YOURID: :%s 042 %s %s :Proprio ID univoco +RPL_TRACELINK: :%s 200 %s Link %s %s %s +RPL_TRACECONNECTING: :%s 201 %s Prova. %s %s +RPL_TRACEHANDSHAKE: :%s 202 %s H.S. %s %s +RPL_TRACEUNKNOWN: :%s 203 %s ???? %s %s (%s) %d +RPL_TRACEOPERATOR: :%s 204 %s Operatore %s %s (%s) %lu %lu +RPL_TRACEUSER: :%s 205 %s Utente %s %s (%s) %lu %lu +RPL_TRACESERVER: :%s 206 %s Server %s %dS %dC %s %s!%s@%s %lu +RPL_TRACENEWTYPE: :%s 208 %s <nuovotipo> 0 %s +RPL_TRACECLASS: :%s 209 %s Classe %s %d +RPL_ENDOFSTATS: :%s 219 %s %c :Fine del rapporto /STATS +RPL_STATSUPTIME: :%s 242 %s :Server Up %d Giorni, %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :Connessioni massime: %d (%d clients) (%llu connessioni ricevute) +RPL_LUSERCLIENT: :%s 251 %s :Sono presenti %d utenti e %d invisibili su %d servers +RPL_LUSEROP: :%s 252 %s %d :Operatori IRC Online +RPL_LUSERUNKNOWN: :%s 253 %s %d :Connessione(i) sconosciuta(e) +RPL_LUSERCHANNELS: :%s 254 %s %d :Canali presenti +RPL_LUSERME: :%s 255 %s :Sono presenti %d clients e %d servers +RPL_ADMINME: :%s 256 %s :Informazioni di Amministrazione %s +RPL_ENDOFTRACE: :%s 262 %s %s :Fine del TRACE +RPL_LOAD2HI: :%s 263 %s :Server temporaneamente occupato. Per favore attendi un momento e riprova di nuovo. +RPL_LOCALUSERS: :%s 265 %s :Utenti locali correnti: %d Max: %d +RPL_GLOBALUSERS: :%s 266 %s :Utenti globali correnti: %d Max: %d +RPL_ENDOFACCEPT: :%s 282 %s :Fine della lista /ACCEPT. +RPL_UNAWAY: :%s 305 %s :Non siete più contrassegnati come assenti. +RPL_NOWAWAY: :%s 306 %s :Siete contrassegnati come assenti. +RPL_WHOISADMIN: :%s 313 %s %s :è un Amministratore di Server +RPL_WHOISOPERATOR: :%s 313 %s %s :è un Operatore di IRC +RPL_ENDOFWHO: :%s 315 %s %s :Fine della lista /WHO. +RPL_WHOISIDLE: :%s 317 %s %s %d %d :Secondi di idle. +RPL_ENDOFWHOIS: :%s 318 %s %s :Fine della lista /WHOIS. +RPL_LISTSTART: :%s 321 %s Canale :Utente Nome +RPL_LISTEND: :%s 323 %s :Fine della /LIST (Lista) +RPL_NOTOPIC: :%s 331 %s %s :Nessun topic settato. +RPL_WHOISACTUALLY: :%s 338 %s %s %s :attualmente usa l'host: +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Fine della lista dei canali ad invito (invite). +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Fine della lista dei canali ad eccezione (exception). +RPL_CLOSING: :%s 362 %s %s :Chiuso. Status = %d +RPL_CLOSEEND: :%s 363 %s %d: Connessione chiusa. +RPL_ENDOFLINKS: :%s 365 %s %s :Fine della lista dei /LINKS. +RPL_ENDOFNAMES: :%s 366 %s %s :Fine della lista dei /NAMES. +RPL_ENDOFBANLIST: :%s 368 %s %s :Fine della lista dei ban di canale. +RPL_ENDOFWHOWAS: :%s 369 %s %s :Fine del WHOWAS +RPL_INFOSTART: :%s 373 %s :Informazioni Server +RPL_ENDOFINFO: :%s 374 %s :Fine della lista /INFO. +RPL_MOTDSTART: :%s 375 %s :- %s Messaggio del giorno - +RPL_ENDOFMOTD: :%s 376 %s :Fine del comando /MOTD. +RPL_YOUREOPER: :%s 381 %s :Sei entrato nella... Twilight Zone! (zona crepuscolare) +RPL_REHASHING: :%s 382 %s %s :Aggiornamento +RPL_HOSTHIDDEN: :%s 396 %s :Ora il tuo host è nascosto. +ERR_NOSUCHNICK: :%s 401 %s %s :nick e/o canale non presente. +ERR_NOSUCHSERVER: :%s 402 %s %s :server non presente. +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Canale non presente. +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Impossibile inviare al canale. +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Sei entrato in troppi canali. +ERR_WASNOSUCHNICK: :%s 406 %s %s :Non c'e alcun nickname +ERR_TOOMANYTARGETS: :%s 407 %s %s :Troppi destinatari. Solamente %d processato. +ERR_NOORIGIN: :%s 409 %s :Non è specificata l'origine +ERR_NORECIPIENT: :%s 411 %s :Nessun destinatario specificato (%s) +ERR_NOTEXTTOSEND: :%s 412 %s :Impossibile inviare il testo. +ERR_NOTOPLEVEL: :%s 413 %s %s :Nessun dominio toplevel è stato specificato. +ERR_WILDTOPLEVEL: :%s 414 %s %s :Carattere jolly nel dominio toplevel +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Comando sconosciuto +ERR_NOMOTD: :%s 422 %s :Non è presente il file di MOTD +ERR_NOADMININFO: :%s 423 %s %s :Informazioni amministratrive indisponibili +ERR_NONICKNAMEGIVEN: :%s 431 %s :Nessun nickname specificato. +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Nickname errato. +ERR_NICKNAMEINUSE: :%s 433 %s %s :Nickname già in uso. +ERR_NICKCOLLISION: :%s 436 %s %s :Collisione di Nickname KILL +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Il nick/canale è temporaneamente indisponibile +ERR_NICKTOOFAST: :%s 438 %s %s %s :Cambio di nick troppo veloce. Per favore attendi %d secondi. +ERR_SERVICESDOWN: :%s 440 %s :I Servizi sono attualmente non disponibili (Down) +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :L'utente non è su quel canale. +ERR_NOTONCHANNEL: :%s 442 %s %s :Non sei presente nel canale. +ERR_USERONCHANNEL: :%s 443 %s %s %s :è già presente nel canale +ERR_NOTREGISTERED: :%s 451 %s :Non sei registrato. +ERR_ACCEPTFULL: :%s 456 %s :Lista Accept è piena. +ERR_ACCEPTEXIST: :%s 457 %s %s :è già presente nella tua lista accept. +ERR_ACCEPTNOT: :%s 458 %s %s :non è presente nella tua lista accept. +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Parametri non sufficenti. +ERR_ALREADYREGISTRED: :%s 462 %s :Non è possibile registrarsi nuovamente. +ERR_PASSWDMISMATCH: :%s 464 %s :La Password non è corretta. +ERR_YOUREBANNEDCREEP: :%s 465 %s :Sei stato bannato da questo server- %s +ERR_CHANNELISFULL: :%s 471 %s %s :Non puoi entrare nel canale (+l) +ERR_UNKNOWNMODE: :%s 472 %s %c :Questo è una modalità (mode) sconosciuto per me. +ERR_INVITEONLYCHAN: :%s 473 %s %s :Impossibile entrare nel canale (+i) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Impossibile entrare nel canale (+b) +ERR_BADCHANNELKEY: :%s 475 %s %s :Impossibile entrare nel canale (+k) +ERR_BANLISTFULL: :%s 478 %s %s %s :La lista dei ban del canale e piena. +ERR_BADCHANNAME: :%s 479 %s %s :Nome canale illegale. +ERR_NOPRIVILEGES: :%s 481 %s :Permesso negato - non sei un operatore di IRC +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Non sei un operatore di canale. +ERR_CANTKILLSERVER: :%s 483 %s :Non puoi killare il server! +ERR_RESTRICTED: :%s 484 %s :Sei ristretto. +ERR_NOOPERHOST: :%s 491 %s :Solo pochi mortali meritevoli possono provare ad entrare nella twilight zone (zona crepuscolare) +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :Flag MODE sconosciuta. +ERR_USERSDONTMATCH: :%s 502 %s :Non puoi cambiare i modi di altri utenti +ERR_GHOSTEDCLIENT: :%s 503 %s :Il messaggio non è stato possibile consegnarlo a: %s +ERR_USERNOTONSERV: :%s 504 %s %s :L'utente non è presente su questo server. +ERR_WRONGPONG: :%s 513 %s :Tipo di connessione /QUOTE PONG %lu +ERR_LISTSYNTAX: :%s 521 %s :Sintassi errata Bad list syntax +ERR_HELPNOTFOUND: :%s 524 %s %s :Aiuto non trovato. +RPL_WHOISSECURE: :%s 671 %s %s :è connesso tramite SSL (Collegamento Sicuro) +RPL_ENDOFMODLIST: :%s 703 %s :Fine del /MODLIST. +RPL_ENDOFHELP: :%s 706 %s %s :Fine del /HELP. +RPL_KNOCK: :%s 710 %s %s %s!%s@%s :ha richiesto un invito. +RPL_KNOCKDLVR: :%s 711 %s %s :Il tuo messaggio è stato consegnato. +ERR_TOOMANYKNOCK: :%s 712 %s %s :Troppi messaggi (%s). +ERR_CHANOPEN: :%s 713 %s %s :Il canale è aperto. +ERR_KNOCKONCHAN: :%s 714 %s %s :Sei già presente nel canale. +RPL_TARGUMODEG: :%s 716 %s %s :è in modalità +g (Lato server ignorato) +RPL_TARGNOTIFY: :%s 717 %s %s :siete informati che avete inviato un messaggio a loro. +RPL_UMODEGMSG: :%s 718 %s %s :Vi è arrivato un messaggio e voi siete senza modalita +g. +ERR_NOPRIVS: :%s 723 %s %s :Privilegi di Oper insufficienti. +RPL_TESTMASK: :%s 724 %s %s!%s@%s %u %u :Locale/remoto clients corrispondente. +RPL_NOTESTLINE: :%s 726 %s %s :Nessuna corrispondenza diff --git a/messages/ircd-norwegian.lang b/messages/ircd-norwegian.lang new file mode 100644 index 0000000..e70168c --- /dev/null +++ b/messages/ircd-norwegian.lang @@ -0,0 +1,90 @@ +; SOME DESCRIPTIVE TITLE. +; Copyright (C) YEAR Free Software Foundation, Inc. +; FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +; $Id$ + +RPL_WELCOME: :%s 001 %s :Velkommen til %s Internet Relay Nettverket %s +RPL_YOURHOST: :%s 002 %s :Verten din er %s, som bruker versjon %s +RPL_CREATED: :%s 003 %s :Serveren ble kompilert %s +RPL_ISUPPORT: :%s 005 %s %s :er gyldig for denne serveren +RPL_REDIR: :%s 010 %s %s %d :Vennligst bruk Server/Port istedenfor +RPL_TRACECONNECTING: :%s 201 %s Prøv. %s %s +RPL_TRACEHANDSHAKE: :%s 202 %s T.S. %s %s +RPL_TRACEUSER: :%s 205 %s Bruker %s %s (%s) %lu %lu +RPL_TRACENEWTYPE: :%s 208 %s <nytype> 0 %s +RPL_TRACECLASS: :%s 209 %s Klasse %s %d +RPL_STATSUPTIME: :%s 242 %s :Serveren har vært oppe %d dager, %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :Høyeste tilkoblings telling: %d (%d klienter) (%llu tilkoblinger received) +RPL_LUSERCLIENT: :%s 251 %s :Det er %d brukere og %d usynlige på %d serverere +RPL_LUSEROP: :%s 252 %s %d :IRC Operatører online +RPL_LUSERUNKNOWN: :%s 253 %s %d :ukjente tilkoblinger +RPL_LUSERCHANNELS: :%s 254 %s %d :kanaler laget +RPL_LUSERME: :%s 255 %s :Jeg har %d klienter og %d serverere +RPL_ADMINME: :%s 256 %s :Administrativ informasjon om %s +RPL_ENDOFTRACE: :%s 262 %s %s :Slutten av TRACE +RPL_LOAD2HI: :%s 263 %s :Server lasten er for tiden for høy. Vennligst vent litt og prøv igjen. +RPL_LOCALUSERS: :%s 265 %s :Lokale brukere nå: %d Maks: %d +RPL_GLOBALUSERS: :%s 266 %s :Globale brukere nå: %d Maks: %d +RPL_UNAWAY: :%s 305 %s :Du er ikke lenger markert som vekke (away) +RPL_NOWAWAY: :%s 306 %s :Du har blitt markert som vekke (away) +RPL_WHOISIDLE: :%s 317 %s %s %d %d :sekunder uaktiv, påloggings tid +RPL_ENDOFWHOIS: :%s 318 %s %s :Slutten av /WHOIS listen. +RPL_LISTSTART: :%s 321 %s Kanal :Bruker Navn +RPL_LISTEND: :%s 323 %s :Slutten av /LIST +RPL_NOTOPIC: :%s 331 %s %s :Ingen topic (overskrift) er satt. +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Slutten av Kanal Invite List (Inviterte Listen) +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Slutten av Kanal Exception List (Unntaks Listen) +RPL_CLOSING: :%s 362 %s %s :Lukket. Status = %d +RPL_CLOSEEND: :%s 363 %s %d: Tilkobling Stengt +RPL_ENDOFLINKS: :%s 365 %s %s :Slutten av /LINKS listen. +RPL_ENDOFNAMES: :%s 366 %s %s :Slutten av /NAMES listen. +RPL_ENDOFBANLIST: :%s 368 %s %s :Slutten av Kanal Ban List (Utestengt Listen) +RPL_ENDOFWHOWAS: :%s 369 %s %s :Slutten av WHOWAS +RPL_ENDOFINFO: :%s 374 %s :Slutten av /INFO listen. +RPL_MOTDSTART: :%s 375 %s :- %s Beskjed for Dagen - +RPL_ENDOFMOTD: :%s 376 %s :Slutten av /MOTD kommandoen. +RPL_YOUREOPER: :%s 381 %s :Du har nå kommet inn i... det Forbudte Området! (Twilight Zone!). +ERR_NOSUCHNICK: :%s 401 %s %s :Ikke noen slik bruker/kanal +ERR_NOSUCHSERVER: :%s 402 %s %s :Ikke noen slik server +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Ikke noen slik kanal +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Kan ikke sende til kanalen +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Du har gått på (joined) for mange kanaler +ERR_WASNOSUCHNICK: :%s 406 %s %s :Det var ikke noen slik kallenavn (nickname) +ERR_TOOMANYTARGETS: :%s 407 %s %s :For mange mottakere. Bare %d gikk gjennom +ERR_NOORIGIN: :%s 409 %s :Ingen opprinnelse spesifisert +ERR_NORECIPIENT: :%s 411 %s :Ingen mottaker definert (%s) +ERR_NOTEXTTOSEND: :%s 412 %s :Ingen tekst å sende +ERR_NOTOPLEVEL: :%s 413 %s %s :Ingen øverste-nivå domene (toplevel domain) spesifisert +ERR_WILDTOPLEVEL: :%s 414 %s %s :Uspesifisert i øverste-nivå domene (toplevel domain) +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Ukjent kommando +ERR_NOMOTD: :%s 422 %s :MOTD Filen mangler +ERR_NOADMININFO: :%s 423 %s %s :Ingen administrativ info tilgjengelig +ERR_NONICKNAMEGIVEN: :%s 431 %s :Ingen kallenavn (nickname) definert +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Feilaktig Kallenavn (Nickname) +ERR_NICKNAMEINUSE: :%s 433 %s %s :Kallenavnet (Nickname) er allered i bruk. +ERR_NICKCOLLISION: :%s 436 %s %s :Kallenavn (Nickname) kollisjon KILL +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Kallenavnet/Kanalen er midlertidig utilgjengelig +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :De er ikke på den kanalen +ERR_NOTONCHANNEL: :%s 442 %s %s :Du er ikke på den kanalen +ERR_USERONCHANNEL: :%s 443 %s %s %s :er allered på kanalen +ERR_NOTREGISTERED: :%s 451 %s :Du har ikke registrert +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Ikke nok verdier (parameters) +ERR_ALREADYREGISTRED: :%s 462 %s :Du kan ikke registrere +ERR_PASSWDMISMATCH: :%s 464 %s :Passordet var inkorrekt +ERR_YOUREBANNEDCREEP: :%s 465 %s :Du er utestengt fra denne serveren- %s +ERR_CHANNELISFULL: :%s 471 %s %s :Kan ikke komme inn i kanalen (+l) +ERR_UNKNOWNMODE: :%s 472 %s %c :er en ukjent modus tegn for meg +ERR_INVITEONLYCHAN: :%s 473 %s %s :Kan ikke komme inn i kanalen (+i) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Kan ikke komme inn i kanalen (+b) +ERR_BADCHANNELKEY: :%s 475 %s %s :Kan ikke komme inn i kanalen (+k) +ERR_BANLISTFULL: :%s 478 %s %s %s :Kanalens utestengings liste er full +ERR_BADCHANNAME: :%s 479 %s %s :Ulovlig kanal navn +ERR_NOPRIVILEGES: :%s 481 %s :Tillatelse nektet - Du er ikke en IRC operatør +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Du er ikke en kanal operatør +ERR_CANTKILLSERVER: :%s 483 %s :Du kan ikke drepe (kill) en server! +ERR_RESTRICTED: :%s 484 %s :Du er begrenset +ERR_NOOPERHOST: :%s 491 %s :Kun få dødelige kan prøve å komme inn i det forbudte området (twilight zone) +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :Ukjent MODE flag +ERR_USERSDONTMATCH: :%s 502 %s :Kan ikke forandre modus på andre brukere +ERR_GHOSTEDCLIENT: :%s 503 %s :Beskjeden kunne ikke bli levert til %s +ERR_USERNOTONSERV: :%s 504 %s %s :Bruker er ikke på denne serveren diff --git a/messages/ircd-polish.lang b/messages/ircd-polish.lang new file mode 100644 index 0000000..f84e19d --- /dev/null +++ b/messages/ircd-polish.lang @@ -0,0 +1,108 @@ +; ircd-hybrid-7 custom message file +; Copyright (C) 2003-2005, Piotr Ni¿yñski <nizynski@sysplex.pl> +; Coding: ISO-8859-2 * CP-1250 +; $Id$ + +RPL_WELCOME: :%s 001 %s :Witaj w sieci IRC %s, %s +RPL_YOURHOST: :%s 002 %s :Twój host to %s, obecna wersja %s +RPL_CREATED: :%s 003 %s :Ten serwer zosta³ utworzony %s +RPL_ISUPPORT: :%s 005 %s %s :sa obs³ugiwane przez ten serwer +RPL_REDIR: :%s 010 %s %s %d :Proszê u¿ywaæ tego serwera/portu +RPL_MAPEND: :%s 017 %s :Koniec /MAP +RPL_YOURID: :%s 042 %s %s :Twój unikalny ID +RPL_ENDOFSTATS: :%s 219 %s %c :Koniec raportu /STATS +RPL_STATSUPTIME: :%s 242 %s :Serwer dzia³a %d dni, %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :Najwy¿sza liczba po³aczeñ: %d (%d klientów) (%llu od startu serwera) +RPL_LUSERCLIENT: :%s 251 %s :Jest %d u¿ytkowników i %d niewidzialnych na %d serwerach +RPL_LUSEROP: :%s 252 %s %d :aktywnych IRC Operatorów +RPL_LUSERUNKNOWN: :%s 253 %s %d :- liczba niezarejestrowanych po³aczeñ +RPL_LUSERCHANNELS: :%s 254 %s %d :- liczba utworzonych kana³ów +RPL_LUSERME: :%s 255 %s :Mam %d po³aczonych klientów, serwerów: %d +RPL_ADMINME: :%s 256 %s :Informacje administracyjne o %s +RPL_LOAD2HI: :%s 263 %s :Obcia¿enie serwera jest chwilowo zbyt du¿e. Proszê zaczekaæ chwilê i spróbowaæ ponownie. +RPL_LOCALUSERS: :%s 265 %s :Liczba lokalnych u¿ytkowników: %d Rekord: %d +RPL_GLOBALUSERS: :%s 266 %s :Liczba globalnych u¿ytkowników: %d Rekord: %d +RPL_ENDOFACCEPT: :%s 282 %s :Koniec listy /ACCEPT. +RPL_UNAWAY: :%s 305 %s :Zdjêto flagê nieobecnosci +RPL_NOWAWAY: :%s 306 %s :Ustawiono flagê nieobecnosci +RPL_WHOISADMIN: :%s 313 %s %s :jest administratorem serwera +RPL_WHOISOPERATOR: :%s 313 %s %s :jest operatorem IRC +RPL_ENDOFWHO: :%s 315 %s %s :Koniec listy /WHO. +RPL_WHOISIDLE: :%s 317 %s %s %d %d :sekund bezczynnosci, czas zalogowania +RPL_ENDOFWHOIS: :%s 318 %s %s :Koniec listy /WHOIS. +RPL_LISTSTART: :%s 321 %s Kana³ :U¿ytkownicy Temat +RPL_LISTEND: :%s 323 %s :Koniec /LIST +RPL_NOTOPIC: :%s 331 %s %s :Brak ustawionego tematu. +RPL_WHOISACTUALLY: :%s 338 %s %s %s :w rzeczywistosci u¿ywa hosta +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Koniec listy zaproszeñ kana³owych +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Koniec listy wyjatków kana³owych +RPL_ENDOFLINKS: :%s 365 %s %s :Koniec listy /LINKS. +RPL_ENDOFNAMES: :%s 366 %s %s :Koniec listy /NAMES. +RPL_ENDOFBANLIST: :%s 368 %s %s :Koniec listy banów kana³owych +RPL_ENDOFWHOWAS: :%s 369 %s %s :Koniec /WHOWAS +RPL_INFOSTART: :%s 373 %s :Informacje o serwerze +RPL_ENDOFINFO: :%s 374 %s :Koniec listy /INFO. +RPL_ENDOFMOTD: :%s 376 %s :Koniec komendy /MOTD. +RPL_HOSTHIDDEN: :%s 396 %s %s :zastêpuje teraz Twój host +ERR_NOSUCHNICK: :%s 401 %s %s :Nie ma takiego nicka/kana³u +ERR_NOSUCHSERVER: :%s 402 %s %s :Nie ma takiego serwera +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Nie ma takiego kana³u +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Nie mo¿na wys³aæ na kana³ +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Masz zbyt du¿o otwartych kana³ów +ERR_WASNOSUCHNICK: :%s 406 %s %s :Nie by³o takiego nicka +ERR_TOOMANYTARGETS: :%s 407 %s %s :Zbyt wiele adresatów. Obs³u¿ono tylko %d +ERR_NOORIGIN: :%s 409 %s :Nie podano zród³a +ERR_NORECIPIENT: :%s 411 %s :Nie podano adresata (%s) +ERR_NOTEXTTOSEND: :%s 412 %s :Brak tekstu do wys³ania +ERR_NOTOPLEVEL: :%s 413 %s %s :Nie podano TLD +ERR_WILDTOPLEVEL: :%s 414 %s %s :W TLD nie mo¿e byæ znaków maskujacych +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Nieznana komenda +ERR_NOMOTD: :%s 422 %s :Brakuje pliku MOTD +ERR_NOADMININFO: :%s 423 %s %s :Brak dostêpnych informacji administracyjnych +ERR_NONICKNAMEGIVEN: :%s 431 %s :Nie podano nicka +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Nieprawid³owy nick +ERR_NICKNAMEINUSE: :%s 433 %s %s :Nick jest zajêty. +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Nick/kana³ jest tymczasowo niedostêpny +ERR_NICKTOOFAST: :%s 438 %s %s %s :Zbyt szybka zmiana nicka. Proszê odczekaæ %d sekund. +ERR_SERVICESDOWN: :%s 440 %s :Serwisy sa obecnie niedostêpne +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :Nie ma takiego u¿ytkownika na tym kanale +ERR_NOTONCHANNEL: :%s 442 %s %s :Nie jestes na tym kanale +ERR_USERONCHANNEL: :%s 443 %s %s %s :jest ju¿ na kanale +ERR_NOTREGISTERED: :%s 451 %s :Twoje po³aczenie nie jest jeszcze zarejestrowane +ERR_ACCEPTFULL: :%s 456 %s :Lista ACCEPT jest przepe³niona +ERR_ACCEPTEXIST: :%s 457 %s %s :jest ju¿ na Twojej liscie ACCEPT +ERR_ACCEPTNOT: :%s 458 %s %s :nie jest na Twojej liscie ACCEPT +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Za ma³o parametrów +ERR_ALREADYREGISTRED: :%s 462 %s :Nie mo¿esz zarejestrowaæ siê ponownie +ERR_PASSWDMISMATCH: :%s 464 %s :Nieprawid³owe has³o +ERR_CHANNELISFULL: :%s 471 %s %s :Nie mo¿na wejsc na kana³ (+l) +ERR_UNKNOWNMODE: :%s 472 %s %c :to dla mnie nieznany tryb +ERR_INVITEONLYCHAN: :%s 473 %s %s :Nie mo¿na wejsc na kana³ (+i) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Nie mo¿na wejsc na kana³ (+b) +ERR_BADCHANNELKEY: :%s 475 %s %s :Nie mo¿na wejsc na kana³ (+k) +ERR_BANLISTFULL: :%s 478 %s %s %s :Lista banów kana³owych jest przepe³niona +ERR_BADCHANNAME: :%s 479 %s %s :Niedopuszczalna nazwa kana³u +ERR_NOPRIVILEGES: :%s 481 %s :Brak uprawnieñ - nie jestes IRC Operatorem +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Nie jestes operatorem kana³u +ERR_RESTRICTED: :%s 484 %s :Twoje po³aczenie jest objête restrykcja +ERR_NOOPERHOST: :%s 491 %s :Tylko nieliczni smiertelnicy moga uzyskaæ prawa IRC Operatora +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :Nieznana flaga MODE +ERR_USERSDONTMATCH: :%s 502 %s :Nie mo¿esz zmieniaæ trybów innych u¿ytkowników +ERR_GHOSTEDCLIENT: :%s 503 %s :Wiadomosc dla %s nie mo¿e byæ dostarczona +ERR_USERNOTONSERV: :%s 504 %s %s :U¿ytkownik nie korzysta z tego serwera +ERR_WRONGPONG: :%s 513 %s :Aby siê po³aczyæ, wpisz /QUOTE PONG %lu +ERR_LISTSYNTAX: :%s 521 %s :Z³a sk³adnia dla LIST, wpisz /QUOTE HELP LIST +ERR_HELPNOTFOUND: :%s 524 %s %s :Nie odnaleziono pomocy +RPL_WHOISSECURE: :%s 671 %s %s :u¿ywa SSL (bezpiecznego po³aczenia) +RPL_ENDOFHELP: :%s 706 %s %s :Koniec /HELP. +RPL_KNOCK: :%s 710 %s %s %s!%s@%s :prosi o zaproszenie. +RPL_KNOCKDLVR: :%s 711 %s %s :Twój KNOCK zosta³ dostarczony. +ERR_TOOMANYKNOCK: :%s 712 %s %s :Zbyt wiele KNOCK (%s). +ERR_CHANOPEN: :%s 713 %s %s :Kana³ jest otwarty. +ERR_KNOCKONCHAN: :%s 714 %s %s :Jestes ju¿ na tym kanale. +RPL_TARGUMODEG: :%s 716 %s %s :jest w trybie +g (server side ignore) +RPL_TARGNOTIFY: :%s 717 %s %s :U¿ytkownik zosta³ poinformowany, ¿e do niego pisano. +RPL_UMODEGMSG: :%s 718 %s %s :pisze do Ciebie, ale jestes w trybie +g. +ERR_NOPRIVS: :%s 723 %s %s :Za ma³e uprawnienia operatora. +RPL_TESTMASK: :%s 724 %s %s!%s@%s %u %u :Lokalnych/zdalnych pasujacych klientów. +RPL_NOTESTLINE: :%s 726 %s %s :Brak pasujacych diff --git a/messages/ircd-romanian.lang b/messages/ircd-romanian.lang new file mode 100644 index 0000000..682a621 --- /dev/null +++ b/messages/ircd-romanian.lang @@ -0,0 +1,126 @@ +; ircd-hybrid-7 standard message file - for Romanian +; Copyright (C) 2007 Bogdan Mintoi <bogdomania@yahoo.com> +; $Id$ +; + +RPL_WELCOME: :%s 001 %s :Bine ai venit pe reteaua ValceaNet %s +RPL_YOURHOST: :%s 002 %s :Gazda ta este %s, ruland versiunea %s +RPL_CREATED: :%s 003 %s :Acest server a fost creat la data/ora %s +RPL_ISUPPORT: :%s 005 %s %s :sunt suportate de acest server +RPL_REDIR: :%s 010 %s %s %d :Foloseste acest Server/Port in schimb +RPL_MAPEND: :%s 017 %s :Sfarsitul /MAP +RPL_YOURID: :%s 042 %s %s :ID tau unic +RPL_TRACELINK: :%s 200 %s Link %s %s %s +RPL_TRACECONNECTING: :%s 201 %s Try. %s %s +RPL_TRACEHANDSHAKE: :%s 202 %s H.S. %s %s +RPL_TRACEUNKNOWN: :%s 203 %s ???? %s %s (%s) %d +RPL_TRACEOPERATOR: :%s 204 %s Oper %s %s (%s) %lu %lu +RPL_TRACEUSER: :%s 205 %s User %s %s (%s) %lu %lu +RPL_TRACESERVER: :%s 206 %s Serv %s %dS %dC %s %s!%s@%s %lu +RPL_TRACENEWTYPE: :%s 208 %s <noultip> 0 %s +RPL_TRACECLASS: :%s 209 %s Clasa %s %d +RPL_ENDOFSTATS: :%s 219 %s %c :Sfarsitul /STATS report +RPL_STATSUPTIME: :%s 242 %s :Server Up %d days, %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :Numarul maxim de conexiuni: %d (%d clienti) (%llu conexiuni primite) +RPL_LUSERCLIENT: :%s 251 %s :Exista %d utilizatori si %d invizibili pe %d servere +RPL_LUSEROP: :%s 252 %s %d :IRC Operatori prezenti +RPL_LUSERUNKNOWN: :%s 253 %s %d :conexiuni necunoscute +RPL_LUSERCHANNELS: :%s 254 %s %d :canale formate +RPL_LUSERME: :%s 255 %s :Exista %d clienti si %d servere +RPL_ADMINME: :%s 256 %s :Informatii administrative despre %s +RPL_ENDOFTRACE: :%s 262 %s %s :Sfarsitul TRACE +RPL_LOAD2HI: :%s 263 %s :Serverul este momentan prea incarcat. Reancearca mai tarziu. +RPL_LOCALUSERS: :%s 265 %s :Utilizatori locali actuali: %d Max: %d +RPL_GLOBALUSERS: :%s 266 %s :Utilizatori globali actuali: %d Max: %d +RPL_ENDOFACCEPT: :%s 282 %s :Sfarsitul listei /ACCEPT +RPL_UNAWAY: :%s 305 %s :Nu mai esti marcat(a) ca fiind away. +RPL_NOWAWAY: :%s 306 %s :Esti marcat(a) ca fiind away. +RPL_WHOISADMIN: :%s 313 %s %s :este un Administrator de Server +RPL_WHOISOPERATOR: :%s 313 %s %s :este un IRC Operator +RPL_ENDOFWHO: :%s 315 %s %s :Sfarsitul listei /WHO +RPL_WHOISIDLE: :%s 317 %s %s %d %d :seconds idle +RPL_ENDOFWHOIS: :%s 318 %s %s :Sfarsitul listei /WHOIS +RPL_LISTSTART: :%s 321 %s Canal :Useri Nume +RPL_LISTEND: :%s 323 %s :Sfarsitul /LIST +RPL_NOTOPIC: :%s 331 %s %s :Nu este setat nici un topic. +RPL_WHOISACTUALLY: :%s 338 %s %s %s :in prezent folosind host-ul +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Sfarsitul Liestei de Invite a Canalului +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Sfarsitul Listei de Exceptii a Canalului +RPL_CLOSING: :%s 362 %s %s :Inchis. Status = %d +RPL_CLOSEEND: :%s 363 %s %d: Conexiuni inchise +RPL_ENDOFLINKS: :%s 365 %s %s :Sfarsitul listei /LINKS +RPL_ENDOFNAMES: :%s 366 %s %s :Sfarsitul listei /NAMES +RPL_ENDOFBANLIST: :%s 368 %s %s :Sfarsitul Listei de Ban-uri a Canalului +RPL_ENDOFWHOWAS: :%s 369 %s %s :Sfarsitul WHOWAS +RPL_INFOSTART: :%s 373 %s :Server INFO +RPL_ENDOFINFO: :%s 374 %s :Sfarsitul listei /INFO +RPL_MOTDSTART: :%s 375 %s :- %s Mesajul zilei - +RPL_ENDOFMOTD: :%s 376 %s :Sfarsitul /MOTD +RPL_YOUREOPER: :%s 381 %s :Moduri setate-esti un IRCop +RPL_REHASHING: :%s 382 %s %s :Se executa comanda Rehash +RPL_HOSTHIDDEN: :%s 396 %s :este acum noul tau host +ERR_NOSUCHNICK: :%s 401 %s %s :Nu exista acel nick sau canal +ERR_NOSUCHSERVER: :%s 402 %s %s :Nu exista acel server +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Nu exista acel canal +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Nu poti trimite pe canal +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Te-ai alaturat prea multor canale +ERR_WASNOSUCHNICK: :%s 406 %s %s :Nu a existat un asemenea nickname +ERR_TOOMANYTARGETS: :%s 407 %s %s :Prea multe recipiente date. Doar %d procesate +ERR_NOORIGIN: :%s 409 %s :Nu a fost specificata nici o origine +ERR_NORECIPIENT: :%s 411 %s :Nu a fost specificat nici un recipient (%s) +ERR_NOTEXTTOSEND: :%s 412 %s :Nu exista text de trimis +ERR_NOTOPLEVEL: :%s 413 %s %s :Nici un domeniu TopLevel specificat +ERR_WILDTOPLEVEL: :%s 414 %s %s :Wildcard in Domeniul TopLevel +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Comanda nerecunoscuta +ERR_NOMOTD: :%s 422 %s :Fisierul MOTD lipseste sau nu este activat +ERR_NOADMININFO: :%s 423 %s %s :Nu este disponibila nici o informatie administrativa +ERR_NONICKNAMEGIVEN: :%s 431 %s :Nici un nickname specificat +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Nickname gresit +ERR_NICKNAMEINUSE: :%s 433 %s %s :Nickname ales este deja folosit.Alege un alt nickname. +ERR_NICKCOLLISION: :%s 436 %s %s :Coliziune de nickname - KILL +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Nickul sau canalul specificat este indisponibil temporar +ERR_NICKTOOFAST: :%s 438 %s %s %s :Incercare de a schimba nick-ul prea rapida. Asteapta %d secunde. +ERR_SERVICESDOWN: :%s 440 %s :Serviciile sunt dezactivate temporar. +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :Nu se afla pe acel canal +ERR_NOTONCHANNEL: :%s 442 %s %s :Nu te afli pe acel canal +ERR_USERONCHANNEL: :%s 443 %s %s %s :este deja pe canal +ERR_NOTREGISTERED: :%s 451 %s :Nu esti autentificat(a) +ERR_ACCEPTFULL: :%s 456 %s :Lista de accepturi este plina +ERR_ACCEPTEXIST: :%s 457 %s %s :se afla deja in lista ta de accepturi +ERR_ACCEPTNOT: :%s 458 %s %s :nu se afla in lista ta de accepturi +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Parametri insuficienti +ERR_ALREADYREGISTRED: :%s 462 %s :Esti deja autentificat(a) +ERR_PASSWDMISMATCH: :%s 464 %s :Parola incorecta +ERR_YOUREBANNEDCREEP: :%s 465 %s :Esti momentan banat(a) pe acest server- %s +ERR_CHANNELISFULL: :%s 471 %s %s :Nu poti intra pe canal (+l) +ERR_UNKNOWNMODE: :%s 472 %s %c :este un caracter nerecunoscut de sistem +ERR_INVITEONLYCHAN: :%s 473 %s %s :Nu poti intra pe canal (+i) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Nu poti intra pe canal (+b) +ERR_BADCHANNELKEY: :%s 475 %s %s :Nu poti intra pe canal (+k) +ERR_BANLISTFULL: :%s 478 %s %s %s :Lista de banuri a canalului este plina +ERR_BADCHANNAME: :%s 479 %s %s :Nume de canal ilegal +ERR_NOPRIVILEGES: :%s 481 %s :Imposibil de executat - Nu esti un IRCop +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Nu esti un operator de canal +ERR_CANTKILLSERVER: :%s 483 %s :Nu poti efectua kill unui server! +ERR_RESTRICTED: :%s 484 %s :parametri limitati pentru host-ul tau +ERR_NOOPERHOST: :%s 491 %s :Incercare de autentificare ca IRCop esuata. +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :MODE necunoscut +ERR_USERSDONTMATCH: :%s 502 %s :Nu se pot modifica modurile pentru alti utilizatori +ERR_GHOSTEDCLIENT: :%s 503 %s :Mesajul nu a fost trimis catre %s +ERR_USERNOTONSERV: :%s 504 %s %s :Userul nu se afla pe acest server +ERR_WRONGPONG: :%s 513 %s :Pentru a te conecta tasteaza /QUOTE PONG %lu +ERR_LISTSYNTAX: :%s 521 %s :Sintaxa eronata +ERR_HELPNOTFOUND: :%s 524 %s %s :Help- nu a fost gasit +RPL_WHOISSECURE: :%s 671 %s %s :este conectat prin SSL (conexiune securizata) +RPL_ENDOFMODLIST: :%s 703 %s :Sfarsitul /MODLIST. +RPL_ENDOFHELP: :%s 706 %s %s :Sfarsitul /HELP. +RPL_KNOCK: :%s 710 %s %s %s!%s@%s :a cerut invite. +RPL_KNOCKDLVR: :%s 711 %s %s :KNOCK-ul tau a fost livrat. +ERR_TOOMANYKNOCK: :%s 712 %s %s :Prea multe KNOCK (%s). +ERR_CHANOPEN: :%s 713 %s %s :Canalul este deschis. +ERR_KNOCKONCHAN: :%s 714 %s %s :Te afli deja pe acel canal. +RPL_TARGUMODEG: :%s 716 %s %s :se afla in modul +g (server side ignore) +RPL_TARGNOTIFY: :%s 717 %s %s :has been informed that you messaged them. +RPL_UMODEGMSG: :%s 718 %s %s :iti trimite mesaj,si tu ai setat umode +g. +ERR_NOPRIVS: :%s 723 %s %s :privilegii de operator insuficiente. +RPL_NOTESTLINE: :%s 726 %s %s :Nu exista potriviri diff --git a/messages/ircd-russian.lang b/messages/ircd-russian.lang new file mode 100644 index 0000000..dbbbb5c --- /dev/null +++ b/messages/ircd-russian.lang @@ -0,0 +1,93 @@ +; ircd-hybrid-7 custom message file +; Copyright (C) 2003 +; Ilya Shtift <ishtift@tagil.svrw.ru>, 2003. +; $Id$ + +RPL_WELCOME: :%s 001 %s :Äîáðî ïîæàëîâàòü â %s Internet Relay Chat Network %s +RPL_YOURHOST: :%s 002 %s :Âàø ñåðâåð %s, âåðñèÿ %s +RPL_CREATED: :%s 003 %s :Ýòîò ñåðâåð áûë ñîçäàí %s +RPL_ISUPPORT: :%s 005 %s %s :ïîääåðæèâàåòñÿ ýòèì ñåðâåðîì +RPL_REDIR: :%s 010 %s %s %d :Ïîæàëóéñòà èñïîëüçóéòå ýòîò ñåðâåð/ïîðò +RPL_MAPEND: :%s 017 %s :Çàâåðøåíèå /MAP +RPL_ENDOFSTATS: :%s 219 %s %c :Çàâåðøåíèå âûâîäà îò÷åòà /STATS +RPL_STATSUPTIME: :%s 242 %s :Ñåðâåð ðàáîòàåò %d äíåé, %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :Íàèáîëüøåå êîëè÷åñòâî ñîåäèíåíèé: %d (%d êëèåíòîâ) (%llu âõîäÿùèõ ñîåäèíåíèé) +RPL_LUSERCLIENT: :%s 251 %s :Çäåñü %d ïîëüçîâàòåëåé è %d íåâèäèìûõ íà %d ñåðâåðàõ +RPL_LUSEROP: :%s 252 %s %d :IRC Îïåðàòîðîâ â íàøåé ñåòè +RPL_LUSERUNKNOWN: :%s 253 %s %d :íåèçâåñòíûõ ñîåäèíåíèé +RPL_LUSERCHANNELS: :%s 254 %s %d :ñôîðìèðîâàíî êàíàëîâ +RPL_LUSERME: :%s 255 %s :Ê ñåðâåðó ïîäêëþ÷åííî %d êëèåíòîâ è %d ñåðâåðîâ +RPL_ADMINME: :%s 256 %s :Èíôîðìàöèÿ îá àäìèíèñòðàòîðå %s +RPL_ENDOFTRACE: :%s 262 %s %s :Çàâåðøåíèå TRACE +RPL_LOAD2HI: :%s 263 %s :Ñåðâåð âðåìåííî ïåðåãðóæåí. Ïîïðîáóéòå ïîâòîðèòü ïîïûòêó åùå ðàç íåìíîãî ïîçæå. +RPL_LOCALUSERS: :%s 265 %s :Òåêóùèå êîëè÷åñòâî ëîêàëüíûõ ïîëüçîâàòåëåé: %d Ìàêñèìàëüíîå: %d +RPL_GLOBALUSERS: :%s 266 %s :Òåêóùèå êîëè÷åñòâî ãëîáàëüíûõ ïîëüçîâàòåëåé: %d Ìàêñèìàëüíîå: %d +RPL_UNAWAY: :%s 305 %s :Òåïåðü Âû íå îòìå÷åíû êàê away +RPL_NOWAWAY: :%s 306 %s :Òåïåðü Âû îòìå÷åíû êàê away +RPL_ENDOFWHO: :%s 315 %s %s :Çàâåðøåíèå âûâîäà ñïèñêà /WHO +RPL_WHOISIDLE: :%s 317 %s %s %d %d :ñåêóíä ìîë÷èò, âðåìÿ ïîäêëþ÷åíèÿ +RPL_ENDOFWHOIS: :%s 318 %s %s :Çàâåðøåíèå âûâîäà ñïèñêà /WHOIS. +RPL_LISTEND: :%s 323 %s :Çàâåðøåíèå âûâîäà /LIST +RPL_NOTOPIC: :%s 331 %s %s :Òîïèê íå óñòàíîâëåí. +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Çàâåðøåíèå âûâîäà ñïèñêà Ïðèãëàøåíèÿ Êàíàëà +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Çàâåðøåíèå âûâîäà ñïèñêà Èñêëþ÷åíèÿ Êàíàëà +RPL_CLOSING: :%s 362 %s %s :Çàêðûòî. Ñòàòóñ = %d +RPL_CLOSEEND: :%s 363 %s %d :Ñîåäèíåíèÿ çàêðûòû +RPL_ENDOFLINKS: :%s 365 %s %s :Çàâåðøåíèå âûâîäà ñïèñêà /LINKS. +RPL_ENDOFNAMES: :%s 366 %s %s :Çàâåðøåíèå âûâîäà ñïèñêà /NAMES. +RPL_ENDOFBANLIST: :%s 368 %s %s :Çàâåðøåíèå âûâîäà ñïèñêà Áàíîâ Êàíàëà +RPL_ENDOFWHOWAS: :%s 369 %s %s :Çàâåðøåíèå âûâîäà WHOWAS +RPL_ENDOFINFO: :%s 374 %s :Çàâåðøåíèå âûâîäà ñïèñêà /INFO +RPL_MOTDSTART: :%s 375 %s :- %s Ñîîáùåíèå äíÿ - +RPL_ENDOFMOTD: :%s 376 %s :Çàâåðøåíèå âûâîäà êîìàíäû /MOTD. +RPL_REHASHING: :%s 382 %s %s :Ïåðå÷èòûâàåòñÿ ôàéë êîíôèãóðàöèè +ERR_NOSUCHNICK: :%s 401 %s %s :Íèê/êàíàë íå íàéäåí +ERR_NOSUCHSERVER: :%s 402 %s %s :Ñåðâåð íå íàéäåí +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Êàíàë íå íàéäåí +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Íåâîçìîæíî ïåðåäàòü íà êàíàë +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Âû óæå çàøëè íà ìàêñèìàëüíî âîçìîæíîå êîëè÷åñòâî êàíàëîâ +ERR_WASNOSUCHNICK: :%s 406 %s %s :Çäåñü íå íàõîäèëñÿ ýòîò íèê +ERR_NOORIGIN: :%s 409 %s :Èñòî÷íèê íå áûë îïåðåäåëåí +ERR_NOTEXTTOSEND: :%s 412 %s :Âû íå óêàçàëè òåêñò äëÿ îòïðàâêè +ERR_NOTOPLEVEL: :%s 413 %s %s :Íå óêàçàí äîìåí âåðõíåãî óðîâíÿ +ERR_WILDTOPLEVEL: :%s 414 %s %s :Wildcard ñèìâîë â äîìåíå âåðõíåãî óðîâíÿ +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Íåèçâåñòíàÿ êîìàíäà +ERR_NOMOTD: :%s 422 %s :Ôàéë MOTD íå íàéäåí +ERR_NOADMININFO: :%s 423 %s %s :Èíôîðìàöèÿ îá àäìèíèñòðàòîðå íå äîñòóïíà +ERR_NONICKNAMEGIVEN: :%s 431 %s :Âû íå óêàçàëè íèê +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Íåâåðíûé íèê +ERR_NICKNAMEINUSE: :%s 433 %s %s :Ýòîò íèê óæå èñïîëüçóåòñÿ. +ERR_NICKCOLLISION: :%s 436 %s %s :Êîëëèçèÿ íèêà KILL +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Íèê/êàíàë âðåìåííî íåäîñòóïåí +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :Îí íå íàõîäèòñÿ íà ýòîì êàíàëå +ERR_NOTONCHANNEL: :%s 442 %s %s :Âû íå íàõîäèòåñü íà ýòîì êàíàëå +ERR_USERONCHANNEL: :%s 443 %s %s %s :âû óæå íàõîäèòåñü íà êàíàëå +ERR_NOTREGISTERED: :%s 451 %s :Âû íå çàðåãèñòðèðîâàëèñü +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Ñëèøêîì ìàëî ïàðàìåòðîâ +ERR_ALREADYREGISTRED: :%s 462 %s :Âû íå ìîæåòå çàðåãèñòðèðîâàòñÿ +ERR_PASSWDMISMATCH: :%s 464 %s :Íåâåðíûé ïàðîëü +ERR_YOUREBANNEDCREEP: :%s 465 %s :Âû çàáàíåíû íà ýòîì ñåðâåðå- %s +ERR_CHANNELISFULL: :%s 471 %s %s :Íåâîçìîæíî çàéòè íà êàíàë (+l) +ERR_UNKNOWNMODE: :%s 472 %s %c :íåèçâåñòíûé ñèìâîë ðåæèìà +ERR_INVITEONLYCHAN: :%s 473 %s %s :Íåâîçìîæíî çàéòè íà êàíàë (+i) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Íåâîçìîæíî çàéòè íà êàíàë (+b) +ERR_BADCHANNELKEY: :%s 475 %s %s :Íåâîçìîæíî çàéòè íà êàíàë (+k) +ERR_BANLISTFULL: :%s 478 %s %s %s :Áàí ëèñò êàíàëà ïåðåïîëíåí +ERR_BADCHANNAME: :%s 479 %s %s :Íåäîïóñòèìîå èìÿ êàíàëà +ERR_NOPRIVILEGES: :%s 481 %s : äîñòóïå îòêàçàíî - Âû íå IRC Îïåðàòîð +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Âû íå îïåðàòîð êàíàëà +ERR_CANTKILLSERVER: :%s 483 %s :Âû íå ìîæåòå óáèòü ñåðâåð! +ERR_RESTRICTED: :%s 484 %s :Âû îãðàíè÷åíû +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :Íåèçâåñòíûé MODE ôëàã +ERR_USERSDONTMATCH: :%s 502 %s :Âû íå ìîæåòå èçìåíèòü ðåæèì äðóãîãî ïîëüçîâàòåëÿ +ERR_GHOSTEDCLIENT: :%s 503 %s :Íåâîçìîæíî äîñòàâèòü ñîîáùåíèå äëÿ %s +ERR_USERNOTONSERV: :%s 504 %s %s :Ïîëüçîâàòåëü íå íàõîäèòñÿ íà ýòîì ñåðâåðå +ERR_WRONGPONG: :%s 513 %s :Äëÿ ñîåäèíåíèÿ ââåäèòå /QUOTE PONG %lu +ERR_HELPNOTFOUND: :%s 524 %s %s :Ôàéë ïîìîùè íå íàéäåí +RPL_ENDOFMODLIST: :%s 703 %s :Çàâåðøåíèå âûâîäà /MODLIST. +RPL_ENDOFHELP :%s 706 %s %s :Çàâåðøåíèå âûâîäà /HELP. +RPL_KNOCK: :%s 710 %s %s %s!%s@%s :îïîâåùåí î ïðèãëàøåíèè. +RPL_KNOCKDLVR: :%s 711 %s %s :Âàø KNOCK áûë äîñòàâëåí. +ERR_TOOMANYKNOCK: :%s 712 %s %s :Ñëèøêîì ìíîãî KNOCKs (%s). +ERR_CHANOPEN: :%s 713 %s %s :Êàíàë îòêðûò. +ERR_KNOCKONCHAN: :%s 714 %s %s :Âû óæå íàõîäèòåñü íà ýòîì êàíàëå. diff --git a/messages/ircd-spanish.lang b/messages/ircd-spanish.lang new file mode 100644 index 0000000..4faa99b --- /dev/null +++ b/messages/ircd-spanish.lang @@ -0,0 +1,97 @@ +; SOME DESCRIPTIVE TITLE. +; Copyright (C) YEAR Free Software Foundation, Inc. +; FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +; $Id$ + +RPL_WELCOME: :%s 001 %s :Bienvenido al %s Internet Relay Chat Network %s +RPL_YOURHOST: :%s 002 %s :Estas en el servidor %s, corriendo la version %s +RPL_CREATED: :%s 003 %s :Este servidor fue creado el %s +RPL_ISUPPORT: :%s 005 %s %s :estan disponibles en servidor +RPL_REDIR: :%s 010 %s %s %d :Porfavor usa este puerto del servidor/envez +RPL_TRACELINK: :%s 200 %s Link %s %s %s +RPL_TRACECONNECTING: :%s 201 %s Trata. %s %s +RPL_TRACEHANDSHAKE: :%s 202 %s H.S. %s %s +RPL_TRACEOPERATOR: :%s 204 %s Oper %s %s (%s) %lu %lu +RPL_TRACEUSER: :%s 205 %s Usuario %s %s (%s) %lu %lu +RPL_TRACESERVER: :%s 206 %s Serv %s %dS %dC %s %s!%s@%s %lu +RPL_TRACENEWTYPE: :%s 208 %s <nuevotipo> 0 %s +RPL_TRACECLASS: :%s 209 %s Clase %s %d +RPL_ENDOFSTATS: :%s 219 %s %c :Fin del Reporte de /STATS +RPL_STATSUPTIME: :%s 242 %s :Servidor Activo %d dias, %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :Cuenta Maxima de Conexiones: %d (%d clientes) (%llu conexiones resivida) +RPL_LUSERCLIENT: :%s 251 %s :Hay %d usuarios y %d son invisibles en %d servidores +RPL_LUSEROP: :%s 252 %s %d :Operadores de IRC en linea +RPL_LUSERUNKNOWN: :%s 253 %s %d :Conexion Desconosida(s) +RPL_LUSERCHANNELS: :%s 254 %s %d :canales formados +RPL_LUSERME: :%s 255 %s :Tengo %d clientes en %d servidor(es) +RPL_ADMINME: :%s 256 %s :Informacion Administrativa de %s +RPL_ENDOFTRACE: :%s 262 %s %s :Fin de TRACE +RPL_LOAD2HI: :%s 263 %s :Servidor actualmente muy cargado. Porfavor espere un momento y trate otra vez. +RPL_LOCALUSERS: :%s 265 %s :Usuarios locales actuales: %d Max: %d +RPL_GLOBALUSERS: :%s 266 %s :Usuarios globales actuales: %d Max: %d +RPL_UNAWAY: :%s 305 %s :Ahora ya no estas marcado como Ausente (away) +RPL_NOWAWAY: :%s 306 %s :Ahora estas marcado como Ausente (away) +RPL_ENDOFWHO: :%s 315 %s %s :Fin de la lista de /WHO +RPL_WHOISIDLE: :%s 317 %s %s %d %d :seconds idle, tiempo de entrada +RPL_ENDOFWHOIS: :%s 318 %s %s :Fin de la lista de /WHOIS +RPL_LISTSTART: :%s 321 %s Canal :Nombre de Usuarios +RPL_LISTEND: :%s 323 %s :Fin de /LIST +RPL_NOTOPIC: :%s 331 %s %s :Topico no establecido. +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Fin de la lista de invitados del canal +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Fin de la lista de Excepciones del canal +RPL_CLOSING: :%s 362 %s %s :Cerrado. Estado = %d +RPL_CLOSEEND: :%s 363 %s %d: Conexiones Cerradas +RPL_ENDOFLINKS: :%s 365 %s %s :Fin de la lista de /LINKS +RPL_ENDOFNAMES: :%s 366 %s %s :Fin de la lista de /NAMES +RPL_ENDOFBANLIST: :%s 368 %s %s :Fin de la lista de banned(s) del canal +RPL_ENDOFWHOWAS: :%s 369 %s %s :Fin de WHOWAS +RPL_INFOSTART: :%s 373 %s :INFO del Servidor +RPL_ENDOFINFO: :%s 374 %s :Fin de la lista de /INFO +RPL_MOTDSTART: :%s 375 %s :- %s Mensaje del dia - +RPL_ENDOFMOTD: :%s 376 %s :Fin del comando de /MOTD +RPL_YOUREOPER: :%s 381 %s :Has entrado a... Twilight Zone!. +RPL_REHASHING: :%s 382 %s %s :Actualizando +ERR_NOSUCHNICK: :%s 401 %s %s :Ese nick/canal no existe +ERR_NOSUCHSERVER: :%s 402 %s %s :Ese servidor no existe +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Ese canal no existe +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :No se pueden enviar mensajes al canal +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Has entrado a muchos canales +ERR_WASNOSUCHNICK: :%s 406 %s %s :No habia nadie con ese nick +ERR_TOOMANYTARGETS: :%s 407 %s %s :Too many recipients. Only %d processed +ERR_NOORIGIN: :%s 409 %s :Origen no especificado +ERR_NORECIPIENT: :%s 411 %s :No recipient given (%s) +ERR_NOTEXTTOSEND: :%s 412 %s :No texto para enviar +ERR_NOTOPLEVEL: :%s 413 %s %s :No toplevel domain specified +ERR_WILDTOPLEVEL: :%s 414 %s %s :Wildcard in toplevel Domain +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Comando desconosido +ERR_NOMOTD: :%s 422 %s :El Mensaje del dia MOTD no esta presente +ERR_NOADMININFO: :%s 423 %s %s :Informacion administrativa no disponible +ERR_NONICKNAMEGIVEN: :%s 431 %s :No nickname dado +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Nick Invalido/Erroneo +ERR_NICKNAMEINUSE: :%s 433 %s %s :Nick actualmente en uso +ERR_NICKCOLLISION: :%s 436 %s %s :Colision de nicks KILL +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Nick/Canal no esta disponible temporalmente +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :No estan en el canal +ERR_NOTONCHANNEL: :%s 442 %s %s :Tu no estas en ese canal +ERR_USERONCHANNEL: :%s 443 %s %s %s :Ya esta en el canal +ERR_NOTREGISTERED: :%s 451 %s :No te has registrado +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Parametros insuficientes +ERR_ALREADYREGISTRED: :%s 462 %s :No puedes ser registrado +ERR_PASSWDMISMATCH: :%s 464 %s :Password Incorrecto +ERR_YOUREBANNEDCREEP: :%s 465 %s :Tu estas banned de este servidor- %s +ERR_CHANNELISFULL: :%s 471 %s %s :No puedes entrar al canal (+l) +ERR_UNKNOWNMODE: :%s 472 %s %c :Es un mode desconosido para mi +ERR_INVITEONLYCHAN: :%s 473 %s %s :No puedes entrar al canal (+i) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :No puedes entrar al canal (+b) +ERR_BADCHANNELKEY: :%s 475 %s %s :No puedes entrar al canal (+k) +ERR_BANLISTFULL: :%s 478 %s %s %s :La lista de ban en el canal esta llena +ERR_BADCHANNAME: :%s 479 %s %s :El nombre del canal es Ilegal o invalido +ERR_NOPRIVILEGES: :%s 481 %s :Permiso Negado - Tu no eres un Operador de IRC +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Tu no eres un operador del canal +ERR_CANTKILLSERVER: :%s 483 %s :Tu no puedes matar un servidor! +ERR_RESTRICTED: :%s 484 %s :Estas Restringido +ERR_NOOPERHOST: :%s 491 %s :Solamente algunos mortales pueden tratar de entrar al mundo de.. twilight zone +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :Flag MODE desconosida +ERR_USERSDONTMATCH: :%s 502 %s :No puedes cambiar los modes de otros usuarios +ERR_GHOSTEDCLIENT: :%s 503 %s :Mensaje no puede ser entregado a %s +ERR_USERNOTONSERV: :%s 504 %s %s :Usuario no esta en este servidor diff --git a/messages/ircd-standard.example.lang b/messages/ircd-standard.example.lang new file mode 100644 index 0000000..9ec8833 --- /dev/null +++ b/messages/ircd-standard.example.lang @@ -0,0 +1,137 @@ +; ircd-hybrid-7 standard message file - for reference only +; Copyright (C) 2003 Joshua Kwan <joshk@triplehelix.org> +; $Id$ + +; Use this file as a starting point for translating everything into the +; language you need. This file contains all of the defined events in +; messages.tab. + +; You will probably be able to leave out many of these, but in the +; event that you need some, they're ALL here. Even the very mundane +; ones - except where there is NULL. + +; Please replace my name with yours, the title with your language, +; remove these lines, etc. when creating your own file. + +RPL_WELCOME: :%s 001 %s :Welcome to the %s Internet Relay Chat Network %s +RPL_YOURHOST: :%s 002 %s :Your host is %s, running version %s +RPL_CREATED: :%s 003 %s :This server was created %s +RPL_ISUPPORT: :%s 005 %s %s :are supported by this server +RPL_REDIR: :%s 010 %s %s %d :Please use this Server/Port instead +RPL_MAPEND: :%s 017 %s :End of /MAP +RPL_YOURID: :%s 042 %s %s :your unique ID +RPL_TRACELINK: :%s 200 %s Link %s %s %s +RPL_TRACECONNECTING: :%s 201 %s Try. %s %s +RPL_TRACEHANDSHAKE: :%s 202 %s H.S. %s %s +RPL_TRACEUNKNOWN: :%s 203 %s ???? %s %s (%s) %d +RPL_TRACEOPERATOR: :%s 204 %s Oper %s %s (%s) %lu %lu +RPL_TRACEUSER: :%s 205 %s User %s %s (%s) %lu %lu +RPL_TRACESERVER: :%s 206 %s Serv %s %dS %dC %s %s!%s@%s %lu +RPL_TRACENEWTYPE: :%s 208 %s <newtype> 0 %s +RPL_TRACECLASS: :%s 209 %s Class %s %d +RPL_ENDOFSTATS: :%s 219 %s %c :End of /STATS report +RPL_STATSUPTIME: :%s 242 %s :Server Up %d days, %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :Highest connection count: %d (%d clients) (%llu connections received) +RPL_LUSERCLIENT: :%s 251 %s :There are %d users and %d invisible on %d servers +RPL_LUSEROP: :%s 252 %s %d :IRC Operators online +RPL_LUSERUNKNOWN: :%s 253 %s %d :unknown connection(s) +RPL_LUSERCHANNELS: :%s 254 %s %d :channels formed +RPL_LUSERME: :%s 255 %s :I have %d clients and %d servers +RPL_ADMINME: :%s 256 %s :Administrative info about %s +RPL_ENDOFTRACE: :%s 262 %s %s :End of TRACE +RPL_LOAD2HI: :%s 263 %s :Server load is temporarily too heavy. Please wait a while and try again. +RPL_LOCALUSERS: :%s 265 %s :Current local users: %d Max: %d +RPL_GLOBALUSERS: :%s 266 %s :Current global users: %d Max: %d +RPL_ENDOFACCEPT: :%s 282 %s :End of /ACCEPT list. +RPL_UNAWAY: :%s 305 %s :You are no longer marked as being away +RPL_NOWAWAY: :%s 306 %s :You have been marked as being away +RPL_WHOISADMIN: :%s 313 %s %s :is a Server Administrator +RPL_WHOISOPERATOR: :%s 313 %s %s :is an IRC Operator +RPL_ENDOFWHO: :%s 315 %s %s :End of /WHO list. +RPL_WHOISIDLE: :%s 317 %s %s %d %d :seconds idle +RPL_ENDOFWHOIS: :%s 318 %s %s :End of /WHOIS list. +RPL_LISTSTART: :%s 321 %s Channel :Users Name +RPL_LISTEND: :%s 323 %s :End of /LIST +RPL_NOTOPIC: :%s 331 %s %s :No topic is set. +RPL_WHOISACTUALLY: :%s 338 %s %s %s :actually using host +RPL_ENDOFINVEXLIST: :%s 347 %s %s :End of Channel Invite List +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :End of Channel Exception List +RPL_CLOSING: :%s 362 %s %s :Closed. Status = %d +RPL_CLOSEEND: :%s 363 %s %d: Connections Closed +RPL_ENDOFLINKS: :%s 365 %s %s :End of /LINKS list. +RPL_ENDOFNAMES: :%s 366 %s %s :End of /NAMES list. +RPL_ENDOFBANLIST: :%s 368 %s %s :End of Channel Ban List +RPL_ENDOFWHOWAS: :%s 369 %s %s :End of WHOWAS +RPL_INFOSTART: :%s 373 %s :Server INFO +RPL_ENDOFINFO: :%s 374 %s :End of /INFO list. +RPL_MOTDSTART: :%s 375 %s :- %s Message of the Day - +RPL_ENDOFMOTD: :%s 376 %s :End of /MOTD command. +RPL_YOUREOPER: :%s 381 %s :You have entered... the Twilight Zone! +RPL_REHASHING: :%s 382 %s %s :Rehashing +RPL_HOSTHIDDEN: :%s 396 %s :is now your hidden host +ERR_NOSUCHNICK: :%s 401 %s %s :No such nick/channel +ERR_NOSUCHSERVER: :%s 402 %s %s :No such server +ERR_NOSUCHCHANNEL: :%s 403 %s %s :No such channel +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Cannot send to channel +ERR_TOOMANYCHANNELS: :%s 405 %s %s :You have joined too many channels +ERR_WASNOSUCHNICK: :%s 406 %s %s :There was no such nickname +ERR_TOOMANYTARGETS: :%s 407 %s %s :Too many recipients. Only %d processed +ERR_NOORIGIN: :%s 409 %s :No origin specified +ERR_NORECIPIENT: :%s 411 %s :No recipient given (%s) +ERR_NOTEXTTOSEND: :%s 412 %s :No text to send +ERR_NOTOPLEVEL: :%s 413 %s %s :No toplevel domain specified +ERR_WILDTOPLEVEL: :%s 414 %s %s :Wildcard in toplevel Domain +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Unknown command +ERR_NOMOTD: :%s 422 %s :MOTD File is missing +ERR_NOADMININFO: :%s 423 %s %s :No administrative info available +ERR_NONICKNAMEGIVEN: :%s 431 %s :No nickname given +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Erroneous Nickname +ERR_NICKNAMEINUSE: :%s 433 %s %s :Nickname is already in use. +ERR_NICKCOLLISION: :%s 436 %s %s :Nickname collision KILL +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Nick/channel is temporarily unavailable +ERR_NICKTOOFAST: :%s 438 %s %s %s :Nick change too fast. Please wait %d seconds. +ERR_SERVICESDOWN: :%s 440 %s :Services is currently down. +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :They aren't on that channel +ERR_NOTONCHANNEL: :%s 442 %s %s :You're not on that channel +ERR_USERONCHANNEL: :%s 443 %s %s %s :is already on channel +ERR_NOTREGISTERED: :%s 451 %s :You have not registered +ERR_ACCEPTFULL: :%s 456 %s :Accept list is full +ERR_ACCEPTEXIST: :%s 457 %s %s :is already on your accept list +ERR_ACCEPTNOT: :%s 458 %s %s :is not on your accept list +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Not enough parameters +ERR_ALREADYREGISTRED: :%s 462 %s :You may not reregister +ERR_PASSWDMISMATCH: :%s 464 %s :Password Incorrect +ERR_YOUREBANNEDCREEP: :%s 465 %s :You are banned from this server- %s +ERR_CHANNELISFULL: :%s 471 %s %s :Cannot join channel (+l) +ERR_UNKNOWNMODE: :%s 472 %s %c :is unknown mode char to me +ERR_INVITEONLYCHAN: :%s 473 %s %s :Cannot join channel (+i) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Cannot join channel (+b) +ERR_BADCHANNELKEY: :%s 475 %s %s :Cannot join channel (+k) +ERR_BANLISTFULL: :%s 478 %s %s %s :Channel ban list is full +ERR_BADCHANNAME: :%s 479 %s %s :Illegal channel name +ERR_NOPRIVILEGES: :%s 481 %s :Permission Denied - You're not an IRC operator +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :You're not channel operator +ERR_CANTKILLSERVER: :%s 483 %s :You can't kill a server! +ERR_RESTRICTED: :%s 484 %s :You are restricted +ERR_NOOPERHOST: :%s 491 %s :Only few of mere mortals may try to enter the twilight zone +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :Unknown MODE flag +ERR_USERSDONTMATCH: :%s 502 %s :Can't change mode for other users +ERR_GHOSTEDCLIENT: :%s 503 %s :Message could not be delivered to %s +ERR_USERNOTONSERV: :%s 504 %s %s :User is not on this server +ERR_WRONGPONG: :%s 513 %s :To connect type /QUOTE PONG %lu +ERR_LISTSYNTAX: :%s 521 %s :Bad list syntax +ERR_HELPNOTFOUND: :%s 524 %s %s :Help not found +RPL_WHOISSECURE: :%s 671 %s %s :is connected via SSL (secure link) +RPL_ENDOFMODLIST: :%s 703 %s :End of /MODLIST. +RPL_ENDOFHELP: :%s 706 %s %s :End of /HELP. +RPL_KNOCK: :%s 710 %s %s %s!%s@%s :has asked for an invite. +RPL_KNOCKDLVR: :%s 711 %s %s :Your KNOCK has been delivered. +ERR_TOOMANYKNOCK: :%s 712 %s %s :Too many KNOCKs (%s). +ERR_CHANOPEN: :%s 713 %s %s :Channel is open. +ERR_KNOCKONCHAN: :%s 714 %s %s :You are already on that channel. +RPL_TARGUMODEG: :%s 716 %s %s :is in +g mode (server side ignore) +RPL_TARGNOTIFY: :%s 717 %s %s :has been informed that you messaged them. +RPL_UMODEGMSG: :%s 718 %s %s :is messaging you, and you are umode +g. +ERR_NOPRIVS: :%s 723 %s %s :Insufficient oper privs. +RPL_TESTMASK: :%s 724 %s %s!%s@%s %u %u :Local/remote clients match. +RPL_NOTESTLINE: :%s 726 %s %s :No matches diff --git a/messages/ircd-swedish.lang b/messages/ircd-swedish.lang new file mode 100644 index 0000000..a4b522f --- /dev/null +++ b/messages/ircd-swedish.lang @@ -0,0 +1,108 @@ +; ircd-hybrid-7 swedish message file +; Copyright (C) 2000-2005 +; David Taylor <davidt@yadt.co.uk>, 2000. +; Rickard Åberg <shelter@chatjunkies.org>, 2005. +; $Id$ + +RPL_WELCOME: :%s 001 %s :Välkommen till %s Internet Relay Chat Network %s +RPL_YOURHOST: :%s 002 %s :Din värd är %s, som kör version %s +RPL_CREATED: :%s 003 %s :Denna server skapades %s +RPL_ISUPPORT: :%s 005 %s %s :stödjs av denna server +RPL_REDIR: :%s 010 %s %s %d :Vänligen använd denna Server/Port i stället +RPL_TRACECONNECTING: :%s 201 %s Försök. %s %s +RPL_TRACEUSER: :%s 205 %s Användare %s %s (%s) %lu %lu +RPL_TRACENEWTYPE: :%s 208 %s <nytyp> 0 %s +RPL_TRACECLASS: :%s 209 %s Klass %s %d +RPL_ENDOFSTATS: :%s 219 %s %c :Slut på /STATS rapport +RPL_STATSUPTIME: :%s 242 %s :Server Upptid %d dagar, %d:%02d:%02d +RPL_STATSCONN: :%s 250 %s :Högsta anslutning antal: %d (%d klienter) (%llu anslutningar mottagna) +RPL_LUSERCLIENT: :%s 251 %s :Det finns %d användare och %d osynliga på %d servrar +RPL_LUSEROP: :%s 252 %s %d :IRC Operatörer online +RPL_LUSERUNKNOWN: :%s 253 %s %d :okänd(a) anslutning(ar) +RPL_LUSERCHANNELS: :%s 254 %s %d :kanaler skapade +RPL_LUSERME: :%s 255 %s :Jag har %d klienter och %d servrar +RPL_ADMINME: :%s 256 %s :Administrativ info om %s +RPL_ENDOFTRACE: :%s 262 %s %s :Slut på TRACE +RPL_LOAD2HI: :%s 263 %s :Servern är för tillfället överbelastad. Vänligen vänta en stund och försök igen senare. +RPL_LOCALUSERS: :%s 265 %s :Antal lokala användare: %d Max: %d +RPL_GLOBALUSERS: :%s 266 %s :Antal globala användare: %d Max: %d +RPL_UNAWAY: :%s 305 %s :Du är inte längre markerad som borta +RPL_NOWAWAY: :%s 306 %s :Du har blivit markerad som borta +RPL_ENDOFWHO: :%s 315 %s %s :Slut på /WHO lista. +RPL_WHOISIDLE: :%s 317 %s %s %d %d :sekunder overksam, login tid +RPL_ENDOFWHOIS: :%s 318 %s %s :Slut på /WHOIS lista. +RPL_LISTSTART: :%s 321 %s Kanaler :Användare Namn +RPL_LISTEND: :%s 323 %s :Slut på /LIST +RPL_NOTOPIC: :%s 331 %s %s :Ingen topic är satt. +RPL_ENDOFINVEXLIST: :%s 347 %s %s :Slut på Kanal Inbjudningslista +RPL_ENDOFEXCEPTLIST: :%s 349 %s %s :Slut på Kanal Undantagslista +RPL_CLOSING: :%s 362 %s %s :Stängd. Status = %d +RPL_CLOSEEND: :%s 363 %s %d: Anslutningar Stängda +RPL_ENDOFLINKS: :%s 365 %s %s :Slut på /LINKS lista. +RPL_ENDOFNAMES: :%s 366 %s %s :Slut på /NAMES lista. +RPL_ENDOFBANLIST: :%s 368 %s %s :Slut på Kanal Banlista +RPL_ENDOFWHOWAS: :%s 369 %s %s :Slut på WHOWAS +RPL_ENDOFINFO: :%s 374 %s :Slut på /INFO lista. +RPL_MOTDSTART: :%s 375 %s :- %s Dagens Meddelande - +RPL_ENDOFMOTD: :%s 376 %s :Slut på /MOTD. +RPL_YOUREOPER: :%s 381 %s :Du är nu i... Skymmningstimmen!. +RPL_REHASHING: :%s 382 %s %s :Laddar om +ERR_NOSUCHNICK: :%s 401 %s %s :Ej existerande smeknamn/kanal +ERR_NOSUCHSERVER: :%s 402 %s %s :Ej existerande server +ERR_NOSUCHCHANNEL: :%s 403 %s %s :Ej existerande kanal +ERR_CANNOTSENDTOCHAN: :%s 404 %s %s :Kan ej skicka till kanal +ERR_TOOMANYCHANNELS: :%s 405 %s %s :Du befinner dig i för många kanaler +ERR_WASNOSUCHNICK: :%s 406 %s %s :Det fanns inget sådant smeknamn +ERR_TOOMANYTARGETS: :%s 407 %s %s :För många mottagare. Bara %d bearbetade +ERR_NOORIGIN: :%s 409 %s :Ingen mottagare specificerad +ERR_NORECIPIENT: :%s 411 %s :Ingen mottagare specificerad (%s) +ERR_NOTEXTTOSEND: :%s 412 %s :Ingen text att skicka +ERR_NOTOPLEVEL: :%s 413 %s %s :Ingen topp domän specificerad +ERR_WILDTOPLEVEL: :%s 414 %s %s :Jokertecken i toppdomän +ERR_UNKNOWNCOMMAND: :%s 421 %s %s :Okänt kommando +ERR_NOMOTD: :%s 422 %s :MOTD fil saknas +ERR_NOADMININFO: :%s 423 %s %s :Ingen administrativ info tillgänglig +ERR_NONICKNAMEGIVEN: :%s 431 %s :Inget smeknamn specificerat +ERR_ERRONEUSNICKNAME: :%s 432 %s %s :Felaktigt Smeknamn +ERR_NICKNAMEINUSE: :%s 433 %s %s :Smeknamnet används redan. +ERR_NICKCOLLISION: :%s 436 %s %s :Smeknamn kollision KILL +ERR_UNAVAILRESOURCE: :%s 437 %s %s :Smeknamn/kanal är temporärt inte tillgänglig +ERR_USERNOTINCHANNEL: :%s 441 %s %s %s :De är inte i den kanalen +ERR_NOTONCHANNEL: :%s 442 %s %s :Du är inte i den kanalen +ERR_USERONCHANNEL: :%s 443 %s %s %s :är redan i kanalen +ERR_NOTREGISTERED: :%s 451 %s :Du har inte registrerat dig +ERR_NEEDMOREPARAMS: :%s 461 %s %s :Otillräckliga parametrar +ERR_ALREADYREGISTRED: :%s 462 %s :Du får inte registrera dig +ERR_PASSWDMISMATCH: :%s 464 %s :Felaktigt Lösenord +ERR_YOUREBANNEDCREEP: :%s 465 %s :Du är bannad från denna server- %s +ERR_CHANNELISFULL: :%s 471 %s %s :Kan inte öppna kanal (+l) +ERR_UNKNOWNMODE: :%s 472 %s %c :är okänd mode parameter för mig +ERR_INVITEONLYCHAN: :%s 473 %s %s :Kan ej öppna kanal (+i) +ERR_BANNEDFROMCHAN: :%s 474 %s %s :Kan ej öppna kanal (+b) +ERR_BADCHANNELKEY: :%s 475 %s %s :Kan ej öppna kanal (+k) +ERR_BANLISTFULL: :%s 478 %s %s %s :Kanalens ban lista är full +ERR_BADCHANNAME: :%s 479 %s %s :Felaktigt kanalnamn +ERR_NOPRIVILEGES: :%s 481 %s :Tillträde förbjuden - Du är inte en IRC operatör +ERR_CHANOPRIVSNEEDED: :%s 482 %s %s :Du är inte en operatör +ERR_CANTKILLSERVER: :%s 483 %s :Man kan inte /KILL en server! +ERR_NOOPERHOST: :%s 491 %s :Tyvärr, du har inte vad som krävs för att vara en Operatör här. +ERR_UMODEUNKNOWNFLAG: :%s 501 %s :Okänd MODE flagga +ERR_USERSDONTMATCH: :%s 502 %s :Kan inte ändra mode for andra användare +ERR_GHOSTEDCLIENT: :%s 503 %s :Meddelandet kunde inte levereras till %s +ERR_USERNOTONSERV: :%s 504 %s %s :Användaren är inte på denna server +ERR_WRONGPONG: :%s 513 %s :För att ansluta, skriv /QUOTE PONG %lu +ERR_LISTSYNTAX: :%s 521 %s :Felaktig listning. +ERR_HELPNOTFOUND: :%s 524 %s %s :Hjälp ej funnen. +RPL_ENDOFMODLIST: :%s 703 %s :Slut på /MODLIST. +RPL_ENDOFHELP: :%s 706 %s %s :Slut på /HELP. +RPL_KNOCK: :%s 710 %s %s %s!%s@%s :har frågat efter inbjudan. +RPL_KNOCKDLVR: :%s 711 %s %s :Din KNOCK har blivit skickad. +ERR_TOOMANYKNOCK: :%s 712 %s %s :För många KNOCKs (%s). +ERR_CHANOPEN: :%s 713 %s %s :Kanalen är öppen. +ERR_KNOCKONCHAN: :%s 714 %s %s :Du är redan i den kanalen. +RPL_TARGUMODEG: :%s 716 %s %s :är i +g läge (server-side ignorering) +RPL_TARGNOTIFY: :%s 717 %s %s :har blivit informerad om att du skickat ett meddelande. +RPL_UMODEGMSG: :%s 718 %s %s :skriver till dig, och du har umode +g aktiverat. +ERR_NOPRIVS: :%s 723 %s %s :Otillräckliga oper privilegier. +RPL_TESTMASK: :%s 724 %s %s!%s@%s %u %u :Lokal/fjärr klient matchar. +RPL_NOTESTLINE: :%s 726 %s %s :Ingen match/träff. @@ -0,0 +1,330 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2012-01-06.18; # UTC + +# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, 'missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle 'PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file 'aclocal.m4' + autoconf touch file 'configure' + autoheader touch file 'config.h.in' + autom4te touch the output file, or create a stub one + automake touch all 'Makefile.in' files + bison create 'y.tab.[ch]', if possible, from existing .[ch] + flex create 'lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create 'lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create 'y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to <bug-automake@gnu.org>." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running '$TOOL --version' or '$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified 'acinclude.m4' or '${configure_ac}'. You might want + to install the Automake and Perl packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified '${configure_ac}'. You might want to install the + Autoconf and GNU m4 packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified 'acconfig.h' or '${configure_ac}'. You might want + to install the Autoconf and GNU m4 packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified 'Makefile.am', 'acinclude.m4' or '${configure_ac}'. + You might want to install the Automake and Perl packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: '$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get '$1' as part of Autoconf from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: '$1' $msg. You should only need it if + you modified a '.y' file. You may need the Bison package + in order for those modifications to take effect. You can get + Bison from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified a '.l' file. You may need the Flex package + in order for those modifications to take effect. You can get + Flex from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + Help2man package in order for those modifications to take + effect. You can get Help2man from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified a '.texi' or '.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy 'make' (AIX, + DU, IRIX). You might want to install the Texinfo package or + the GNU make package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: '$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the 'README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing '$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/modules/Makefile.am b/modules/Makefile.am new file mode 100644 index 0000000..e25e3a8 --- /dev/null +++ b/modules/Makefile.am @@ -0,0 +1,192 @@ +AUTOMAKE_OPTIONS = foreign +MODULE_FLAGS = -module -avoid-version +SUBDIRS = core + +AM_CPPFLAGS = -I$(top_srcdir)/include +modulesdir = $(pkglibdir)/modules/autoload + +modules_LTLIBRARIES = m_accept.la \ + m_admin.la \ + m_away.la \ + m_capab.la \ + m_cap.la \ + m_challenge.la \ + m_close.la \ + m_connect.la \ + m_dline.la \ + m_encap.la \ + m_eob.la \ + m_etrace.la \ + m_gline.la \ + m_globops.la \ + m_hash.la \ + m_help.la \ + m_info.la \ + m_invite.la \ + m_ison.la \ + m_kline.la \ + m_knock.la \ + m_links.la \ + m_list.la \ + m_locops.la \ + m_lusers.la \ + m_map.la \ + m_module.la \ + m_motd.la \ + m_names.la \ + m_oper.la \ + m_operwall.la \ + m_pass.la \ + m_ping.la \ + m_pong.la \ + m_post.la \ + m_rehash.la \ + m_restart.la \ + m_resv.la \ + m_set.la \ + m_services.la \ + m_stats.la \ + m_svinfo.la \ + m_svsmode.la \ + m_svsnick.la \ + m_tburst.la \ + m_testline.la \ + m_testmask.la \ + m_time.la \ + m_topic.la \ + m_trace.la \ + m_user.la \ + m_userhost.la \ + m_users.la \ + m_version.la \ + m_wallops.la \ + m_watch.la \ + m_who.la \ + m_whois.la \ + m_whowas.la \ + m_xline.la + + +m_challenge_la_LDFLAGS = $(MODULE_FLAGS) +m_accept_la_LDFLAGS = $(MODULE_FLAGS) +m_admin_la_LDFLAGS = $(MODULE_FLAGS) +m_away_la_LDFLAGS = $(MODULE_FLAGS) +m_capab_la_LDFLAGS = $(MODULE_FLAGS) +m_cap_la_LDFLAGS = $(MODULE_FLAGS) +m_close_la_LDFLAGS = $(MODULE_FLAGS) +m_connect_la_LDFLAGS = $(MODULE_FLAGS) +m_dline_la_LDFLAGS = $(MODULE_FLAGS) +m_encap_la_LDFLAGS = $(MODULE_FLAGS) +m_eob_la_LDFLAGS = $(MODULE_FLAGS) +m_etrace_la_LDFLAGS = $(MODULE_FLAGS) +m_gline_la_LDFLAGS = $(MODULE_FLAGS) +m_globops_la_LDFLAGS = $(MODULE_FLAGS) +m_hash_la_LDFLAGS = $(MODULE_FLAGS) +m_help_la_LDFLAGS = $(MODULE_FLAGS) +m_info_la_LDFLAGS = $(MODULE_FLAGS) +m_invite_la_LDFLAGS = $(MODULE_FLAGS) +m_ison_la_LDFLAGS = $(MODULE_FLAGS) +m_kline_la_LDFLAGS = $(MODULE_FLAGS) +m_knock_la_LDFLAGS = $(MODULE_FLAGS) +m_links_la_LDFLAGS = $(MODULE_FLAGS) +m_list_la_LDFLAGS = $(MODULE_FLAGS) +m_locops_la_LDFLAGS = $(MODULE_FLAGS) +m_lusers_la_LDFLAGS = $(MODULE_FLAGS) +m_map_la_LDFLAGS = $(MODULE_FLAGS) +m_module_la_LDFLAGS = $(MODULE_FLAGS) +m_motd_la_LDFLAGS = $(MODULE_FLAGS) +m_names_la_LDFLAGS = $(MODULE_FLAGS) +m_oper_la_LDFLAGS = $(MODULE_FLAGS) +m_operwall_la_LDFLAGS = $(MODULE_FLAGS) +m_pass_la_LDFLAGS = $(MODULE_FLAGS) +m_ping_la_LDFLAGS = $(MODULE_FLAGS) +m_pong_la_LDFLAGS = $(MODULE_FLAGS) +m_post_la_LDFLAGS = $(MODULE_FLAGS) +m_rehash_la_LDFLAGS = $(MODULE_FLAGS) +m_restart_la_LDFLAGS = $(MODULE_FLAGS) +m_resv_la_LDFLAGS = $(MODULE_FLAGS) +m_set_la_LDFLAGS = $(MODULE_FLAGS) +m_services_la_LDFLAGS = $(MODULE_FLAGS) +m_stats_la_LDFLAGS = $(MODULE_FLAGS) +m_svinfo_la_LDFLAGS = $(MODULE_FLAGS) +m_svsmode_la_LDFLAGS = $(MODULE_FLAGS) +m_svsnick_la_LDFLAGS = $(MODULE_FLAGS) +m_tburst_la_LDFLAGS = $(MODULE_FLAGS) +m_testline_la_LDFLAGS = $(MODULE_FLAGS) +m_testmask_la_LDFLAGS = $(MODULE_FLAGS) +m_time_la_LDFLAGS = $(MODULE_FLAGS) +m_topic_la_LDFLAGS = $(MODULE_FLAGS) +m_trace_la_LDFLAGS = $(MODULE_FLAGS) +m_user_la_LDFLAGS = $(MODULE_FLAGS) +m_userhost_la_LDFLAGS = $(MODULE_FLAGS) +m_users_la_LDFLAGS = $(MODULE_FLAGS) +m_version_la_LDFLAGS = $(MODULE_FLAGS) +m_wallops_la_LDFLAGS = $(MODULE_FLAGS) +m_watch_la_LDFLAGS = $(MODULE_FLAGS) +m_who_la_LDFLAGS = $(MODULE_FLAGS) +m_whois_la_LDFLAGS = $(MODULE_FLAGS) +m_whowas_la_LDFLAGS = $(MODULE_FLAGS) +m_xline_la_LDFLAGS = $(MODULE_FLAGS) + +m_accept_la_SOURCES = m_accept.c +m_admin_la_SOURCES = m_admin.c +m_away_la_SOURCES = m_away.c +m_capab_la_SOURCES = m_capab.c +m_cap_la_SOURCES = m_cap.c +m_challenge_la_SOURCES = m_challenge.c +m_close_la_SOURCES = m_close.c +m_connect_la_SOURCES = m_connect.c +m_dline_la_SOURCES = m_dline.c +m_encap_la_SOURCES = m_encap.c +m_eob_la_SOURCES = m_eob.c +m_etrace_la_SOURCES = m_etrace.c +m_gline_la_SOURCES = m_gline.c +m_globops_la_SOURCES = m_globops.c +m_hash_la_SOURCES = m_hash.c +m_help_la_SOURCES = m_help.c +m_info_la_SOURCES = m_info.c +m_invite_la_SOURCES = m_invite.c +m_ison_la_SOURCES = m_ison.c +m_kline_la_SOURCES = m_kline.c +m_knock_la_SOURCES = m_knock.c +m_links_la_SOURCES = m_links.c +m_list_la_SOURCES = m_list.c +m_locops_la_SOURCES = m_locops.c +m_lusers_la_SOURCES = m_lusers.c +m_map_la_SOURCES = m_map.c +m_module_la_SOURCES = m_module.c +m_motd_la_SOURCES = m_motd.c +m_names_la_SOURCES = m_names.c +m_oper_la_SOURCES = m_oper.c +m_operwall_la_SOURCES = m_operwall.c +m_pass_la_SOURCES = m_pass.c +m_ping_la_SOURCES = m_ping.c +m_pong_la_SOURCES = m_pong.c +m_post_la_SOURCES = m_post.c +m_rehash_la_SOURCES = m_rehash.c +m_restart_la_SOURCES = m_restart.c +m_resv_la_SOURCES = m_resv.c +m_set_la_SOURCES = m_set.c +m_services_la_SOURCES = m_services.c +m_stats_la_SOURCES = m_stats.c +m_svinfo_la_SOURCES = m_svinfo.c +m_svsmode_la_SOURCES = m_svsmode.c +m_svsnick_la_SOURCES = m_svsnick.c +m_tburst_la_SOURCES = m_tburst.c +m_testline_la_SOURCES = m_testline.c +m_testmask_la_SOURCES = m_testmask.c +m_time_la_SOURCES = m_time.c +m_topic_la_SOURCES = m_topic.c +m_trace_la_SOURCES = m_trace.c +m_user_la_SOURCES = m_user.c +m_userhost_la_SOURCES = m_userhost.c +m_users_la_SOURCES = m_users.c +m_version_la_SOURCES = m_version.c +m_wallops_la_SOURCES = m_wallops.c +m_watch_la_SOURCES = m_watch.c +m_who_la_SOURCES = m_who.c +m_whois_la_SOURCES = m_whois.c +m_whowas_la_SOURCES = m_whowas.c +m_xline_la_SOURCES = m_xline.c + +modules: $(modules_LTLIBRARIES) diff --git a/modules/Makefile.in b/modules/Makefile.in new file mode 100644 index 0000000..1f6cb89 --- /dev/null +++ b/modules/Makefile.in @@ -0,0 +1,1495 @@ +# Makefile.in generated by automake 1.12.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = modules +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(modulesdir)" +LTLIBRARIES = $(modules_LTLIBRARIES) +m_accept_la_LIBADD = +am_m_accept_la_OBJECTS = m_accept.lo +m_accept_la_OBJECTS = $(am_m_accept_la_OBJECTS) +m_accept_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_accept_la_LDFLAGS) $(LDFLAGS) -o $@ +m_admin_la_LIBADD = +am_m_admin_la_OBJECTS = m_admin.lo +m_admin_la_OBJECTS = $(am_m_admin_la_OBJECTS) +m_admin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_admin_la_LDFLAGS) $(LDFLAGS) -o $@ +m_away_la_LIBADD = +am_m_away_la_OBJECTS = m_away.lo +m_away_la_OBJECTS = $(am_m_away_la_OBJECTS) +m_away_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_away_la_LDFLAGS) $(LDFLAGS) -o $@ +m_cap_la_LIBADD = +am_m_cap_la_OBJECTS = m_cap.lo +m_cap_la_OBJECTS = $(am_m_cap_la_OBJECTS) +m_cap_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(m_cap_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +m_capab_la_LIBADD = +am_m_capab_la_OBJECTS = m_capab.lo +m_capab_la_OBJECTS = $(am_m_capab_la_OBJECTS) +m_capab_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_capab_la_LDFLAGS) $(LDFLAGS) -o $@ +m_challenge_la_LIBADD = +am_m_challenge_la_OBJECTS = m_challenge.lo +m_challenge_la_OBJECTS = $(am_m_challenge_la_OBJECTS) +m_challenge_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_challenge_la_LDFLAGS) $(LDFLAGS) -o $@ +m_close_la_LIBADD = +am_m_close_la_OBJECTS = m_close.lo +m_close_la_OBJECTS = $(am_m_close_la_OBJECTS) +m_close_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_close_la_LDFLAGS) $(LDFLAGS) -o $@ +m_connect_la_LIBADD = +am_m_connect_la_OBJECTS = m_connect.lo +m_connect_la_OBJECTS = $(am_m_connect_la_OBJECTS) +m_connect_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_connect_la_LDFLAGS) $(LDFLAGS) -o $@ +m_dline_la_LIBADD = +am_m_dline_la_OBJECTS = m_dline.lo +m_dline_la_OBJECTS = $(am_m_dline_la_OBJECTS) +m_dline_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_dline_la_LDFLAGS) $(LDFLAGS) -o $@ +m_encap_la_LIBADD = +am_m_encap_la_OBJECTS = m_encap.lo +m_encap_la_OBJECTS = $(am_m_encap_la_OBJECTS) +m_encap_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_encap_la_LDFLAGS) $(LDFLAGS) -o $@ +m_eob_la_LIBADD = +am_m_eob_la_OBJECTS = m_eob.lo +m_eob_la_OBJECTS = $(am_m_eob_la_OBJECTS) +m_eob_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(m_eob_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +m_etrace_la_LIBADD = +am_m_etrace_la_OBJECTS = m_etrace.lo +m_etrace_la_OBJECTS = $(am_m_etrace_la_OBJECTS) +m_etrace_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_etrace_la_LDFLAGS) $(LDFLAGS) -o $@ +m_gline_la_LIBADD = +am_m_gline_la_OBJECTS = m_gline.lo +m_gline_la_OBJECTS = $(am_m_gline_la_OBJECTS) +m_gline_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_gline_la_LDFLAGS) $(LDFLAGS) -o $@ +m_globops_la_LIBADD = +am_m_globops_la_OBJECTS = m_globops.lo +m_globops_la_OBJECTS = $(am_m_globops_la_OBJECTS) +m_globops_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_globops_la_LDFLAGS) $(LDFLAGS) -o $@ +m_hash_la_LIBADD = +am_m_hash_la_OBJECTS = m_hash.lo +m_hash_la_OBJECTS = $(am_m_hash_la_OBJECTS) +m_hash_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_hash_la_LDFLAGS) $(LDFLAGS) -o $@ +m_help_la_LIBADD = +am_m_help_la_OBJECTS = m_help.lo +m_help_la_OBJECTS = $(am_m_help_la_OBJECTS) +m_help_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_help_la_LDFLAGS) $(LDFLAGS) -o $@ +m_info_la_LIBADD = +am_m_info_la_OBJECTS = m_info.lo +m_info_la_OBJECTS = $(am_m_info_la_OBJECTS) +m_info_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_info_la_LDFLAGS) $(LDFLAGS) -o $@ +m_invite_la_LIBADD = +am_m_invite_la_OBJECTS = m_invite.lo +m_invite_la_OBJECTS = $(am_m_invite_la_OBJECTS) +m_invite_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_invite_la_LDFLAGS) $(LDFLAGS) -o $@ +m_ison_la_LIBADD = +am_m_ison_la_OBJECTS = m_ison.lo +m_ison_la_OBJECTS = $(am_m_ison_la_OBJECTS) +m_ison_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_ison_la_LDFLAGS) $(LDFLAGS) -o $@ +m_kline_la_LIBADD = +am_m_kline_la_OBJECTS = m_kline.lo +m_kline_la_OBJECTS = $(am_m_kline_la_OBJECTS) +m_kline_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_kline_la_LDFLAGS) $(LDFLAGS) -o $@ +m_knock_la_LIBADD = +am_m_knock_la_OBJECTS = m_knock.lo +m_knock_la_OBJECTS = $(am_m_knock_la_OBJECTS) +m_knock_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_knock_la_LDFLAGS) $(LDFLAGS) -o $@ +m_links_la_LIBADD = +am_m_links_la_OBJECTS = m_links.lo +m_links_la_OBJECTS = $(am_m_links_la_OBJECTS) +m_links_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_links_la_LDFLAGS) $(LDFLAGS) -o $@ +m_list_la_LIBADD = +am_m_list_la_OBJECTS = m_list.lo +m_list_la_OBJECTS = $(am_m_list_la_OBJECTS) +m_list_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_list_la_LDFLAGS) $(LDFLAGS) -o $@ +m_locops_la_LIBADD = +am_m_locops_la_OBJECTS = m_locops.lo +m_locops_la_OBJECTS = $(am_m_locops_la_OBJECTS) +m_locops_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_locops_la_LDFLAGS) $(LDFLAGS) -o $@ +m_lusers_la_LIBADD = +am_m_lusers_la_OBJECTS = m_lusers.lo +m_lusers_la_OBJECTS = $(am_m_lusers_la_OBJECTS) +m_lusers_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_lusers_la_LDFLAGS) $(LDFLAGS) -o $@ +m_map_la_LIBADD = +am_m_map_la_OBJECTS = m_map.lo +m_map_la_OBJECTS = $(am_m_map_la_OBJECTS) +m_map_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(m_map_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +m_module_la_LIBADD = +am_m_module_la_OBJECTS = m_module.lo +m_module_la_OBJECTS = $(am_m_module_la_OBJECTS) +m_module_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_module_la_LDFLAGS) $(LDFLAGS) -o $@ +m_motd_la_LIBADD = +am_m_motd_la_OBJECTS = m_motd.lo +m_motd_la_OBJECTS = $(am_m_motd_la_OBJECTS) +m_motd_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_motd_la_LDFLAGS) $(LDFLAGS) -o $@ +m_names_la_LIBADD = +am_m_names_la_OBJECTS = m_names.lo +m_names_la_OBJECTS = $(am_m_names_la_OBJECTS) +m_names_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_names_la_LDFLAGS) $(LDFLAGS) -o $@ +m_oper_la_LIBADD = +am_m_oper_la_OBJECTS = m_oper.lo +m_oper_la_OBJECTS = $(am_m_oper_la_OBJECTS) +m_oper_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_oper_la_LDFLAGS) $(LDFLAGS) -o $@ +m_operwall_la_LIBADD = +am_m_operwall_la_OBJECTS = m_operwall.lo +m_operwall_la_OBJECTS = $(am_m_operwall_la_OBJECTS) +m_operwall_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_operwall_la_LDFLAGS) $(LDFLAGS) -o $@ +m_pass_la_LIBADD = +am_m_pass_la_OBJECTS = m_pass.lo +m_pass_la_OBJECTS = $(am_m_pass_la_OBJECTS) +m_pass_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_pass_la_LDFLAGS) $(LDFLAGS) -o $@ +m_ping_la_LIBADD = +am_m_ping_la_OBJECTS = m_ping.lo +m_ping_la_OBJECTS = $(am_m_ping_la_OBJECTS) +m_ping_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_ping_la_LDFLAGS) $(LDFLAGS) -o $@ +m_pong_la_LIBADD = +am_m_pong_la_OBJECTS = m_pong.lo +m_pong_la_OBJECTS = $(am_m_pong_la_OBJECTS) +m_pong_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_pong_la_LDFLAGS) $(LDFLAGS) -o $@ +m_post_la_LIBADD = +am_m_post_la_OBJECTS = m_post.lo +m_post_la_OBJECTS = $(am_m_post_la_OBJECTS) +m_post_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_post_la_LDFLAGS) $(LDFLAGS) -o $@ +m_rehash_la_LIBADD = +am_m_rehash_la_OBJECTS = m_rehash.lo +m_rehash_la_OBJECTS = $(am_m_rehash_la_OBJECTS) +m_rehash_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_rehash_la_LDFLAGS) $(LDFLAGS) -o $@ +m_restart_la_LIBADD = +am_m_restart_la_OBJECTS = m_restart.lo +m_restart_la_OBJECTS = $(am_m_restart_la_OBJECTS) +m_restart_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_restart_la_LDFLAGS) $(LDFLAGS) -o $@ +m_resv_la_LIBADD = +am_m_resv_la_OBJECTS = m_resv.lo +m_resv_la_OBJECTS = $(am_m_resv_la_OBJECTS) +m_resv_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_resv_la_LDFLAGS) $(LDFLAGS) -o $@ +m_services_la_LIBADD = +am_m_services_la_OBJECTS = m_services.lo +m_services_la_OBJECTS = $(am_m_services_la_OBJECTS) +m_services_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_services_la_LDFLAGS) $(LDFLAGS) -o $@ +m_set_la_LIBADD = +am_m_set_la_OBJECTS = m_set.lo +m_set_la_OBJECTS = $(am_m_set_la_OBJECTS) +m_set_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(m_set_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +m_stats_la_LIBADD = +am_m_stats_la_OBJECTS = m_stats.lo +m_stats_la_OBJECTS = $(am_m_stats_la_OBJECTS) +m_stats_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_stats_la_LDFLAGS) $(LDFLAGS) -o $@ +m_svinfo_la_LIBADD = +am_m_svinfo_la_OBJECTS = m_svinfo.lo +m_svinfo_la_OBJECTS = $(am_m_svinfo_la_OBJECTS) +m_svinfo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_svinfo_la_LDFLAGS) $(LDFLAGS) -o $@ +m_svsmode_la_LIBADD = +am_m_svsmode_la_OBJECTS = m_svsmode.lo +m_svsmode_la_OBJECTS = $(am_m_svsmode_la_OBJECTS) +m_svsmode_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_svsmode_la_LDFLAGS) $(LDFLAGS) -o $@ +m_svsnick_la_LIBADD = +am_m_svsnick_la_OBJECTS = m_svsnick.lo +m_svsnick_la_OBJECTS = $(am_m_svsnick_la_OBJECTS) +m_svsnick_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_svsnick_la_LDFLAGS) $(LDFLAGS) -o $@ +m_tburst_la_LIBADD = +am_m_tburst_la_OBJECTS = m_tburst.lo +m_tburst_la_OBJECTS = $(am_m_tburst_la_OBJECTS) +m_tburst_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_tburst_la_LDFLAGS) $(LDFLAGS) -o $@ +m_testline_la_LIBADD = +am_m_testline_la_OBJECTS = m_testline.lo +m_testline_la_OBJECTS = $(am_m_testline_la_OBJECTS) +m_testline_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_testline_la_LDFLAGS) $(LDFLAGS) -o $@ +m_testmask_la_LIBADD = +am_m_testmask_la_OBJECTS = m_testmask.lo +m_testmask_la_OBJECTS = $(am_m_testmask_la_OBJECTS) +m_testmask_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_testmask_la_LDFLAGS) $(LDFLAGS) -o $@ +m_time_la_LIBADD = +am_m_time_la_OBJECTS = m_time.lo +m_time_la_OBJECTS = $(am_m_time_la_OBJECTS) +m_time_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_time_la_LDFLAGS) $(LDFLAGS) -o $@ +m_topic_la_LIBADD = +am_m_topic_la_OBJECTS = m_topic.lo +m_topic_la_OBJECTS = $(am_m_topic_la_OBJECTS) +m_topic_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_topic_la_LDFLAGS) $(LDFLAGS) -o $@ +m_trace_la_LIBADD = +am_m_trace_la_OBJECTS = m_trace.lo +m_trace_la_OBJECTS = $(am_m_trace_la_OBJECTS) +m_trace_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_trace_la_LDFLAGS) $(LDFLAGS) -o $@ +m_user_la_LIBADD = +am_m_user_la_OBJECTS = m_user.lo +m_user_la_OBJECTS = $(am_m_user_la_OBJECTS) +m_user_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_user_la_LDFLAGS) $(LDFLAGS) -o $@ +m_userhost_la_LIBADD = +am_m_userhost_la_OBJECTS = m_userhost.lo +m_userhost_la_OBJECTS = $(am_m_userhost_la_OBJECTS) +m_userhost_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_userhost_la_LDFLAGS) $(LDFLAGS) -o $@ +m_users_la_LIBADD = +am_m_users_la_OBJECTS = m_users.lo +m_users_la_OBJECTS = $(am_m_users_la_OBJECTS) +m_users_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_users_la_LDFLAGS) $(LDFLAGS) -o $@ +m_version_la_LIBADD = +am_m_version_la_OBJECTS = m_version.lo +m_version_la_OBJECTS = $(am_m_version_la_OBJECTS) +m_version_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_version_la_LDFLAGS) $(LDFLAGS) -o $@ +m_wallops_la_LIBADD = +am_m_wallops_la_OBJECTS = m_wallops.lo +m_wallops_la_OBJECTS = $(am_m_wallops_la_OBJECTS) +m_wallops_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_wallops_la_LDFLAGS) $(LDFLAGS) -o $@ +m_watch_la_LIBADD = +am_m_watch_la_OBJECTS = m_watch.lo +m_watch_la_OBJECTS = $(am_m_watch_la_OBJECTS) +m_watch_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_watch_la_LDFLAGS) $(LDFLAGS) -o $@ +m_who_la_LIBADD = +am_m_who_la_OBJECTS = m_who.lo +m_who_la_OBJECTS = $(am_m_who_la_OBJECTS) +m_who_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(m_who_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +m_whois_la_LIBADD = +am_m_whois_la_OBJECTS = m_whois.lo +m_whois_la_OBJECTS = $(am_m_whois_la_OBJECTS) +m_whois_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_whois_la_LDFLAGS) $(LDFLAGS) -o $@ +m_whowas_la_LIBADD = +am_m_whowas_la_OBJECTS = m_whowas.lo +m_whowas_la_OBJECTS = $(am_m_whowas_la_OBJECTS) +m_whowas_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_whowas_la_LDFLAGS) $(LDFLAGS) -o $@ +m_xline_la_LIBADD = +am_m_xline_la_OBJECTS = m_xline.lo +m_xline_la_OBJECTS = $(am_m_xline_la_OBJECTS) +m_xline_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_xline_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(m_accept_la_SOURCES) $(m_admin_la_SOURCES) \ + $(m_away_la_SOURCES) $(m_cap_la_SOURCES) $(m_capab_la_SOURCES) \ + $(m_challenge_la_SOURCES) $(m_close_la_SOURCES) \ + $(m_connect_la_SOURCES) $(m_dline_la_SOURCES) \ + $(m_encap_la_SOURCES) $(m_eob_la_SOURCES) \ + $(m_etrace_la_SOURCES) $(m_gline_la_SOURCES) \ + $(m_globops_la_SOURCES) $(m_hash_la_SOURCES) \ + $(m_help_la_SOURCES) $(m_info_la_SOURCES) \ + $(m_invite_la_SOURCES) $(m_ison_la_SOURCES) \ + $(m_kline_la_SOURCES) $(m_knock_la_SOURCES) \ + $(m_links_la_SOURCES) $(m_list_la_SOURCES) \ + $(m_locops_la_SOURCES) $(m_lusers_la_SOURCES) \ + $(m_map_la_SOURCES) $(m_module_la_SOURCES) \ + $(m_motd_la_SOURCES) $(m_names_la_SOURCES) \ + $(m_oper_la_SOURCES) $(m_operwall_la_SOURCES) \ + $(m_pass_la_SOURCES) $(m_ping_la_SOURCES) $(m_pong_la_SOURCES) \ + $(m_post_la_SOURCES) $(m_rehash_la_SOURCES) \ + $(m_restart_la_SOURCES) $(m_resv_la_SOURCES) \ + $(m_services_la_SOURCES) $(m_set_la_SOURCES) \ + $(m_stats_la_SOURCES) $(m_svinfo_la_SOURCES) \ + $(m_svsmode_la_SOURCES) $(m_svsnick_la_SOURCES) \ + $(m_tburst_la_SOURCES) $(m_testline_la_SOURCES) \ + $(m_testmask_la_SOURCES) $(m_time_la_SOURCES) \ + $(m_topic_la_SOURCES) $(m_trace_la_SOURCES) \ + $(m_user_la_SOURCES) $(m_userhost_la_SOURCES) \ + $(m_users_la_SOURCES) $(m_version_la_SOURCES) \ + $(m_wallops_la_SOURCES) $(m_watch_la_SOURCES) \ + $(m_who_la_SOURCES) $(m_whois_la_SOURCES) \ + $(m_whowas_la_SOURCES) $(m_xline_la_SOURCES) +DIST_SOURCES = $(m_accept_la_SOURCES) $(m_admin_la_SOURCES) \ + $(m_away_la_SOURCES) $(m_cap_la_SOURCES) $(m_capab_la_SOURCES) \ + $(m_challenge_la_SOURCES) $(m_close_la_SOURCES) \ + $(m_connect_la_SOURCES) $(m_dline_la_SOURCES) \ + $(m_encap_la_SOURCES) $(m_eob_la_SOURCES) \ + $(m_etrace_la_SOURCES) $(m_gline_la_SOURCES) \ + $(m_globops_la_SOURCES) $(m_hash_la_SOURCES) \ + $(m_help_la_SOURCES) $(m_info_la_SOURCES) \ + $(m_invite_la_SOURCES) $(m_ison_la_SOURCES) \ + $(m_kline_la_SOURCES) $(m_knock_la_SOURCES) \ + $(m_links_la_SOURCES) $(m_list_la_SOURCES) \ + $(m_locops_la_SOURCES) $(m_lusers_la_SOURCES) \ + $(m_map_la_SOURCES) $(m_module_la_SOURCES) \ + $(m_motd_la_SOURCES) $(m_names_la_SOURCES) \ + $(m_oper_la_SOURCES) $(m_operwall_la_SOURCES) \ + $(m_pass_la_SOURCES) $(m_ping_la_SOURCES) $(m_pong_la_SOURCES) \ + $(m_post_la_SOURCES) $(m_rehash_la_SOURCES) \ + $(m_restart_la_SOURCES) $(m_resv_la_SOURCES) \ + $(m_services_la_SOURCES) $(m_set_la_SOURCES) \ + $(m_stats_la_SOURCES) $(m_svinfo_la_SOURCES) \ + $(m_svsmode_la_SOURCES) $(m_svsnick_la_SOURCES) \ + $(m_tburst_la_SOURCES) $(m_testline_la_SOURCES) \ + $(m_testmask_la_SOURCES) $(m_time_la_SOURCES) \ + $(m_topic_la_SOURCES) $(m_trace_la_SOURCES) \ + $(m_user_la_SOURCES) $(m_userhost_la_SOURCES) \ + $(m_users_la_SOURCES) $(m_version_la_SOURCES) \ + $(m_wallops_la_SOURCES) $(m_watch_la_SOURCES) \ + $(m_who_la_SOURCES) $(m_whois_la_SOURCES) \ + $(m_whowas_la_SOURCES) $(m_xline_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBDIR = @LIBDIR@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PREFIX = @PREFIX@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +MODULE_FLAGS = -module -avoid-version +SUBDIRS = core +AM_CPPFLAGS = -I$(top_srcdir)/include +modulesdir = $(pkglibdir)/modules/autoload +modules_LTLIBRARIES = m_accept.la \ + m_admin.la \ + m_away.la \ + m_capab.la \ + m_cap.la \ + m_challenge.la \ + m_close.la \ + m_connect.la \ + m_dline.la \ + m_encap.la \ + m_eob.la \ + m_etrace.la \ + m_gline.la \ + m_globops.la \ + m_hash.la \ + m_help.la \ + m_info.la \ + m_invite.la \ + m_ison.la \ + m_kline.la \ + m_knock.la \ + m_links.la \ + m_list.la \ + m_locops.la \ + m_lusers.la \ + m_map.la \ + m_module.la \ + m_motd.la \ + m_names.la \ + m_oper.la \ + m_operwall.la \ + m_pass.la \ + m_ping.la \ + m_pong.la \ + m_post.la \ + m_rehash.la \ + m_restart.la \ + m_resv.la \ + m_set.la \ + m_services.la \ + m_stats.la \ + m_svinfo.la \ + m_svsmode.la \ + m_svsnick.la \ + m_tburst.la \ + m_testline.la \ + m_testmask.la \ + m_time.la \ + m_topic.la \ + m_trace.la \ + m_user.la \ + m_userhost.la \ + m_users.la \ + m_version.la \ + m_wallops.la \ + m_watch.la \ + m_who.la \ + m_whois.la \ + m_whowas.la \ + m_xline.la + +m_challenge_la_LDFLAGS = $(MODULE_FLAGS) +m_accept_la_LDFLAGS = $(MODULE_FLAGS) +m_admin_la_LDFLAGS = $(MODULE_FLAGS) +m_away_la_LDFLAGS = $(MODULE_FLAGS) +m_capab_la_LDFLAGS = $(MODULE_FLAGS) +m_cap_la_LDFLAGS = $(MODULE_FLAGS) +m_close_la_LDFLAGS = $(MODULE_FLAGS) +m_connect_la_LDFLAGS = $(MODULE_FLAGS) +m_dline_la_LDFLAGS = $(MODULE_FLAGS) +m_encap_la_LDFLAGS = $(MODULE_FLAGS) +m_eob_la_LDFLAGS = $(MODULE_FLAGS) +m_etrace_la_LDFLAGS = $(MODULE_FLAGS) +m_gline_la_LDFLAGS = $(MODULE_FLAGS) +m_globops_la_LDFLAGS = $(MODULE_FLAGS) +m_hash_la_LDFLAGS = $(MODULE_FLAGS) +m_help_la_LDFLAGS = $(MODULE_FLAGS) +m_info_la_LDFLAGS = $(MODULE_FLAGS) +m_invite_la_LDFLAGS = $(MODULE_FLAGS) +m_ison_la_LDFLAGS = $(MODULE_FLAGS) +m_kline_la_LDFLAGS = $(MODULE_FLAGS) +m_knock_la_LDFLAGS = $(MODULE_FLAGS) +m_links_la_LDFLAGS = $(MODULE_FLAGS) +m_list_la_LDFLAGS = $(MODULE_FLAGS) +m_locops_la_LDFLAGS = $(MODULE_FLAGS) +m_lusers_la_LDFLAGS = $(MODULE_FLAGS) +m_map_la_LDFLAGS = $(MODULE_FLAGS) +m_module_la_LDFLAGS = $(MODULE_FLAGS) +m_motd_la_LDFLAGS = $(MODULE_FLAGS) +m_names_la_LDFLAGS = $(MODULE_FLAGS) +m_oper_la_LDFLAGS = $(MODULE_FLAGS) +m_operwall_la_LDFLAGS = $(MODULE_FLAGS) +m_pass_la_LDFLAGS = $(MODULE_FLAGS) +m_ping_la_LDFLAGS = $(MODULE_FLAGS) +m_pong_la_LDFLAGS = $(MODULE_FLAGS) +m_post_la_LDFLAGS = $(MODULE_FLAGS) +m_rehash_la_LDFLAGS = $(MODULE_FLAGS) +m_restart_la_LDFLAGS = $(MODULE_FLAGS) +m_resv_la_LDFLAGS = $(MODULE_FLAGS) +m_set_la_LDFLAGS = $(MODULE_FLAGS) +m_services_la_LDFLAGS = $(MODULE_FLAGS) +m_stats_la_LDFLAGS = $(MODULE_FLAGS) +m_svinfo_la_LDFLAGS = $(MODULE_FLAGS) +m_svsmode_la_LDFLAGS = $(MODULE_FLAGS) +m_svsnick_la_LDFLAGS = $(MODULE_FLAGS) +m_tburst_la_LDFLAGS = $(MODULE_FLAGS) +m_testline_la_LDFLAGS = $(MODULE_FLAGS) +m_testmask_la_LDFLAGS = $(MODULE_FLAGS) +m_time_la_LDFLAGS = $(MODULE_FLAGS) +m_topic_la_LDFLAGS = $(MODULE_FLAGS) +m_trace_la_LDFLAGS = $(MODULE_FLAGS) +m_user_la_LDFLAGS = $(MODULE_FLAGS) +m_userhost_la_LDFLAGS = $(MODULE_FLAGS) +m_users_la_LDFLAGS = $(MODULE_FLAGS) +m_version_la_LDFLAGS = $(MODULE_FLAGS) +m_wallops_la_LDFLAGS = $(MODULE_FLAGS) +m_watch_la_LDFLAGS = $(MODULE_FLAGS) +m_who_la_LDFLAGS = $(MODULE_FLAGS) +m_whois_la_LDFLAGS = $(MODULE_FLAGS) +m_whowas_la_LDFLAGS = $(MODULE_FLAGS) +m_xline_la_LDFLAGS = $(MODULE_FLAGS) +m_accept_la_SOURCES = m_accept.c +m_admin_la_SOURCES = m_admin.c +m_away_la_SOURCES = m_away.c +m_capab_la_SOURCES = m_capab.c +m_cap_la_SOURCES = m_cap.c +m_challenge_la_SOURCES = m_challenge.c +m_close_la_SOURCES = m_close.c +m_connect_la_SOURCES = m_connect.c +m_dline_la_SOURCES = m_dline.c +m_encap_la_SOURCES = m_encap.c +m_eob_la_SOURCES = m_eob.c +m_etrace_la_SOURCES = m_etrace.c +m_gline_la_SOURCES = m_gline.c +m_globops_la_SOURCES = m_globops.c +m_hash_la_SOURCES = m_hash.c +m_help_la_SOURCES = m_help.c +m_info_la_SOURCES = m_info.c +m_invite_la_SOURCES = m_invite.c +m_ison_la_SOURCES = m_ison.c +m_kline_la_SOURCES = m_kline.c +m_knock_la_SOURCES = m_knock.c +m_links_la_SOURCES = m_links.c +m_list_la_SOURCES = m_list.c +m_locops_la_SOURCES = m_locops.c +m_lusers_la_SOURCES = m_lusers.c +m_map_la_SOURCES = m_map.c +m_module_la_SOURCES = m_module.c +m_motd_la_SOURCES = m_motd.c +m_names_la_SOURCES = m_names.c +m_oper_la_SOURCES = m_oper.c +m_operwall_la_SOURCES = m_operwall.c +m_pass_la_SOURCES = m_pass.c +m_ping_la_SOURCES = m_ping.c +m_pong_la_SOURCES = m_pong.c +m_post_la_SOURCES = m_post.c +m_rehash_la_SOURCES = m_rehash.c +m_restart_la_SOURCES = m_restart.c +m_resv_la_SOURCES = m_resv.c +m_set_la_SOURCES = m_set.c +m_services_la_SOURCES = m_services.c +m_stats_la_SOURCES = m_stats.c +m_svinfo_la_SOURCES = m_svinfo.c +m_svsmode_la_SOURCES = m_svsmode.c +m_svsnick_la_SOURCES = m_svsnick.c +m_tburst_la_SOURCES = m_tburst.c +m_testline_la_SOURCES = m_testline.c +m_testmask_la_SOURCES = m_testmask.c +m_time_la_SOURCES = m_time.c +m_topic_la_SOURCES = m_topic.c +m_trace_la_SOURCES = m_trace.c +m_user_la_SOURCES = m_user.c +m_userhost_la_SOURCES = m_userhost.c +m_users_la_SOURCES = m_users.c +m_version_la_SOURCES = m_version.c +m_wallops_la_SOURCES = m_wallops.c +m_watch_la_SOURCES = m_watch.c +m_who_la_SOURCES = m_who.c +m_whois_la_SOURCES = m_whois.c +m_whowas_la_SOURCES = m_whowas.c +m_xline_la_SOURCES = m_xline.c +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign modules/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign modules/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-modulesLTLIBRARIES: $(modules_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(modules_LTLIBRARIES)'; test -n "$(modulesdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(modulesdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(modulesdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(modulesdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(modulesdir)"; \ + } + +uninstall-modulesLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(modules_LTLIBRARIES)'; test -n "$(modulesdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(modulesdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(modulesdir)/$$f"; \ + done + +clean-modulesLTLIBRARIES: + -test -z "$(modules_LTLIBRARIES)" || rm -f $(modules_LTLIBRARIES) + @list='$(modules_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +m_accept.la: $(m_accept_la_OBJECTS) $(m_accept_la_DEPENDENCIES) $(EXTRA_m_accept_la_DEPENDENCIES) + $(m_accept_la_LINK) -rpath $(modulesdir) $(m_accept_la_OBJECTS) $(m_accept_la_LIBADD) $(LIBS) +m_admin.la: $(m_admin_la_OBJECTS) $(m_admin_la_DEPENDENCIES) $(EXTRA_m_admin_la_DEPENDENCIES) + $(m_admin_la_LINK) -rpath $(modulesdir) $(m_admin_la_OBJECTS) $(m_admin_la_LIBADD) $(LIBS) +m_away.la: $(m_away_la_OBJECTS) $(m_away_la_DEPENDENCIES) $(EXTRA_m_away_la_DEPENDENCIES) + $(m_away_la_LINK) -rpath $(modulesdir) $(m_away_la_OBJECTS) $(m_away_la_LIBADD) $(LIBS) +m_cap.la: $(m_cap_la_OBJECTS) $(m_cap_la_DEPENDENCIES) $(EXTRA_m_cap_la_DEPENDENCIES) + $(m_cap_la_LINK) -rpath $(modulesdir) $(m_cap_la_OBJECTS) $(m_cap_la_LIBADD) $(LIBS) +m_capab.la: $(m_capab_la_OBJECTS) $(m_capab_la_DEPENDENCIES) $(EXTRA_m_capab_la_DEPENDENCIES) + $(m_capab_la_LINK) -rpath $(modulesdir) $(m_capab_la_OBJECTS) $(m_capab_la_LIBADD) $(LIBS) +m_challenge.la: $(m_challenge_la_OBJECTS) $(m_challenge_la_DEPENDENCIES) $(EXTRA_m_challenge_la_DEPENDENCIES) + $(m_challenge_la_LINK) -rpath $(modulesdir) $(m_challenge_la_OBJECTS) $(m_challenge_la_LIBADD) $(LIBS) +m_close.la: $(m_close_la_OBJECTS) $(m_close_la_DEPENDENCIES) $(EXTRA_m_close_la_DEPENDENCIES) + $(m_close_la_LINK) -rpath $(modulesdir) $(m_close_la_OBJECTS) $(m_close_la_LIBADD) $(LIBS) +m_connect.la: $(m_connect_la_OBJECTS) $(m_connect_la_DEPENDENCIES) $(EXTRA_m_connect_la_DEPENDENCIES) + $(m_connect_la_LINK) -rpath $(modulesdir) $(m_connect_la_OBJECTS) $(m_connect_la_LIBADD) $(LIBS) +m_dline.la: $(m_dline_la_OBJECTS) $(m_dline_la_DEPENDENCIES) $(EXTRA_m_dline_la_DEPENDENCIES) + $(m_dline_la_LINK) -rpath $(modulesdir) $(m_dline_la_OBJECTS) $(m_dline_la_LIBADD) $(LIBS) +m_encap.la: $(m_encap_la_OBJECTS) $(m_encap_la_DEPENDENCIES) $(EXTRA_m_encap_la_DEPENDENCIES) + $(m_encap_la_LINK) -rpath $(modulesdir) $(m_encap_la_OBJECTS) $(m_encap_la_LIBADD) $(LIBS) +m_eob.la: $(m_eob_la_OBJECTS) $(m_eob_la_DEPENDENCIES) $(EXTRA_m_eob_la_DEPENDENCIES) + $(m_eob_la_LINK) -rpath $(modulesdir) $(m_eob_la_OBJECTS) $(m_eob_la_LIBADD) $(LIBS) +m_etrace.la: $(m_etrace_la_OBJECTS) $(m_etrace_la_DEPENDENCIES) $(EXTRA_m_etrace_la_DEPENDENCIES) + $(m_etrace_la_LINK) -rpath $(modulesdir) $(m_etrace_la_OBJECTS) $(m_etrace_la_LIBADD) $(LIBS) +m_gline.la: $(m_gline_la_OBJECTS) $(m_gline_la_DEPENDENCIES) $(EXTRA_m_gline_la_DEPENDENCIES) + $(m_gline_la_LINK) -rpath $(modulesdir) $(m_gline_la_OBJECTS) $(m_gline_la_LIBADD) $(LIBS) +m_globops.la: $(m_globops_la_OBJECTS) $(m_globops_la_DEPENDENCIES) $(EXTRA_m_globops_la_DEPENDENCIES) + $(m_globops_la_LINK) -rpath $(modulesdir) $(m_globops_la_OBJECTS) $(m_globops_la_LIBADD) $(LIBS) +m_hash.la: $(m_hash_la_OBJECTS) $(m_hash_la_DEPENDENCIES) $(EXTRA_m_hash_la_DEPENDENCIES) + $(m_hash_la_LINK) -rpath $(modulesdir) $(m_hash_la_OBJECTS) $(m_hash_la_LIBADD) $(LIBS) +m_help.la: $(m_help_la_OBJECTS) $(m_help_la_DEPENDENCIES) $(EXTRA_m_help_la_DEPENDENCIES) + $(m_help_la_LINK) -rpath $(modulesdir) $(m_help_la_OBJECTS) $(m_help_la_LIBADD) $(LIBS) +m_info.la: $(m_info_la_OBJECTS) $(m_info_la_DEPENDENCIES) $(EXTRA_m_info_la_DEPENDENCIES) + $(m_info_la_LINK) -rpath $(modulesdir) $(m_info_la_OBJECTS) $(m_info_la_LIBADD) $(LIBS) +m_invite.la: $(m_invite_la_OBJECTS) $(m_invite_la_DEPENDENCIES) $(EXTRA_m_invite_la_DEPENDENCIES) + $(m_invite_la_LINK) -rpath $(modulesdir) $(m_invite_la_OBJECTS) $(m_invite_la_LIBADD) $(LIBS) +m_ison.la: $(m_ison_la_OBJECTS) $(m_ison_la_DEPENDENCIES) $(EXTRA_m_ison_la_DEPENDENCIES) + $(m_ison_la_LINK) -rpath $(modulesdir) $(m_ison_la_OBJECTS) $(m_ison_la_LIBADD) $(LIBS) +m_kline.la: $(m_kline_la_OBJECTS) $(m_kline_la_DEPENDENCIES) $(EXTRA_m_kline_la_DEPENDENCIES) + $(m_kline_la_LINK) -rpath $(modulesdir) $(m_kline_la_OBJECTS) $(m_kline_la_LIBADD) $(LIBS) +m_knock.la: $(m_knock_la_OBJECTS) $(m_knock_la_DEPENDENCIES) $(EXTRA_m_knock_la_DEPENDENCIES) + $(m_knock_la_LINK) -rpath $(modulesdir) $(m_knock_la_OBJECTS) $(m_knock_la_LIBADD) $(LIBS) +m_links.la: $(m_links_la_OBJECTS) $(m_links_la_DEPENDENCIES) $(EXTRA_m_links_la_DEPENDENCIES) + $(m_links_la_LINK) -rpath $(modulesdir) $(m_links_la_OBJECTS) $(m_links_la_LIBADD) $(LIBS) +m_list.la: $(m_list_la_OBJECTS) $(m_list_la_DEPENDENCIES) $(EXTRA_m_list_la_DEPENDENCIES) + $(m_list_la_LINK) -rpath $(modulesdir) $(m_list_la_OBJECTS) $(m_list_la_LIBADD) $(LIBS) +m_locops.la: $(m_locops_la_OBJECTS) $(m_locops_la_DEPENDENCIES) $(EXTRA_m_locops_la_DEPENDENCIES) + $(m_locops_la_LINK) -rpath $(modulesdir) $(m_locops_la_OBJECTS) $(m_locops_la_LIBADD) $(LIBS) +m_lusers.la: $(m_lusers_la_OBJECTS) $(m_lusers_la_DEPENDENCIES) $(EXTRA_m_lusers_la_DEPENDENCIES) + $(m_lusers_la_LINK) -rpath $(modulesdir) $(m_lusers_la_OBJECTS) $(m_lusers_la_LIBADD) $(LIBS) +m_map.la: $(m_map_la_OBJECTS) $(m_map_la_DEPENDENCIES) $(EXTRA_m_map_la_DEPENDENCIES) + $(m_map_la_LINK) -rpath $(modulesdir) $(m_map_la_OBJECTS) $(m_map_la_LIBADD) $(LIBS) +m_module.la: $(m_module_la_OBJECTS) $(m_module_la_DEPENDENCIES) $(EXTRA_m_module_la_DEPENDENCIES) + $(m_module_la_LINK) -rpath $(modulesdir) $(m_module_la_OBJECTS) $(m_module_la_LIBADD) $(LIBS) +m_motd.la: $(m_motd_la_OBJECTS) $(m_motd_la_DEPENDENCIES) $(EXTRA_m_motd_la_DEPENDENCIES) + $(m_motd_la_LINK) -rpath $(modulesdir) $(m_motd_la_OBJECTS) $(m_motd_la_LIBADD) $(LIBS) +m_names.la: $(m_names_la_OBJECTS) $(m_names_la_DEPENDENCIES) $(EXTRA_m_names_la_DEPENDENCIES) + $(m_names_la_LINK) -rpath $(modulesdir) $(m_names_la_OBJECTS) $(m_names_la_LIBADD) $(LIBS) +m_oper.la: $(m_oper_la_OBJECTS) $(m_oper_la_DEPENDENCIES) $(EXTRA_m_oper_la_DEPENDENCIES) + $(m_oper_la_LINK) -rpath $(modulesdir) $(m_oper_la_OBJECTS) $(m_oper_la_LIBADD) $(LIBS) +m_operwall.la: $(m_operwall_la_OBJECTS) $(m_operwall_la_DEPENDENCIES) $(EXTRA_m_operwall_la_DEPENDENCIES) + $(m_operwall_la_LINK) -rpath $(modulesdir) $(m_operwall_la_OBJECTS) $(m_operwall_la_LIBADD) $(LIBS) +m_pass.la: $(m_pass_la_OBJECTS) $(m_pass_la_DEPENDENCIES) $(EXTRA_m_pass_la_DEPENDENCIES) + $(m_pass_la_LINK) -rpath $(modulesdir) $(m_pass_la_OBJECTS) $(m_pass_la_LIBADD) $(LIBS) +m_ping.la: $(m_ping_la_OBJECTS) $(m_ping_la_DEPENDENCIES) $(EXTRA_m_ping_la_DEPENDENCIES) + $(m_ping_la_LINK) -rpath $(modulesdir) $(m_ping_la_OBJECTS) $(m_ping_la_LIBADD) $(LIBS) +m_pong.la: $(m_pong_la_OBJECTS) $(m_pong_la_DEPENDENCIES) $(EXTRA_m_pong_la_DEPENDENCIES) + $(m_pong_la_LINK) -rpath $(modulesdir) $(m_pong_la_OBJECTS) $(m_pong_la_LIBADD) $(LIBS) +m_post.la: $(m_post_la_OBJECTS) $(m_post_la_DEPENDENCIES) $(EXTRA_m_post_la_DEPENDENCIES) + $(m_post_la_LINK) -rpath $(modulesdir) $(m_post_la_OBJECTS) $(m_post_la_LIBADD) $(LIBS) +m_rehash.la: $(m_rehash_la_OBJECTS) $(m_rehash_la_DEPENDENCIES) $(EXTRA_m_rehash_la_DEPENDENCIES) + $(m_rehash_la_LINK) -rpath $(modulesdir) $(m_rehash_la_OBJECTS) $(m_rehash_la_LIBADD) $(LIBS) +m_restart.la: $(m_restart_la_OBJECTS) $(m_restart_la_DEPENDENCIES) $(EXTRA_m_restart_la_DEPENDENCIES) + $(m_restart_la_LINK) -rpath $(modulesdir) $(m_restart_la_OBJECTS) $(m_restart_la_LIBADD) $(LIBS) +m_resv.la: $(m_resv_la_OBJECTS) $(m_resv_la_DEPENDENCIES) $(EXTRA_m_resv_la_DEPENDENCIES) + $(m_resv_la_LINK) -rpath $(modulesdir) $(m_resv_la_OBJECTS) $(m_resv_la_LIBADD) $(LIBS) +m_services.la: $(m_services_la_OBJECTS) $(m_services_la_DEPENDENCIES) $(EXTRA_m_services_la_DEPENDENCIES) + $(m_services_la_LINK) -rpath $(modulesdir) $(m_services_la_OBJECTS) $(m_services_la_LIBADD) $(LIBS) +m_set.la: $(m_set_la_OBJECTS) $(m_set_la_DEPENDENCIES) $(EXTRA_m_set_la_DEPENDENCIES) + $(m_set_la_LINK) -rpath $(modulesdir) $(m_set_la_OBJECTS) $(m_set_la_LIBADD) $(LIBS) +m_stats.la: $(m_stats_la_OBJECTS) $(m_stats_la_DEPENDENCIES) $(EXTRA_m_stats_la_DEPENDENCIES) + $(m_stats_la_LINK) -rpath $(modulesdir) $(m_stats_la_OBJECTS) $(m_stats_la_LIBADD) $(LIBS) +m_svinfo.la: $(m_svinfo_la_OBJECTS) $(m_svinfo_la_DEPENDENCIES) $(EXTRA_m_svinfo_la_DEPENDENCIES) + $(m_svinfo_la_LINK) -rpath $(modulesdir) $(m_svinfo_la_OBJECTS) $(m_svinfo_la_LIBADD) $(LIBS) +m_svsmode.la: $(m_svsmode_la_OBJECTS) $(m_svsmode_la_DEPENDENCIES) $(EXTRA_m_svsmode_la_DEPENDENCIES) + $(m_svsmode_la_LINK) -rpath $(modulesdir) $(m_svsmode_la_OBJECTS) $(m_svsmode_la_LIBADD) $(LIBS) +m_svsnick.la: $(m_svsnick_la_OBJECTS) $(m_svsnick_la_DEPENDENCIES) $(EXTRA_m_svsnick_la_DEPENDENCIES) + $(m_svsnick_la_LINK) -rpath $(modulesdir) $(m_svsnick_la_OBJECTS) $(m_svsnick_la_LIBADD) $(LIBS) +m_tburst.la: $(m_tburst_la_OBJECTS) $(m_tburst_la_DEPENDENCIES) $(EXTRA_m_tburst_la_DEPENDENCIES) + $(m_tburst_la_LINK) -rpath $(modulesdir) $(m_tburst_la_OBJECTS) $(m_tburst_la_LIBADD) $(LIBS) +m_testline.la: $(m_testline_la_OBJECTS) $(m_testline_la_DEPENDENCIES) $(EXTRA_m_testline_la_DEPENDENCIES) + $(m_testline_la_LINK) -rpath $(modulesdir) $(m_testline_la_OBJECTS) $(m_testline_la_LIBADD) $(LIBS) +m_testmask.la: $(m_testmask_la_OBJECTS) $(m_testmask_la_DEPENDENCIES) $(EXTRA_m_testmask_la_DEPENDENCIES) + $(m_testmask_la_LINK) -rpath $(modulesdir) $(m_testmask_la_OBJECTS) $(m_testmask_la_LIBADD) $(LIBS) +m_time.la: $(m_time_la_OBJECTS) $(m_time_la_DEPENDENCIES) $(EXTRA_m_time_la_DEPENDENCIES) + $(m_time_la_LINK) -rpath $(modulesdir) $(m_time_la_OBJECTS) $(m_time_la_LIBADD) $(LIBS) +m_topic.la: $(m_topic_la_OBJECTS) $(m_topic_la_DEPENDENCIES) $(EXTRA_m_topic_la_DEPENDENCIES) + $(m_topic_la_LINK) -rpath $(modulesdir) $(m_topic_la_OBJECTS) $(m_topic_la_LIBADD) $(LIBS) +m_trace.la: $(m_trace_la_OBJECTS) $(m_trace_la_DEPENDENCIES) $(EXTRA_m_trace_la_DEPENDENCIES) + $(m_trace_la_LINK) -rpath $(modulesdir) $(m_trace_la_OBJECTS) $(m_trace_la_LIBADD) $(LIBS) +m_user.la: $(m_user_la_OBJECTS) $(m_user_la_DEPENDENCIES) $(EXTRA_m_user_la_DEPENDENCIES) + $(m_user_la_LINK) -rpath $(modulesdir) $(m_user_la_OBJECTS) $(m_user_la_LIBADD) $(LIBS) +m_userhost.la: $(m_userhost_la_OBJECTS) $(m_userhost_la_DEPENDENCIES) $(EXTRA_m_userhost_la_DEPENDENCIES) + $(m_userhost_la_LINK) -rpath $(modulesdir) $(m_userhost_la_OBJECTS) $(m_userhost_la_LIBADD) $(LIBS) +m_users.la: $(m_users_la_OBJECTS) $(m_users_la_DEPENDENCIES) $(EXTRA_m_users_la_DEPENDENCIES) + $(m_users_la_LINK) -rpath $(modulesdir) $(m_users_la_OBJECTS) $(m_users_la_LIBADD) $(LIBS) +m_version.la: $(m_version_la_OBJECTS) $(m_version_la_DEPENDENCIES) $(EXTRA_m_version_la_DEPENDENCIES) + $(m_version_la_LINK) -rpath $(modulesdir) $(m_version_la_OBJECTS) $(m_version_la_LIBADD) $(LIBS) +m_wallops.la: $(m_wallops_la_OBJECTS) $(m_wallops_la_DEPENDENCIES) $(EXTRA_m_wallops_la_DEPENDENCIES) + $(m_wallops_la_LINK) -rpath $(modulesdir) $(m_wallops_la_OBJECTS) $(m_wallops_la_LIBADD) $(LIBS) +m_watch.la: $(m_watch_la_OBJECTS) $(m_watch_la_DEPENDENCIES) $(EXTRA_m_watch_la_DEPENDENCIES) + $(m_watch_la_LINK) -rpath $(modulesdir) $(m_watch_la_OBJECTS) $(m_watch_la_LIBADD) $(LIBS) +m_who.la: $(m_who_la_OBJECTS) $(m_who_la_DEPENDENCIES) $(EXTRA_m_who_la_DEPENDENCIES) + $(m_who_la_LINK) -rpath $(modulesdir) $(m_who_la_OBJECTS) $(m_who_la_LIBADD) $(LIBS) +m_whois.la: $(m_whois_la_OBJECTS) $(m_whois_la_DEPENDENCIES) $(EXTRA_m_whois_la_DEPENDENCIES) + $(m_whois_la_LINK) -rpath $(modulesdir) $(m_whois_la_OBJECTS) $(m_whois_la_LIBADD) $(LIBS) +m_whowas.la: $(m_whowas_la_OBJECTS) $(m_whowas_la_DEPENDENCIES) $(EXTRA_m_whowas_la_DEPENDENCIES) + $(m_whowas_la_LINK) -rpath $(modulesdir) $(m_whowas_la_OBJECTS) $(m_whowas_la_LIBADD) $(LIBS) +m_xline.la: $(m_xline_la_OBJECTS) $(m_xline_la_DEPENDENCIES) $(EXTRA_m_xline_la_DEPENDENCIES) + $(m_xline_la_LINK) -rpath $(modulesdir) $(m_xline_la_OBJECTS) $(m_xline_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_accept.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_admin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_away.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_cap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_capab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_challenge.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_close.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_connect.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_dline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_encap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_eob.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_etrace.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_gline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_globops.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_hash.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_help.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_info.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_invite.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_ison.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_kline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_knock.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_links.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_list.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_locops.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_lusers.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_map.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_module.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_motd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_names.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_oper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_operwall.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_pass.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_ping.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_pong.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_post.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_rehash.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_restart.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_resv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_services.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_set.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_stats.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_svinfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_svsmode.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_svsnick.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_tburst.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_testline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_testmask.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_time.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_topic.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_trace.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_user.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_userhost.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_users.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_version.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_wallops.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_watch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_who.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_whois.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_whowas.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_xline.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done +cscopelist-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(modulesdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-modulesLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-modulesLTLIBRARIES + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-modulesLTLIBRARIES + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) \ + cscopelist-recursive ctags-recursive install-am install-strip \ + tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + clean-modulesLTLIBRARIES cscopelist cscopelist-recursive ctags \ + ctags-recursive distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-modulesLTLIBRARIES \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-modulesLTLIBRARIES + + +modules: $(modules_LTLIBRARIES) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/modules/core/Makefile.am b/modules/core/Makefile.am new file mode 100644 index 0000000..6e4cbba --- /dev/null +++ b/modules/core/Makefile.am @@ -0,0 +1,58 @@ +AUTOMAKE_OPTIONS = foreign +MODULE_FLAGS = -module -avoid-version + +AM_CPPFLAGS = -I$(top_srcdir)/include +modulesdir = $(pkglibdir)/modules + + +m_die_la_LDFLAGS = $(MODULE_FLAGS) +m_error_la_LDFLAGS = $(MODULE_FLAGS) +m_join_la_LDFLAGS = $(MODULE_FLAGS) +m_kick_la_LDFLAGS = $(MODULE_FLAGS) +m_kill_la_LDFLAGS = $(MODULE_FLAGS) +m_message_la_LDFLAGS = $(MODULE_FLAGS) +m_mode_la_LDFLAGS = $(MODULE_FLAGS) +m_nick_la_LDFLAGS = $(MODULE_FLAGS) +m_part_la_LDFLAGS = $(MODULE_FLAGS) +m_quit_la_LDFLAGS = $(MODULE_FLAGS) +m_server_la_LDFLAGS = $(MODULE_FLAGS) +m_sjoin_la_LDFLAGS = $(MODULE_FLAGS) +m_squit_la_LDFLAGS = $(MODULE_FLAGS) + +m_die_la_SOURCES = m_die.c +m_error_la_SOURCES = m_error.c +m_join_la_SOURCES = m_join.c +m_kick_la_SOURCES = m_kick.c +m_kill_la_SOURCES = m_kill.c +m_message_la_SOURCES = m_message.c +m_mode_la_SOURCES = m_mode.c +m_nick_la_SOURCES = m_nick.c +m_part_la_SOURCES = m_part.c +m_quit_la_SOURCES = m_quit.c +m_server_la_SOURCES = m_server.c +m_sjoin_la_SOURCES = m_sjoin.c +m_squit_la_SOURCES = m_squit.c + +modules_LTLIBRARIES = m_die.la \ + m_error.la \ + m_join.la \ + m_kick.la \ + m_kill.la \ + m_message.la \ + m_mode.la \ + m_nick.la \ + m_part.la \ + m_quit.la \ + m_server.la \ + m_sjoin.la \ + m_squit.la + +modules: $(modules_LTLIBRARIES) + +install-exec-hook: + if test -d $(DESTDIR)$(pkglibdir)-old; then \ + rm -rf $(DESTDIR)$(pkglibdir)-old; \ + fi + if test -d $(DESTDIR)$(pkglibdir); then \ + mv $(DESTDIR)$(pkglibdir) $(DESTDIR)$(pkglibdir)-old; \ + fi diff --git a/modules/core/Makefile.in b/modules/core/Makefile.in new file mode 100644 index 0000000..9af88eb --- /dev/null +++ b/modules/core/Makefile.in @@ -0,0 +1,766 @@ +# Makefile.in generated by automake 1.12.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = modules/core +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(modulesdir)" +LTLIBRARIES = $(modules_LTLIBRARIES) +m_die_la_LIBADD = +am_m_die_la_OBJECTS = m_die.lo +m_die_la_OBJECTS = $(am_m_die_la_OBJECTS) +m_die_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(m_die_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +m_error_la_LIBADD = +am_m_error_la_OBJECTS = m_error.lo +m_error_la_OBJECTS = $(am_m_error_la_OBJECTS) +m_error_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_error_la_LDFLAGS) $(LDFLAGS) -o $@ +m_join_la_LIBADD = +am_m_join_la_OBJECTS = m_join.lo +m_join_la_OBJECTS = $(am_m_join_la_OBJECTS) +m_join_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_join_la_LDFLAGS) $(LDFLAGS) -o $@ +m_kick_la_LIBADD = +am_m_kick_la_OBJECTS = m_kick.lo +m_kick_la_OBJECTS = $(am_m_kick_la_OBJECTS) +m_kick_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_kick_la_LDFLAGS) $(LDFLAGS) -o $@ +m_kill_la_LIBADD = +am_m_kill_la_OBJECTS = m_kill.lo +m_kill_la_OBJECTS = $(am_m_kill_la_OBJECTS) +m_kill_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_kill_la_LDFLAGS) $(LDFLAGS) -o $@ +m_message_la_LIBADD = +am_m_message_la_OBJECTS = m_message.lo +m_message_la_OBJECTS = $(am_m_message_la_OBJECTS) +m_message_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_message_la_LDFLAGS) $(LDFLAGS) -o $@ +m_mode_la_LIBADD = +am_m_mode_la_OBJECTS = m_mode.lo +m_mode_la_OBJECTS = $(am_m_mode_la_OBJECTS) +m_mode_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_mode_la_LDFLAGS) $(LDFLAGS) -o $@ +m_nick_la_LIBADD = +am_m_nick_la_OBJECTS = m_nick.lo +m_nick_la_OBJECTS = $(am_m_nick_la_OBJECTS) +m_nick_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_nick_la_LDFLAGS) $(LDFLAGS) -o $@ +m_part_la_LIBADD = +am_m_part_la_OBJECTS = m_part.lo +m_part_la_OBJECTS = $(am_m_part_la_OBJECTS) +m_part_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_part_la_LDFLAGS) $(LDFLAGS) -o $@ +m_quit_la_LIBADD = +am_m_quit_la_OBJECTS = m_quit.lo +m_quit_la_OBJECTS = $(am_m_quit_la_OBJECTS) +m_quit_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_quit_la_LDFLAGS) $(LDFLAGS) -o $@ +m_server_la_LIBADD = +am_m_server_la_OBJECTS = m_server.lo +m_server_la_OBJECTS = $(am_m_server_la_OBJECTS) +m_server_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_server_la_LDFLAGS) $(LDFLAGS) -o $@ +m_sjoin_la_LIBADD = +am_m_sjoin_la_OBJECTS = m_sjoin.lo +m_sjoin_la_OBJECTS = $(am_m_sjoin_la_OBJECTS) +m_sjoin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_sjoin_la_LDFLAGS) $(LDFLAGS) -o $@ +m_squit_la_LIBADD = +am_m_squit_la_OBJECTS = m_squit.lo +m_squit_la_OBJECTS = $(am_m_squit_la_OBJECTS) +m_squit_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(m_squit_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(m_die_la_SOURCES) $(m_error_la_SOURCES) \ + $(m_join_la_SOURCES) $(m_kick_la_SOURCES) $(m_kill_la_SOURCES) \ + $(m_message_la_SOURCES) $(m_mode_la_SOURCES) \ + $(m_nick_la_SOURCES) $(m_part_la_SOURCES) $(m_quit_la_SOURCES) \ + $(m_server_la_SOURCES) $(m_sjoin_la_SOURCES) \ + $(m_squit_la_SOURCES) +DIST_SOURCES = $(m_die_la_SOURCES) $(m_error_la_SOURCES) \ + $(m_join_la_SOURCES) $(m_kick_la_SOURCES) $(m_kill_la_SOURCES) \ + $(m_message_la_SOURCES) $(m_mode_la_SOURCES) \ + $(m_nick_la_SOURCES) $(m_part_la_SOURCES) $(m_quit_la_SOURCES) \ + $(m_server_la_SOURCES) $(m_sjoin_la_SOURCES) \ + $(m_squit_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBDIR = @LIBDIR@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PREFIX = @PREFIX@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +MODULE_FLAGS = -module -avoid-version +AM_CPPFLAGS = -I$(top_srcdir)/include +modulesdir = $(pkglibdir)/modules +m_die_la_LDFLAGS = $(MODULE_FLAGS) +m_error_la_LDFLAGS = $(MODULE_FLAGS) +m_join_la_LDFLAGS = $(MODULE_FLAGS) +m_kick_la_LDFLAGS = $(MODULE_FLAGS) +m_kill_la_LDFLAGS = $(MODULE_FLAGS) +m_message_la_LDFLAGS = $(MODULE_FLAGS) +m_mode_la_LDFLAGS = $(MODULE_FLAGS) +m_nick_la_LDFLAGS = $(MODULE_FLAGS) +m_part_la_LDFLAGS = $(MODULE_FLAGS) +m_quit_la_LDFLAGS = $(MODULE_FLAGS) +m_server_la_LDFLAGS = $(MODULE_FLAGS) +m_sjoin_la_LDFLAGS = $(MODULE_FLAGS) +m_squit_la_LDFLAGS = $(MODULE_FLAGS) +m_die_la_SOURCES = m_die.c +m_error_la_SOURCES = m_error.c +m_join_la_SOURCES = m_join.c +m_kick_la_SOURCES = m_kick.c +m_kill_la_SOURCES = m_kill.c +m_message_la_SOURCES = m_message.c +m_mode_la_SOURCES = m_mode.c +m_nick_la_SOURCES = m_nick.c +m_part_la_SOURCES = m_part.c +m_quit_la_SOURCES = m_quit.c +m_server_la_SOURCES = m_server.c +m_sjoin_la_SOURCES = m_sjoin.c +m_squit_la_SOURCES = m_squit.c +modules_LTLIBRARIES = m_die.la \ + m_error.la \ + m_join.la \ + m_kick.la \ + m_kill.la \ + m_message.la \ + m_mode.la \ + m_nick.la \ + m_part.la \ + m_quit.la \ + m_server.la \ + m_sjoin.la \ + m_squit.la + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign modules/core/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign modules/core/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-modulesLTLIBRARIES: $(modules_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(modules_LTLIBRARIES)'; test -n "$(modulesdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(modulesdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(modulesdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(modulesdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(modulesdir)"; \ + } + +uninstall-modulesLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(modules_LTLIBRARIES)'; test -n "$(modulesdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(modulesdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(modulesdir)/$$f"; \ + done + +clean-modulesLTLIBRARIES: + -test -z "$(modules_LTLIBRARIES)" || rm -f $(modules_LTLIBRARIES) + @list='$(modules_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +m_die.la: $(m_die_la_OBJECTS) $(m_die_la_DEPENDENCIES) $(EXTRA_m_die_la_DEPENDENCIES) + $(m_die_la_LINK) -rpath $(modulesdir) $(m_die_la_OBJECTS) $(m_die_la_LIBADD) $(LIBS) +m_error.la: $(m_error_la_OBJECTS) $(m_error_la_DEPENDENCIES) $(EXTRA_m_error_la_DEPENDENCIES) + $(m_error_la_LINK) -rpath $(modulesdir) $(m_error_la_OBJECTS) $(m_error_la_LIBADD) $(LIBS) +m_join.la: $(m_join_la_OBJECTS) $(m_join_la_DEPENDENCIES) $(EXTRA_m_join_la_DEPENDENCIES) + $(m_join_la_LINK) -rpath $(modulesdir) $(m_join_la_OBJECTS) $(m_join_la_LIBADD) $(LIBS) +m_kick.la: $(m_kick_la_OBJECTS) $(m_kick_la_DEPENDENCIES) $(EXTRA_m_kick_la_DEPENDENCIES) + $(m_kick_la_LINK) -rpath $(modulesdir) $(m_kick_la_OBJECTS) $(m_kick_la_LIBADD) $(LIBS) +m_kill.la: $(m_kill_la_OBJECTS) $(m_kill_la_DEPENDENCIES) $(EXTRA_m_kill_la_DEPENDENCIES) + $(m_kill_la_LINK) -rpath $(modulesdir) $(m_kill_la_OBJECTS) $(m_kill_la_LIBADD) $(LIBS) +m_message.la: $(m_message_la_OBJECTS) $(m_message_la_DEPENDENCIES) $(EXTRA_m_message_la_DEPENDENCIES) + $(m_message_la_LINK) -rpath $(modulesdir) $(m_message_la_OBJECTS) $(m_message_la_LIBADD) $(LIBS) +m_mode.la: $(m_mode_la_OBJECTS) $(m_mode_la_DEPENDENCIES) $(EXTRA_m_mode_la_DEPENDENCIES) + $(m_mode_la_LINK) -rpath $(modulesdir) $(m_mode_la_OBJECTS) $(m_mode_la_LIBADD) $(LIBS) +m_nick.la: $(m_nick_la_OBJECTS) $(m_nick_la_DEPENDENCIES) $(EXTRA_m_nick_la_DEPENDENCIES) + $(m_nick_la_LINK) -rpath $(modulesdir) $(m_nick_la_OBJECTS) $(m_nick_la_LIBADD) $(LIBS) +m_part.la: $(m_part_la_OBJECTS) $(m_part_la_DEPENDENCIES) $(EXTRA_m_part_la_DEPENDENCIES) + $(m_part_la_LINK) -rpath $(modulesdir) $(m_part_la_OBJECTS) $(m_part_la_LIBADD) $(LIBS) +m_quit.la: $(m_quit_la_OBJECTS) $(m_quit_la_DEPENDENCIES) $(EXTRA_m_quit_la_DEPENDENCIES) + $(m_quit_la_LINK) -rpath $(modulesdir) $(m_quit_la_OBJECTS) $(m_quit_la_LIBADD) $(LIBS) +m_server.la: $(m_server_la_OBJECTS) $(m_server_la_DEPENDENCIES) $(EXTRA_m_server_la_DEPENDENCIES) + $(m_server_la_LINK) -rpath $(modulesdir) $(m_server_la_OBJECTS) $(m_server_la_LIBADD) $(LIBS) +m_sjoin.la: $(m_sjoin_la_OBJECTS) $(m_sjoin_la_DEPENDENCIES) $(EXTRA_m_sjoin_la_DEPENDENCIES) + $(m_sjoin_la_LINK) -rpath $(modulesdir) $(m_sjoin_la_OBJECTS) $(m_sjoin_la_LIBADD) $(LIBS) +m_squit.la: $(m_squit_la_OBJECTS) $(m_squit_la_DEPENDENCIES) $(EXTRA_m_squit_la_DEPENDENCIES) + $(m_squit_la_LINK) -rpath $(modulesdir) $(m_squit_la_OBJECTS) $(m_squit_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_die.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_error.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_join.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_kick.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_kill.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_message.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_mode.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_nick.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_part.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_quit.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_server.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_sjoin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_squit.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscopelist: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(modulesdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-modulesLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-modulesLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-modulesLTLIBRARIES + +.MAKE: install-am install-exec-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-modulesLTLIBRARIES cscopelist ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-exec-hook install-html install-html-am \ + install-info install-info-am install-man \ + install-modulesLTLIBRARIES install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-modulesLTLIBRARIES + + +modules: $(modules_LTLIBRARIES) + +install-exec-hook: + if test -d $(DESTDIR)$(pkglibdir)-old; then \ + rm -rf $(DESTDIR)$(pkglibdir)-old; \ + fi + if test -d $(DESTDIR)$(pkglibdir); then \ + mv $(DESTDIR)$(pkglibdir) $(DESTDIR)$(pkglibdir)-old; \ + fi + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/modules/core/m_die.c b/modules/core/m_die.c new file mode 100644 index 0000000..b47c92c --- /dev/null +++ b/modules/core/m_die.c @@ -0,0 +1,97 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_die.c: Kills off this server. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "irc_string.h" +#include "numeric.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "restart.h" +#include "conf.h" + + +/* + * mo_die - DIE command handler + */ +static void +mo_die(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char buf[IRCD_BUFSIZE]; + + if (!HasOFlag(source_p, OPER_FLAG_DIE)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "die"); + return; + } + + if (parc < 2 || EmptyString(parv[1])) + { + sendto_one(source_p, ":%s NOTICE %s :Need server name /die %s", + me.name, source_p->name, me.name); + return; + } + + if (irccmp(parv[1], me.name)) + { + sendto_one(source_p, ":%s NOTICE %s :Mismatch on /die %s", + me.name, source_p->name, me.name); + return; + } + + snprintf(buf, sizeof(buf), "received DIE command from %s", + get_oper_name(source_p)); + server_die(buf, 0); +} + +static struct Message die_msgtab = { + "DIE", 0, 0, 1, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_die, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&die_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&die_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_CORE +}; diff --git a/modules/core/m_error.c b/modules/core/m_error.c new file mode 100644 index 0000000..9228628 --- /dev/null +++ b/modules/core/m_error.c @@ -0,0 +1,116 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_error.c: Handles error messages from the other end. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "send.h" +#include "modules.h" +#include "log.h" +#include "parse.h" + + +/* + * Note: At least at protocol level ERROR has only one parameter. + * --msa + * + * parv[0] = sender prefix + * parv[*] = parameters + */ +static void +m_error(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *para; + + para = (parc > 1 && *parv[1] != '\0') ? parv[1] : "<>"; + + ilog(LOG_TYPE_IRCD, "Received ERROR message from %s: %s", + source_p->name, para); + + if (client_p == source_p) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, "ERROR :from %s -- %s", + get_client_name(client_p, HIDE_IP), para); + sendto_realops_flags(UMODE_ALL, L_OPER, "ERROR :from %s -- %s", + get_client_name(client_p, MASK_IP), para); + } + else + { + sendto_realops_flags(UMODE_ALL, L_OPER, "ERROR :from %s via %s -- %s", + source_p->name, get_client_name(client_p, MASK_IP), para); + sendto_realops_flags(UMODE_ALL, L_ADMIN, "ERROR :from %s via %s -- %s", + source_p->name, get_client_name(client_p, HIDE_IP), para); + } + + if (MyClient(source_p)) + exit_client(source_p, source_p, "ERROR"); +} + +static void +ms_error(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *para; + + para = (parc > 1 && *parv[1] != '\0') ? parv[1] : "<>"; + + ilog(LOG_TYPE_IRCD, "Received ERROR message from %s: %s", + source_p->name, para); + + if (client_p == source_p) + sendto_realops_flags(UMODE_ALL, L_ALL, "ERROR :from %s -- %s", + get_client_name(client_p, MASK_IP), para); + else + sendto_realops_flags(UMODE_ALL, L_ALL, "ERROR :from %s via %s -- %s", + source_p->name, + get_client_name(client_p, MASK_IP), para); +} + +static struct Message error_msgtab = { + "ERROR", 0, 0, 1, MAXPARA, MFLG_SLOW, 0, + { m_error, m_ignore, ms_error, m_ignore, m_ignore, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&error_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&error_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_CORE +}; diff --git a/modules/core/m_join.c b/modules/core/m_join.c new file mode 100644 index 0000000..35bbf3a --- /dev/null +++ b/modules/core/m_join.c @@ -0,0 +1,680 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_join.c: Joins a channel. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "s_serv.h" +#include "conf.h" +#include "parse.h" +#include "modules.h" + + +static void do_join_0(struct Client *, struct Client *); + +static void set_final_mode(struct Mode *, struct Mode *); +static void remove_our_modes(struct Channel *, struct Client *); +static void remove_a_mode(struct Channel *, struct Client *, int, char); + +static char modebuf[MODEBUFLEN]; +static char parabuf[MODEBUFLEN]; +static char sendbuf[MODEBUFLEN]; +static char *mbuf; + +/* last0() stolen from ircu */ +static char * +last0(struct Client *client_p, struct Client *source_p, char *chanlist) +{ + char *p; + int join0 = 0; + + for (p = chanlist; *p; ++p) /* find last "JOIN 0" */ + { + if (*p == '0' && (*(p + 1) == ',' || *(p + 1) == '\0')) + { + if ((*p + 1) == ',') + ++p; + + chanlist = p + 1; + join0 = 1; + } + else + { + while (*p != ',' && *p != '\0') /* skip past channel name */ + ++p; + + if (*p == '\0') /* hit the end */ + break; + } + } + + if (join0) + do_join_0(client_p, source_p); + + return chanlist; +} + +/* m_join() + * parv[0] = sender prefix + * parv[1] = channel + * parv[2] = channel password (key) + */ +static void +m_join(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *p = NULL; + char *key_list = NULL; + char *chan_list = NULL; + char *chan = NULL; + struct Channel *chptr = NULL; + int i = 0; + unsigned int flags = 0; + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "JOIN"); + return; + } + + assert(client_p == source_p); + + key_list = parv[2]; + chan_list = last0(client_p, source_p, parv[1]); + + for (chan = strtoken(&p, chan_list, ","); chan; + chan = strtoken(&p, NULL, ",")) + { + char *key = NULL; + + /* If we have any more keys, take the first for this channel. */ + if (!EmptyString(key_list) && (key_list = strchr(key = key_list, ','))) + *key_list++ = '\0'; + + /* Empty keys are the same as no keys. */ + if (key && *key == '\0') + key = NULL; + + if (!check_channel_name(chan, 1)) + { + sendto_one(source_p, form_str(ERR_BADCHANNAME), + me.name, source_p->name, chan); + continue; + } + + if (!IsExemptResv(source_p) && + !(HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.oper_pass_resv) && + (!hash_find_resv(chan) == ConfigChannel.restrict_channels)) + { + sendto_one(source_p, form_str(ERR_BADCHANNAME), + me.name, source_p->name, chan); + sendto_realops_flags(UMODE_SPY, L_ALL, + "Forbidding reserved channel [%s] from user %s", + chan, get_client_name(source_p, HIDE_IP)); + continue; + } + + if (dlink_list_length(&source_p->channel) >= + (HasUMode(source_p, UMODE_OPER) ? + ConfigChannel.max_chans_per_oper : + ConfigChannel.max_chans_per_user)) + { + sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS), + me.name, source_p->name, chan); + break; + } + + if ((chptr = hash_find_channel(chan)) != NULL) + { + if (IsMember(source_p, chptr)) + continue; + + if (splitmode && !HasUMode(source_p, UMODE_OPER) && + ConfigChannel.no_join_on_split) + { + sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE), + me.name, source_p->name, chan); + continue; + } + + /* + * can_join checks for +i key, bans. + */ + if ((i = can_join(source_p, chptr, key))) + { + sendto_one(source_p, form_str(i), me.name, + source_p->name, chptr->chname); + continue; + } + + /* + * This should never be the case unless there is some sort of + * persistant channels. + */ + if (dlink_list_length(&chptr->members) == 0) + flags = CHFL_CHANOP; + else + flags = 0; + } + else + { + if (splitmode && !HasUMode(source_p, UMODE_OPER) && + (ConfigChannel.no_create_on_split || ConfigChannel.no_join_on_split)) + { + sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE), + me.name, source_p->name, chan); + continue; + } + + flags = CHFL_CHANOP; + chptr = make_channel(chan); + } + + if (!HasUMode(source_p, UMODE_OPER)) + check_spambot_warning(source_p, chptr->chname); + + add_user_to_channel(chptr, source_p, flags, 1); + + /* + * Set timestamp if appropriate, and propagate + */ + if (flags & CHFL_CHANOP) + { + chptr->channelts = CurrentTime; + chptr->mode.mode |= MODE_TOPICLIMIT; + chptr->mode.mode |= MODE_NOPRIVMSGS; + + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s SJOIN %lu %s +nt :@%s", + me.id, (unsigned long)chptr->channelts, + chptr->chname, source_p->id); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s SJOIN %lu %s +nt :@%s", + me.name, (unsigned long)chptr->channelts, + chptr->chname, source_p->name); + /* + * notify all other users on the new channel + */ + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN :%s", + source_p->name, source_p->username, + source_p->host, chptr->chname); + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s +nt", + me.name, chptr->chname); + } + else + { + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s JOIN %lu %s +", + source_p->id, (unsigned long)chptr->channelts, + chptr->chname); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s SJOIN %lu %s + :%s", + me.name, (unsigned long)chptr->channelts, + chptr->chname, source_p->name); + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN :%s", + source_p->name, source_p->username, + source_p->host, chptr->chname); + } + + del_invite(chptr, source_p); + + if (chptr->topic[0]) + { + sendto_one(source_p, form_str(RPL_TOPIC), me.name, + source_p->name, chptr->chname, chptr->topic); + + sendto_one(source_p, form_str(RPL_TOPICWHOTIME), + me.name, source_p->name, chptr->chname, + chptr->topic_info, chptr->topic_time); + } + + channel_member_names(source_p, chptr, 1); + + source_p->localClient->last_join_time = CurrentTime; + } +} + +/* ms_join() + * + * inputs - parv[0] = uid + * parv[1] = ts + * parv[2] = channel name + * parv[3] = modes (Deprecated) + * output - none + * side effects - handles remote JOIN's sent by servers. In TSora + * remote clients are joined using SJOIN, hence a + * JOIN sent by a server on behalf of a client is an error. + * here, the initial code is in to take an extra parameter + * and use it for the TimeStamp on a new channel. + */ +static void +ms_join(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + time_t newts = 0; + time_t oldts = 0; + int keep_our_modes = 1; + int keep_new_modes = 1; + int isnew = 0; + const char *servername = NULL; + struct Channel *chptr = NULL; + struct Mode mode, *oldmode; + + if (parc == 2 && !irccmp(parv[1], "0")) + { + do_join_0(client_p, source_p); + return; + } + + if (parc < 4) + return; + + if (!check_channel_name(parv[2], 0)) + { + sendto_realops_flags(UMODE_DEBUG, L_ALL, + "*** Too long or invalid channel name from %s: %s", + client_p->name, parv[2]); + return; + } + + mbuf = modebuf; + mode.mode = mode.limit = 0; + mode.key[0] = '\0'; + + if ((chptr = hash_find_channel(parv[2])) == NULL) + { + isnew = 1; + chptr = make_channel(parv[2]); + } + + newts = atol(parv[1]); + oldts = chptr->channelts; + oldmode = &chptr->mode; + + if (ConfigFileEntry.ignore_bogus_ts) + { + if (newts < 800000000) + { + sendto_realops_flags(UMODE_DEBUG, L_ALL, + "*** Bogus TS %lu on %s ignored from %s", + (unsigned long)newts, chptr->chname, + client_p->name); + + newts = (oldts == 0) ? 0 : 800000000; + } + } + else + { + if (!newts && !isnew && oldts) + { + sendto_channel_local(ALL_MEMBERS, 0, chptr, + ":%s NOTICE %s :*** Notice -- TS for %s changed from %lu to 0", + me.name, chptr->chname, chptr->chname, (unsigned long)oldts); + sendto_realops_flags(UMODE_ALL, L_ALL, + "Server %s changing TS on %s from %lu to 0", + source_p->name, chptr->chname, (unsigned long)oldts); + } + } + + if (isnew) + chptr->channelts = newts; + else if (newts == 0 || oldts == 0) + chptr->channelts = 0; + else if (newts == oldts) + ; + else if (newts < oldts) + { + keep_our_modes = 0; + chptr->channelts = newts; + } + else + keep_new_modes = 0; + + if (!keep_new_modes) + mode = *oldmode; + else if (keep_our_modes) + { + mode.mode |= oldmode->mode; + if (oldmode->limit > mode.limit) + mode.limit = oldmode->limit; + if (strcmp(mode.key, oldmode->key) < 0) + strcpy(mode.key, oldmode->key); + } + + set_final_mode(&mode, oldmode); + chptr->mode = mode; + + /* Lost the TS, other side wins, so remove modes on this side */ + if (!keep_our_modes) + { + remove_our_modes(chptr, source_p); + + if (chptr->topic[0]) + { + set_channel_topic(chptr, "", "", 0); + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s TOPIC %s :", + (IsHidden(source_p) || + ConfigServerHide.hide_servers) ? + me.name : source_p->name, chptr->chname); + } + + sendto_channel_local(ALL_MEMBERS, 0, chptr, + ":%s NOTICE %s :*** Notice -- TS for %s changed from %lu to %lu", + me.name, chptr->chname, chptr->chname, + (unsigned long)oldts, (unsigned long)newts); + } + + if (*modebuf != '\0') + { + servername = (ConfigServerHide.hide_servers || IsHidden(source_p)) ? + me.name : source_p->name; + + /* This _SHOULD_ be to ALL_MEMBERS + * It contains only +imnpstlk, etc */ + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s %s %s", + servername, chptr->chname, modebuf, parabuf); + } + + if (!IsMember(source_p, chptr)) + { + add_user_to_channel(chptr, source_p, 0, 1); + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN :%s", + source_p->name, source_p->username, + source_p->host, chptr->chname); + } + + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s JOIN %lu %s +", + ID(source_p), (unsigned long)chptr->channelts, chptr->chname); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s SJOIN %lu %s + :%s", + source_p->servptr->name, (unsigned long)chptr->channelts, + chptr->chname, source_p->name); +} + +/* do_join_0() + * + * inputs - pointer to client doing join 0 + * output - NONE + * side effects - Use has decided to join 0. This is legacy + * from the days when channels were numbers not names. *sigh* + * There is a bunch of evilness necessary here due to + * anti spambot code. + */ +static void +do_join_0(struct Client *client_p, struct Client *source_p) +{ + struct Channel *chptr = NULL; + dlink_node *ptr = NULL, *ptr_next = NULL; + + if (source_p->channel.head) + if (MyConnect(source_p) && !HasUMode(source_p, UMODE_OPER)) + check_spambot_warning(source_p, NULL); + + DLINK_FOREACH_SAFE(ptr, ptr_next, source_p->channel.head) + { + chptr = ((struct Membership *)ptr->data)->chptr; + + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s PART %s", ID(source_p), chptr->chname); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s PART %s", source_p->name, chptr->chname); + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s PART %s", + source_p->name, source_p->username, + source_p->host, chptr->chname); + + remove_user_from_channel(ptr->data); + } +} + +/* set_final_mode + * + * inputs - channel mode + * - old channel mode + * output - NONE + * side effects - walk through all the channel modes turning off modes + * that were on in oldmode but aren't on in mode. + * Then walk through turning on modes that are on in mode + * but were not set in oldmode. + */ +static void +set_final_mode(struct Mode *mode, struct Mode *oldmode) +{ + const struct mode_letter *tab; + char *pbuf = parabuf; + int what = 0; + int len; + + for (tab = chan_modes; tab->letter; ++tab) + { + if ((tab->mode & mode->mode) && + !(tab->mode & oldmode->mode)) + { + if (what != 1) + { + *mbuf++ = '+'; + what = 1; + } + *mbuf++ = tab->letter; + } + } + + for (tab = chan_modes; tab->letter; ++tab) + { + if ((tab->mode & oldmode->mode) && + !(tab->mode & mode->mode)) + { + if (what != -1) + { + *mbuf++ = '-'; + what = -1; + } + *mbuf++ = tab->letter; + } + } + + if (oldmode->limit != 0 && mode->limit == 0) + { + if (what != -1) + { + *mbuf++ = '-'; + what = -1; + } + *mbuf++ = 'l'; + } + + if (oldmode->key[0] && !mode->key[0]) + { + if (what != -1) + { + *mbuf++ = '-'; + what = -1; + } + *mbuf++ = 'k'; + len = ircsprintf(pbuf, "%s ", oldmode->key); + pbuf += len; + } + + if (mode->limit != 0 && oldmode->limit != mode->limit) + { + if (what != 1) + { + *mbuf++ = '+'; + what = 1; + } + *mbuf++ = 'l'; + len = ircsprintf(pbuf, "%d ", mode->limit); + pbuf += len; + } + + if (mode->key[0] && strcmp(oldmode->key, mode->key)) + { + if (what != 1) + { + *mbuf++ = '+'; + what = 1; + } + *mbuf++ = 'k'; + len = ircsprintf(pbuf, "%s ", mode->key); + pbuf += len; + } + *mbuf = '\0'; +} + +/* remove_our_modes() + * + * inputs - pointer to channel to remove modes from + * - client pointer + * output - NONE + * side effects - Go through the local members, remove all their + * chanop modes etc., this side lost the TS. + */ +static void +remove_our_modes(struct Channel *chptr, struct Client *source_p) +{ + remove_a_mode(chptr, source_p, CHFL_CHANOP, 'o'); +#ifdef HALFOPS + remove_a_mode(chptr, source_p, CHFL_HALFOP, 'h'); +#endif + remove_a_mode(chptr, source_p, CHFL_VOICE, 'v'); +} + +/* remove_a_mode() + * + * inputs - + * output - NONE + * side effects - remove ONE mode from a channel + */ +static void +remove_a_mode(struct Channel *chptr, struct Client *source_p, + int mask, char flag) +{ + dlink_node *ptr; + struct Membership *ms; + char lmodebuf[MODEBUFLEN]; + const char *lpara[MAXMODEPARAMS]; + int count = 0; + int lcount; + + mbuf = lmodebuf; + *mbuf++ = '-'; + + for (lcount = 0; lcount < MAXMODEPARAMS; lcount++) + lpara[lcount] = ""; + sendbuf[0] = '\0'; + + DLINK_FOREACH(ptr, chptr->members.head) + { + ms = ptr->data; + + if ((ms->flags & mask) == 0) + continue; + + ms->flags &= ~mask; + + lpara[count++] = ms->client_p->name; + + *mbuf++ = flag; + + if (count >= MAXMODEPARAMS) + { + for (lcount = 0; lcount < MAXMODEPARAMS; lcount++) + { + if (*lpara[lcount] == '\0') + break; + + strlcat(sendbuf, " ", sizeof(sendbuf)); + strlcat(sendbuf, lpara[lcount], sizeof(sendbuf)); + lpara[lcount] = ""; + } + + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, 0, chptr, + ":%s MODE %s %s%s", + (IsHidden(source_p) || + ConfigServerHide.hide_servers) ? + me.name : source_p->name, + chptr->chname, lmodebuf, sendbuf); + mbuf = lmodebuf; + *mbuf++ = '-'; + count = 0; + sendbuf[0] = '\0'; + } + } + + if (count != 0) + { + *mbuf = '\0'; + for (lcount = 0; lcount < MAXMODEPARAMS; lcount++) + { + if (*lpara[lcount] == '\0') + break; + + strlcat(sendbuf, " ", sizeof(sendbuf)); + strlcat(sendbuf, lpara[lcount], sizeof(sendbuf)); + } + sendto_channel_local(ALL_MEMBERS, 0, chptr, + ":%s MODE %s %s%s", + (IsHidden(source_p) || ConfigServerHide.hide_servers) ? + me.name : source_p->name, + chptr->chname, lmodebuf, sendbuf); + } +} + +static struct Message join_msgtab = { + "JOIN", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_join, ms_join, m_ignore, m_join, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&join_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&join_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_CORE +}; diff --git a/modules/core/m_kick.c b/modules/core/m_kick.c new file mode 100644 index 0000000..f800136 --- /dev/null +++ b/modules/core/m_kick.c @@ -0,0 +1,241 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_kick.c: Kicks a user from a channel. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "modules.h" +#include "parse.h" +#include "hash.h" +#include "packet.h" +#include "s_serv.h" + + +/* m_kick() + * parv[0] = sender prefix + * parv[1] = channel + * parv[2] = client to kick + * parv[3] = kick comment + */ +static void +m_kick(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *who; + struct Channel *chptr; + int chasing = 0; + char *comment; + char *name; + char *p = NULL; + char *user; + const char *from, *to; + struct Membership *ms = NULL; + struct Membership *ms_target; + + if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p)) + { + from = me.id; + to = source_p->id; + } + else + { + from = me.name; + to = source_p->name; + } + + if (EmptyString(parv[2])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + from, to, "KICK"); + return; + } + + if (MyClient(source_p) && !IsFloodDone(source_p)) + flood_endgrace(source_p); + + comment = (EmptyString(parv[3])) ? parv[2] : parv[3]; + if (strlen(comment) > (size_t)KICKLEN) + comment[KICKLEN] = '\0'; + + name = parv[1]; + while (*name == ',') + name++; + + if ((p = strchr(name,',')) != NULL) + *p = '\0'; + if (*name == '\0') + return; + + if ((chptr = hash_find_channel(name)) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + from, to, name); + return; + } + + if (!IsServer(source_p) && !HasFlag(source_p, FLAGS_SERVICE)) + { + if ((ms = find_channel_link(source_p, chptr)) == NULL) + { + if (MyConnect(source_p)) + { + sendto_one(source_p, form_str(ERR_NOTONCHANNEL), + me.name, source_p->name, name); + return; + } + } + + if (!has_member_flags(ms, CHFL_CHANOP|CHFL_HALFOP)) + { + /* was a user, not a server, and user isn't seen as a chanop here */ + if (MyConnect(source_p)) + { + /* user on _my_ server, with no chanops.. so go away */ + sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), + me.name, source_p->name, name); + return; + } + + if (chptr->channelts == 0) + { + /* If its a TS 0 channel, do it the old way */ + sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), + from, to, name); + return; + } + + /* Its a user doing a kick, but is not showing as chanop locally + * its also not a user ON -my- server, and the channel has a TS. + * There are two cases we can get to this point then... + * + * 1) connect burst is happening, and for some reason a legit + * op has sent a KICK, but the SJOIN hasn't happened yet or + * been seen. (who knows.. due to lag...) + * + * 2) The channel is desynced. That can STILL happen with TS + * + * Now, the old code roger wrote, would allow the KICK to + * go through. Thats quite legit, but lets weird things like + * KICKS by users who appear not to be chanopped happen, + * or even neater, they appear not to be on the channel. + * This fits every definition of a desync, doesn't it? ;-) + * So I will allow the KICK, otherwise, things are MUCH worse. + * But I will warn it as a possible desync. + * + * -Dianora + */ + } + } + + user = parv[2]; + + while (*user == ',') + user++; + + if ((p = strchr(user, ',')) != NULL) + *p = '\0'; + + if (*user == '\0') + return; + + if ((who = find_chasing(client_p, source_p, user, &chasing)) == NULL) + return; + + if ((ms_target = find_channel_link(who, chptr)) != NULL) + { +#ifdef HALFOPS + /* half ops cannot kick other halfops on private channels */ + if (has_member_flags(ms, CHFL_HALFOP) && !has_member_flags(ms, CHFL_CHANOP)) + { + if (((chptr->mode.mode & MODE_PRIVATE) && has_member_flags(ms_target, + CHFL_CHANOP|CHFL_HALFOP)) || has_member_flags(ms_target, CHFL_CHANOP)) + { + sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), + me.name, source_p->name, name); + return; + } + } +#endif + + /* jdc + * - In the case of a server kicking a user (i.e. CLEARCHAN), + * the kick should show up as coming from the server which did + * the kick. + * - Personally, flame and I believe that server kicks shouldn't + * be sent anyways. Just waiting for some oper to abuse it... + */ + if (IsServer(source_p)) + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s KICK %s %s :%s", + source_p->name, name, who->name, comment); + else + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s KICK %s %s :%s", + source_p->name, source_p->username, + source_p->host, name, who->name, comment); + + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s KICK %s %s :%s", + ID(source_p), chptr->chname, ID(who), comment); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s KICK %s %s :%s", source_p->name, chptr->chname, + who->name, comment); + + remove_user_from_channel(ms_target); + } + else + sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL), + from, to, user, name); +} + +static struct Message kick_msgtab = { + "KICK", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_kick, m_kick, m_ignore, m_kick, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&kick_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&kick_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_CORE +}; diff --git a/modules/core/m_kill.c b/modules/core/m_kill.c new file mode 100644 index 0000000..a76e5a4 --- /dev/null +++ b/modules/core/m_kill.c @@ -0,0 +1,331 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_kill.c: Kills a user. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "hash.h" /* for find_client() */ +#include "ircd.h" +#include "numeric.h" +#include "log.h" +#include "s_serv.h" +#include "conf.h" +#include "send.h" +#include "whowas.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "parse.h" +#include "modules.h" + + +static char buf[IRCD_BUFSIZE]; + +static void +relay_kill(struct Client *one, struct Client *source_p, + struct Client *target_p, const char *inpath, + const char *reason) +{ + dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, serv_list.head) + { + struct Client *client_p = ptr->data; + + if (client_p == one) + continue; + + if (MyClient(source_p)) + sendto_one(client_p, ":%s KILL %s :%s!%s!%s!%s (%s)", + ID_or_name(source_p, client_p), + ID_or_name(target_p, client_p), + me.name, source_p->host, source_p->username, + source_p->name, reason); + else + sendto_one(client_p, ":%s KILL %s :%s %s", + ID_or_name(source_p, client_p), + ID_or_name(target_p, client_p), inpath, reason); + } +} + +/* mo_kill() + * parv[0] = sender prefix + * parv[1] = kill victim + * parv[2] = kill path + */ +static void +mo_kill(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p; + const char *inpath = client_p->name; + char *user; + char *reason; + char def_reason[] = "No reason"; + + user = parv[1]; + reason = parv[2]; /* Either defined or NULL (parc >= 2!!) */ + + if (*user == '\0') + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "KILL"); + return; + } + + if (!HasOFlag(source_p, OPER_FLAG_GLOBAL_KILL|OPER_FLAG_K)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + + if (!EmptyString(reason)) + { + if (strlen(reason) > (size_t)KILLLEN) + reason[KILLLEN] = '\0'; + } + else + reason = def_reason; + + if ((target_p = hash_find_client(user)) == NULL) + { + /* + * If the user has recently changed nick, automatically + * rewrite the KILL for this new nickname--this keeps + * servers in synch when nick change and kill collide + */ + if ((target_p = get_history(user, + (time_t)ConfigFileEntry.kill_chase_time_limit)) + == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, user); + return; + } + + sendto_one(source_p, ":%s NOTICE %s :KILL changed from %s to %s", + me.name, source_p->name, user, target_p->name); + } + + if (IsServer(target_p) || IsMe(target_p)) + { + sendto_one(source_p, form_str(ERR_CANTKILLSERVER), + me.name, source_p->name); + return; + } + + if (!MyConnect(target_p) && !HasOFlag(source_p, OPER_FLAG_GLOBAL_KILL)) + { + sendto_one(source_p, ":%s NOTICE %s :Nick %s isnt on your server", + me.name, source_p->name, target_p->name); + return; + } + + if (MyConnect(target_p)) + sendto_one(target_p, ":%s!%s@%s KILL %s :%s", + source_p->name, source_p->username, source_p->host, + target_p->name, reason); + + /* + * Do not change the format of this message. There's no point in changing messages + * that have been around for ever, for no reason.. + */ + sendto_realops_flags(UMODE_ALL, L_ALL, + "Received KILL message for %s. From %s Path: %s (%s)", + target_p->name, source_p->name, me.name, reason); + + ilog(LOG_TYPE_KILL, "KILL From %s For %s Path %s (%s)", + source_p->name, target_p->name, me.name, reason); + + /* + * And pass on the message to other servers. Note, that if KILL + * was changed, the message has to be sent to all links, also + * back. + * Suicide kills are NOT passed on --SRB + */ + if (!MyConnect(target_p)) + { + relay_kill(client_p, source_p, target_p, inpath, reason); + /* + * Set FLAGS_KILLED. This prevents exit_one_client from sending + * the unnecessary QUIT for this. (This flag should never be + * set in any other place) + */ + AddFlag(target_p, FLAGS_KILLED); + } + + snprintf(buf, sizeof(buf), "Killed (%s (%s))", source_p->name, reason); + exit_client(target_p, source_p, buf); +} + +/* ms_kill() + * parv[0] = sender prefix + * parv[1] = kill victim + * parv[2] = kill path and reason + */ +static void +ms_kill(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p; + char *user; + char *reason; + const char *path; + char def_reason[] = "No reason"; + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "KILL"); + return; + } + + user = parv[1]; + + if (EmptyString(parv[2])) + { + reason = def_reason; + + /* hyb6 takes the nick of the killer from the path *sigh* --fl_ */ + path = source_p->name; + } + else + { + reason = strchr(parv[2], ' '); + + if (reason != NULL) + *reason++ = '\0'; + else + reason = def_reason; + + path = parv[2]; + } + + if ((target_p = find_person(client_p, user)) == NULL) + { + /* + * If the user has recently changed nick, but only if its + * not an uid, automatically rewrite the KILL for this new nickname. + * --this keeps servers in synch when nick change and kill collide + */ + if (IsDigit(*user)) /* Somehow an uid was not found in the hash ! */ + return; + if ((target_p = get_history(user, + (time_t)ConfigFileEntry.kill_chase_time_limit)) + == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, user); + return; + } + + sendto_one(source_p,":%s NOTICE %s :KILL changed from %s to %s", + me.name, source_p->name, user, target_p->name); + } + + if (IsServer(target_p) || IsMe(target_p)) + { + sendto_one(source_p, form_str(ERR_CANTKILLSERVER), + me.name, source_p->name); + return; + } + + if (MyConnect(target_p)) + { + if (IsServer(source_p)) + { + /* dont send clients kills from a hidden server */ + if ((IsHidden(source_p) || ConfigServerHide.hide_servers) && !HasUMode(target_p, UMODE_OPER)) + sendto_one(target_p, ":%s KILL %s :%s", + me.name, target_p->name, reason); + else + sendto_one(target_p, ":%s KILL %s :%s", + source_p->name, target_p->name, reason); + } + else + sendto_one(target_p, ":%s!%s@%s KILL %s :%s", + source_p->name, source_p->username, source_p->host, + target_p->name, reason); + } + + /* + * Be warned, this message must be From %s, or it confuses clients + * so dont change it to From: or the case or anything! -- fl -- db + */ + /* + * path must contain at least 2 !'s, or bitchx falsely declares it + * local --fl + */ + if (HasUMode(source_p, UMODE_OPER)) /* send it normally */ + sendto_realops_flags(UMODE_ALL, L_ALL, + "Received KILL message for %s. From %s Path: %s!%s!%s!%s %s", + target_p->name, source_p->name, source_p->servptr->name, + source_p->host, source_p->username, source_p->name, reason); + else + sendto_realops_flags(UMODE_SKILL, L_ALL, + "Received KILL message for %s. From %s %s", + target_p->name, source_p->name, reason); + + ilog(LOG_TYPE_KILL, "KILL From %s For %s Path %s %s", + source_p->name, target_p->name, source_p->name, reason); + + relay_kill(client_p, source_p, target_p, path, reason); + AddFlag(target_p, FLAGS_KILLED); + + /* reason comes supplied with its own ()'s */ + if (IsServer(source_p) && (IsHidden(source_p) || ConfigServerHide.hide_servers)) + snprintf(buf, sizeof(buf), "Killed (%s %s)", me.name, reason); + else + snprintf(buf, sizeof(buf), "Killed (%s %s)", source_p->name, reason); + + exit_client(target_p, source_p, buf); +} + + +static struct Message kill_msgtab = { + "KILL", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, ms_kill, m_ignore, mo_kill, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&kill_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&kill_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_CORE +}; diff --git a/modules/core/m_message.c b/modules/core/m_message.c new file mode 100644 index 0000000..183154f --- /dev/null +++ b/modules/core/m_message.c @@ -0,0 +1,935 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_message.c: Sends a (PRIVMSG|NOTICE) message to a user or channel. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "conf.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "channel.h" +#include "channel_mode.h" +#include "irc_string.h" +#include "hash.h" +#include "packet.h" + + +struct entity +{ + void *ptr; + int type; + int flags; +}; + +static int build_target_list(int p_or_n, const char *command, + struct Client *client_p, + struct Client *source_p, + char *nicks_channels, char *text); + +static int flood_attack_client(int p_or_n, struct Client *source_p, + struct Client *target_p); +static int flood_attack_channel(int p_or_n, struct Client *source_p, + struct Channel *chptr); +static struct Client* find_userhost (char *, char *, int *); + +#define ENTITY_NONE 0 +#define ENTITY_CHANNEL 1 +#define ENTITY_CHANOPS_ON_CHANNEL 2 +#define ENTITY_CLIENT 3 + +static struct entity targets[512]; +static int ntargets = 0; + +static int duplicate_ptr(void *); + +static void m_message(int, const char *, struct Client *, + struct Client *, int, char **); + +static void msg_channel(int p_or_n, const char *command, + struct Client *client_p, + struct Client *source_p, + struct Channel *chptr, char *text); + +static void msg_channel_flags(int p_or_n, const char *command, + struct Client *client_p, + struct Client *source_p, + struct Channel *chptr, int flags, char *text); + +static void msg_client(int p_or_n, const char *command, + struct Client *source_p, struct Client *target_p, + char *text); + +static void handle_special(int p_or_n, const char *command, + struct Client *client_p, + struct Client *source_p, char *nick, char *text); + +/* +** m_privmsg +** +** massive cleanup +** rev argv 6/91 +** +** Another massive cleanup Nov, 2000 +** (I don't think there is a single line left from 6/91. Maybe.) +** m_privmsg and m_notice do basically the same thing. +** in the original 2.8.2 code base, they were the same function +** "m_message.c." When we did the great cleanup in conjuncton with bleep +** of ircu fame, we split m_privmsg.c and m_notice.c. +** I don't see the point of that now. Its harder to maintain, its +** easier to introduce bugs into one version and not the other etc. +** Really, the penalty of an extra function call isn't that big a deal folks. +** -db Nov 13, 2000 +** +*/ + +#define PRIVMSG 0 +#define NOTICE 1 + +static void +m_privmsg(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + /* servers have no reason to send privmsgs, yet sometimes there is cause + * for a notice.. (for example remote kline replies) --fl_ + */ + if (!IsClient(source_p)) + return; + + m_message(PRIVMSG, "PRIVMSG", client_p, source_p, parc, parv); +} + +static void +m_notice(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + m_message(NOTICE, "NOTICE", client_p, source_p, parc, parv); +} + +/* + * inputs - flag privmsg or notice + * - pointer to command "PRIVMSG" or "NOTICE" + * - pointer to client_p + * - pointer to source_p + * - pointer to channel + */ +static void +m_message(int p_or_n, const char *command, struct Client *client_p, + struct Client *source_p, int parc, char *parv[]) +{ + int i; + + if (parc < 2 || EmptyString(parv[1])) + { + if (p_or_n != NOTICE) + sendto_one(source_p, form_str(ERR_NORECIPIENT), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), command); + return; + } + + if (parc < 3 || EmptyString(parv[2])) + { + if (p_or_n != NOTICE) + sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p)); + return; + } + + /* Finish the flood grace period... */ + if (MyClient(source_p) && !IsFloodDone(source_p)) + flood_endgrace(source_p); + + if (build_target_list(p_or_n, command, client_p, source_p, parv[1], + parv[2]) < 0) + return; + + for (i = 0; i < ntargets; i++) + { + switch (targets[i].type) + { + case ENTITY_CHANNEL: + msg_channel(p_or_n, command, client_p, source_p, + (struct Channel *)targets[i].ptr, parv[2]); + break; + + case ENTITY_CHANOPS_ON_CHANNEL: + msg_channel_flags(p_or_n, command, client_p, source_p, + (struct Channel *)targets[i].ptr, + targets[i].flags, parv[2]); + break; + + case ENTITY_CLIENT: + msg_client(p_or_n, command, source_p, + (struct Client *)targets[i].ptr, parv[2]); + break; + } + } +} + +/* build_target_list() + * + * inputs - pointer to given client_p (server) + * - pointer to given source (oper/client etc.) + * - pointer to list of nicks/channels + * - pointer to table to place results + * - pointer to text (only used if source_p is an oper) + * output - number of valid entities + * side effects - target_table is modified to contain a list of + * pointers to channels or clients + * if source client is an oper + * all the classic old bizzare oper privmsg tricks + * are parsed and sent as is, if prefixed with $ + * to disambiguate. + * + */ +static int +build_target_list(int p_or_n, const char *command, struct Client *client_p, + struct Client *source_p, char *nicks_channels, char *text) +{ + int type; + char *p = NULL, *nick, *target_list; + struct Channel *chptr = NULL; + struct Client *target_p = NULL; + + target_list = nicks_channels; + + ntargets = 0; + + for (nick = strtoken(&p, target_list, ","); nick; + nick = strtoken(&p, NULL, ",")) + { + char *with_prefix; + /* + * channels are privmsg'd a lot more than other clients, moved up + * here plain old channel msg? + */ + + if (IsChanPrefix(*nick)) + { + if ((chptr = hash_find_channel(nick)) != NULL) + { + if (!duplicate_ptr(chptr)) + { + if (ntargets >= ConfigFileEntry.max_targets) + { + sendto_one(source_p, form_str(ERR_TOOMANYTARGETS), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), nick, + ConfigFileEntry.max_targets); + return (1); + } + targets[ntargets].ptr = (void *)chptr; + targets[ntargets++].type = ENTITY_CHANNEL; + } + } + else + { + if (p_or_n != NOTICE) + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), nick); + } + continue; + } + + /* look for a privmsg to another client */ + if ((target_p = find_person(client_p, nick)) != NULL) + { + if (!duplicate_ptr(target_p)) + { + if (ntargets >= ConfigFileEntry.max_targets) + { + sendto_one(source_p, form_str(ERR_TOOMANYTARGETS), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), nick, + ConfigFileEntry.max_targets); + return (1); + } + targets[ntargets].ptr = (void *)target_p; + targets[ntargets].type = ENTITY_CLIENT; + targets[ntargets++].flags = 0; + } + continue; + } + + /* @#channel or +#channel message ? */ + + type = 0; + with_prefix = nick; + /* allow %+@ if someone wants to do that */ + for (; ;) + { + if (*nick == '@') + type |= CHFL_CHANOP; +#ifdef HALFOPS + else if (*nick == '%') + type |= CHFL_CHANOP | CHFL_HALFOP; +#endif + else if (*nick == '+') + type |= CHFL_CHANOP | CHFL_HALFOP | CHFL_VOICE; + else + break; + nick++; + } + + if (type != 0) + { + /* suggested by Mortiis */ + if (*nick == '\0') /* if its a '\0' dump it, there is no recipient */ + { + sendto_one(source_p, form_str(ERR_NORECIPIENT), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), command); + continue; + } + + /* At this point, nick+1 should be a channel name i.e. #foo or &foo + * if the channel is found, fine, if not report an error + */ + + if ((chptr = hash_find_channel(nick)) != NULL) + { + if (IsClient(source_p) && !HasFlag(source_p, FLAGS_SERVICE)) + { + if (!has_member_flags(find_channel_link(source_p, chptr), + CHFL_CHANOP|CHFL_HALFOP|CHFL_VOICE)) + { + sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), with_prefix); + return(-1); + } + } + + if (!duplicate_ptr(chptr)) + { + if (ntargets >= ConfigFileEntry.max_targets) + { + sendto_one(source_p, form_str(ERR_TOOMANYTARGETS), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), nick, + ConfigFileEntry.max_targets); + return(1); + } + targets[ntargets].ptr = (void *)chptr; + targets[ntargets].type = ENTITY_CHANOPS_ON_CHANNEL; + targets[ntargets++].flags = type; + } + } + else + { + if (p_or_n != NOTICE) + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), nick); + } + continue; + } + + if ((*nick == '$') || strchr(nick, '@') != NULL) + { + handle_special(p_or_n, command, client_p, source_p, nick, text); + } + else + { + if (p_or_n != NOTICE) + { + if (!IsDigit(*nick) || MyClient(source_p)) + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), nick); + } + } + /* continue; */ + } + + return(1); +} + +/* duplicate_ptr() + * + * inputs - pointer to check + * - pointer to table of entities + * - number of valid entities so far + * output - YES if duplicate pointer in table, NO if not. + * note, this does the canonize using pointers + * side effects - NONE + */ +static int +duplicate_ptr(void *ptr) +{ + int i; + + for (i = 0; i < ntargets; i++) + { + if (targets[i].ptr == ptr) + return(1); + } + + return(0); +} + +/* msg_channel() + * + * inputs - flag privmsg or notice + * - pointer to command "PRIVMSG" or "NOTICE" + * - pointer to client_p + * - pointer to source_p + * - pointer to channel + * output - NONE + * side effects - message given channel + */ +static void +msg_channel(int p_or_n, const char *command, struct Client *client_p, + struct Client *source_p, struct Channel *chptr, char *text) +{ + int result; + + if (MyClient(source_p)) + { + /* idle time shouldnt be reset by notices --fl */ + if (p_or_n != NOTICE) + source_p->localClient->last_privmsg = CurrentTime; + } + + /* chanops and voiced can flood their own channel with impunity */ + if ((result = can_send(chptr, source_p, NULL)) < 0) + { + if (result == CAN_SEND_OPV || + !flood_attack_channel(p_or_n, source_p, chptr)) + sendto_channel_butone(client_p, source_p, chptr, 0, "%s %s :%s", + command, chptr->chname, text); + } + else + { + if (p_or_n != NOTICE) + sendto_one(source_p, form_str(ERR_CANNOTSENDTOCHAN), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), chptr->chname); + } +} + +/* msg_channel_flags() + * + * inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC + * say NOTICE must not auto reply + * - pointer to command, "PRIVMSG" or "NOTICE" + * - pointer to client_p + * - pointer to source_p + * - pointer to channel + * - flags + * - pointer to text to send + * output - NONE + * side effects - message given channel either chanop or voice + */ +static void +msg_channel_flags(int p_or_n, const char *command, struct Client *client_p, + struct Client *source_p, struct Channel *chptr, + int flags, char *text) +{ + unsigned int type; + char c; + + if (flags & CHFL_VOICE) + { + type = CHFL_VOICE|CHFL_HALFOP|CHFL_CHANOP; + c = '+'; + } +#ifdef HALFOPS + else if (flags & CHFL_HALFOP) + { + type = CHFL_HALFOP|CHFL_CHANOP; + c = '%'; + } +#endif + else + { + type = CHFL_CHANOP; + c = '@'; + } + + if (MyClient(source_p) && p_or_n != NOTICE) + source_p->localClient->last_privmsg = CurrentTime; + + sendto_channel_butone(client_p, source_p, chptr, type, "%s %c%s :%s", + command, c, chptr->chname, text); +} + +/* msg_client() + * + * inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC + * say NOTICE must not auto reply + * - pointer to command, "PRIVMSG" or "NOTICE" + * - pointer to source_p source (struct Client *) + * - pointer to target_p target (struct Client *) + * - pointer to text + * output - NONE + * side effects - message given channel either chanop or voice + */ +static void +msg_client(int p_or_n, const char *command, struct Client *source_p, + struct Client *target_p, char *text) +{ + if (MyConnect(source_p)) + { + /* + * reset idle time for message only if it's not a notice + */ + if ((p_or_n != NOTICE)) + source_p->localClient->last_privmsg = CurrentTime; + + if ((p_or_n != NOTICE) && target_p->away[0]) + sendto_one(source_p, form_str(RPL_AWAY), me.name, + source_p->name, target_p->name, target_p->away); + + if (HasUMode(target_p, UMODE_REGONLY) && target_p != source_p) + { + if (!HasUMode(source_p, UMODE_REGISTERED|UMODE_OPER)) + { + if (p_or_n != NOTICE) + sendto_one(source_p, form_str(ERR_NONONREG), me.name, source_p->name, + target_p->name); + return; + } + } + } + + if (MyClient(target_p)) + { + if (!IsServer(source_p) && HasUMode(target_p, UMODE_CALLERID|UMODE_SOFTCALLERID)) + { + /* Here is the anti-flood bot/spambot code -db */ + if (accept_message(source_p, target_p) || HasFlag(source_p, FLAGS_SERVICE) || + (HasUMode(source_p, UMODE_OPER) && (ConfigFileEntry.opers_bypass_callerid == 1))) + { + sendto_one(target_p, ":%s!%s@%s %s %s :%s", + source_p->name, source_p->username, + source_p->host, command, target_p->name, text); + } + else + { + /* check for accept, flag recipient incoming message */ + if (p_or_n != NOTICE) + sendto_one(source_p, form_str(RPL_TARGUMODEG), + ID_or_name(&me, source_p->from), + ID_or_name(source_p, source_p->from), target_p->name); + + if ((target_p->localClient->last_caller_id_time + + ConfigFileEntry.caller_id_wait) < CurrentTime) + { + if (p_or_n != NOTICE) + sendto_one(source_p, form_str(RPL_TARGNOTIFY), + ID_or_name(&me, source_p->from), + ID_or_name(source_p, source_p->from), target_p->name); + + sendto_one(target_p, form_str(RPL_UMODEGMSG), + me.name, target_p->name, + get_client_name(source_p, HIDE_IP)); + + target_p->localClient->last_caller_id_time = CurrentTime; + + } + /* Only so opers can watch for floods */ + flood_attack_client(p_or_n, source_p, target_p); + } + } + else + { + /* If the client is remote, we dont perform a special check for + * flooding.. as we wouldnt block their message anyway.. this means + * we dont give warnings.. we then check if theyre opered + * (to avoid flood warnings), lastly if theyre our client + * and flooding -- fl */ + if (!MyClient(source_p) || HasUMode(source_p, UMODE_OPER) || + (MyClient(source_p) && + !flood_attack_client(p_or_n, source_p, target_p))) + sendto_anywhere(target_p, source_p, "%s %s :%s", + command, target_p->name, text); + } + } + else + /* The target is a remote user.. same things apply -- fl */ + if (!MyClient(source_p) || HasUMode(source_p, UMODE_OPER) || + (MyClient(source_p) + && !flood_attack_client(p_or_n, source_p, target_p))) + sendto_anywhere(target_p, source_p, "%s %s :%s", command, target_p->name, + text); +} + +/* flood_attack_client() + * + * inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC + * say NOTICE must not auto reply + * - pointer to source Client + * - pointer to target Client + * output - 1 if target is under flood attack + * side effects - check for flood attack on target target_p + */ +static int +flood_attack_client(int p_or_n, struct Client *source_p, + struct Client *target_p) +{ + int delta; + + if (GlobalSetOptions.floodcount && MyConnect(target_p) + && IsClient(source_p) && !IsConfCanFlood(source_p)) + { + if ((target_p->localClient->first_received_message_time + 1) + < CurrentTime) + { + delta = + CurrentTime - target_p->localClient->first_received_message_time; + target_p->localClient->received_number_of_privmsgs -= delta; + target_p->localClient->first_received_message_time = CurrentTime; + + if (target_p->localClient->received_number_of_privmsgs <= 0) + { + target_p->localClient->received_number_of_privmsgs = 0; + DelFlag(target_p, FLAGS_FLOOD_NOTICED); + } + } + + if ((target_p->localClient->received_number_of_privmsgs >= + GlobalSetOptions.floodcount) || HasFlag(target_p, FLAGS_FLOOD_NOTICED)) + { + if (!HasFlag(target_p, FLAGS_FLOOD_NOTICED)) + { + sendto_realops_flags(UMODE_BOTS, L_ALL, + "Possible Flooder %s on %s target: %s", + get_client_name(source_p, HIDE_IP), + source_p->servptr->name, target_p->name); + AddFlag(target_p, FLAGS_FLOOD_NOTICED); + /* add a bit of penalty */ + target_p->localClient->received_number_of_privmsgs += 2; + } + + if (MyClient(source_p) && (p_or_n != NOTICE)) + sendto_one(source_p, + ":%s NOTICE %s :*** Message to %s throttled due to flooding", + me.name, source_p->name, target_p->name); + return(1); + } + else + target_p->localClient->received_number_of_privmsgs++; + } + + return(0); +} + +/* flood_attack_channel() + * + * inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC + * says NOTICE must not auto reply + * - pointer to source Client + * - pointer to target channel + * output - 1 if target is under flood attack + * side effects - check for flood attack on target chptr + */ +static int +flood_attack_channel(int p_or_n, struct Client *source_p, + struct Channel *chptr) +{ + int delta; + + if (GlobalSetOptions.floodcount && !IsConfCanFlood(source_p)) + { + if ((chptr->first_received_message_time + 1) < CurrentTime) + { + delta = CurrentTime - chptr->first_received_message_time; + chptr->received_number_of_privmsgs -= delta; + chptr->first_received_message_time = CurrentTime; + if (chptr->received_number_of_privmsgs <= 0) + { + chptr->received_number_of_privmsgs = 0; + ClearFloodNoticed(chptr); + } + } + + if ((chptr->received_number_of_privmsgs >= GlobalSetOptions.floodcount) + || IsSetFloodNoticed(chptr)) + { + if (!IsSetFloodNoticed(chptr)) + { + sendto_realops_flags(UMODE_BOTS, L_ALL, + "Possible Flooder %s on %s target: %s", + get_client_name(source_p, HIDE_IP), + source_p->servptr->name, chptr->chname); + SetFloodNoticed(chptr); + + /* Add a bit of penalty */ + chptr->received_number_of_privmsgs += 2; + } + if (MyClient(source_p) && (p_or_n != NOTICE)) + sendto_one(source_p, + ":%s NOTICE %s :*** Message to %s throttled due to flooding", + me.name, source_p->name, chptr->chname); + return(1); + } + else + chptr->received_number_of_privmsgs++; + } + + return(0); +} + +/* handle_special() + * + * inputs - server pointer + * - client pointer + * - nick stuff to grok for opers + * - text to send if grok + * output - none + * side effects - old style username@server is handled here for non opers + * opers are allowed username%hostname@server + * all the traditional oper type messages are also parsed here. + * i.e. "/msg #some.host." + * However, syntax has been changed. + * previous syntax "/msg #some.host.mask" + * now becomes "/msg $#some.host.mask" + * previous syntax of: "/msg $some.server.mask" remains + * This disambiguates the syntax. + * + * XXX N.B. dalnet changed it to nick@server as have other servers. + * we will stick with tradition for now. + * - Dianora + */ +static void +handle_special(int p_or_n, const char *command, struct Client *client_p, + struct Client *source_p, char *nick, char *text) +{ + struct Client *target_p; + char *host; + char *server; + char *s; + int count; + + /* + * user[%host]@server addressed? + */ + if ((server = strchr(nick, '@')) != NULL) + { + count = 0; + + if ((host = strchr(nick, '%')) && !HasUMode(source_p, UMODE_OPER)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p)); + return; + } + + if ((target_p = hash_find_server(server + 1)) != NULL) + { + if (!IsMe(target_p)) + { + /* + * Not destined for a user on me :-( + */ + sendto_one(target_p, ":%s %s %s :%s", + ID_or_name(source_p, target_p->from), + command, nick, text); + if ((p_or_n != NOTICE) && MyClient(source_p)) + source_p->localClient->last_privmsg = CurrentTime; + return; + } + + *server = '\0'; + + if (host != NULL) + *host++ = '\0'; + + /* + * Look for users which match the destination host + * (no host == wildcard) and if one and one only is + * found connected to me, deliver message! + */ + target_p = find_userhost(nick, host, &count); + + if (target_p != NULL) + { + if (server != NULL) + *server = '@'; + if (host != NULL) + *--host = '%'; + + if (count == 1) + { + sendto_one(target_p, ":%s!%s@%s %s %s :%s", + source_p->name, source_p->username, source_p->host, + command, nick, text); + if ((p_or_n != NOTICE) && MyClient(source_p)) + source_p->localClient->last_privmsg = CurrentTime; + } + else + sendto_one(source_p, form_str(ERR_TOOMANYTARGETS), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), nick, + ConfigFileEntry.max_targets); + } + } + else if (server && *(server+1) && (target_p == NULL)) + sendto_one(source_p, form_str(ERR_NOSUCHSERVER), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), server+1); + else if (server && (target_p == NULL)) + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), nick); + return; + } + + if (!HasUMode(source_p, UMODE_OPER)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p)); + return; + } + + /* + * the following two cases allow masks in NOTICEs + * (for OPERs only) + * + * Armin, 8Jun90 (gruner@informatik.tu-muenchen.de) + */ + if (*nick == '$') + { + if ((*(nick+1) == '$' || *(nick+1) == '#')) + nick++; + else if (MyClient(source_p) && HasUMode(source_p, UMODE_OPER)) + { + sendto_one(source_p, + ":%s NOTICE %s :The command %s %s is no longer supported, please use $%s", + me.name, source_p->name, command, nick, nick); + return; + } + + if ((s = strrchr(nick, '.')) == NULL) + { + sendto_one(source_p, form_str(ERR_NOTOPLEVEL), + me.name, source_p->name, nick); + return; + } + + while (*++s) + if (*s == '.' || *s == '*' || *s == '?') + break; + + if (*s == '*' || *s == '?') + { + sendto_one(source_p, form_str(ERR_WILDTOPLEVEL), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), nick); + return; + } + + sendto_match_butone(IsServer(client_p) ? client_p : NULL, source_p, + nick + 1, (*nick == '#') ? MATCH_HOST : MATCH_SERVER, + "%s $%s :%s", command, nick, text); + + if ((p_or_n != NOTICE) && MyClient(source_p)) + source_p->localClient->last_privmsg = CurrentTime; + + return; + } +} + +/* + * find_userhost - find a user@host (server or user). + * inputs - user name to look for + * - host name to look for + * - pointer to count of number of matches found + * outputs - pointer to client if found + * - count is updated + * side effects - none + * + */ +static struct Client * +find_userhost(char *user, char *host, int *count) +{ + struct Client *c2ptr; + struct Client *res = NULL; + dlink_node *lc2ptr; + + *count = 0; + + if (collapse(user) != NULL) + { + DLINK_FOREACH(lc2ptr, local_client_list.head) + { + c2ptr = lc2ptr->data; + + if (!IsClient(c2ptr)) /* something other than a client */ + continue; + + if ((!host || match(host, c2ptr->host)) && + irccmp(user, c2ptr->username) == 0) + { + (*count)++; + res = c2ptr; + } + } + } + + return(res); +} + +static struct Message privmsg_msgtab = { + "PRIVMSG", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_privmsg, m_privmsg, m_ignore, m_privmsg, m_ignore} +}; + +static struct Message notice_msgtab = { + "NOTICE", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_notice, m_notice, m_ignore, m_notice, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&privmsg_msgtab); + mod_add_cmd(¬ice_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&privmsg_msgtab); + mod_del_cmd(¬ice_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_CORE +}; diff --git a/modules/core/m_mode.c b/modules/core/m_mode.c new file mode 100644 index 0000000..fa68b22 --- /dev/null +++ b/modules/core/m_mode.c @@ -0,0 +1,313 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_mode.c: Sets a user or channel mode. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "s_user.h" +#include "conf.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "packet.h" + + +/* + * m_mode - MODE command handler + * parv[0] - sender + * parv[1] - channel + */ +static void +m_mode(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Channel *chptr = NULL; + struct Membership *member; + static char modebuf[MODEBUFLEN]; + static char parabuf[MODEBUFLEN]; + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "MODE"); + return; + } + + /* Now, try to find the channel in question */ + if (!IsChanPrefix(*parv[1])) + { + /* if here, it has to be a non-channel name */ + set_user_mode(client_p, source_p, parc, parv); + return; + } + + if ((chptr = hash_find_channel(parv[1])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + ID_or_name(&me, source_p->from), + ID_or_name(source_p, source_p->from), + parv[1]); + return; + } + + /* Now known the channel exists */ + if (parc < 3) + { + channel_modes(chptr, source_p, modebuf, parabuf); + sendto_one(source_p, form_str(RPL_CHANNELMODEIS), + me.name, source_p->name, chptr->chname, modebuf, parabuf); + sendto_one(source_p, form_str(RPL_CREATIONTIME), + me.name, source_p->name, chptr->chname, chptr->channelts); + } + /* bounce all modes from people we deop on sjoin + * servers have always gotten away with murder, + * including telnet servers *g* - Dianora + * + * XXX Is it worth the bother to make an ms_mode() ? - Dianora + */ + else if (IsServer(source_p)) + { + set_channel_mode(client_p, source_p, chptr, NULL, parc - 2, parv + 2, + chptr->chname); + } + else + { + member = find_channel_link(source_p, chptr); + + if (!has_member_flags(member, CHFL_DEOPPED)) + { + /* Finish the flood grace period... */ + if (MyClient(source_p) && !IsFloodDone(source_p)) + { + if (!((parc == 3) && (parv[2][0] == 'b') && (parv[2][1] == '\0'))) + flood_endgrace(source_p); + } + + set_channel_mode(client_p, source_p, chptr, member, parc - 2, parv + 2, + chptr->chname); + } + } +} + +/* + * ms_tmode() + * + * inputs - parv[0] = UID + * parv[1] = TS + * parv[2] = channel name + * parv[3] = modestring + */ +static void +ms_tmode(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) +{ + struct Channel *chptr = NULL; + struct Membership *member = NULL; + + if ((chptr = hash_find_channel(parv[2])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + ID_or_name(&me, client_p), ID_or_name(source_p, client_p), parv[2]); + return; + } + + if (atol(parv[1]) > chptr->channelts) + return; + + if (IsServer(source_p)) + set_channel_mode(client_p, source_p, chptr, NULL, parc - 3, parv + 3, chptr->chname); + else + { + member = find_channel_link(source_p, chptr); + + /* XXX are we sure we just want to bail here? */ + if (has_member_flags(member, CHFL_DEOPPED)) + return; + + set_channel_mode(client_p, source_p, chptr, member, parc - 3, parv + 3, chptr->chname); + } +} + +/* + * ms_bmask() + * + * inputs - parv[0] = SID + * parv[1] = TS + * parv[2] = channel name + * parv[3] = type of ban to add ('b' 'I' or 'e') + * parv[4] = space delimited list of masks to add + * outputs - none + * side effects - propagates unchanged bmask line to CAP_TS6 servers, + * sends plain modes to the others. nothing is sent + * to the server the issuing server is connected through + */ +static void +ms_bmask(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) +{ + static char modebuf[IRCD_BUFSIZE]; + static char parabuf[IRCD_BUFSIZE]; + static char banbuf[IRCD_BUFSIZE]; + struct Channel *chptr; + char *s, *t, *mbuf, *pbuf; + long mode_type; + int mlen, tlen; + int modecount = 0; + int needcap = NOCAPS; + + if ((chptr = hash_find_channel(parv[2])) == NULL) + return; + + /* TS is higher, drop it. */ + if (atol(parv[1]) > chptr->channelts) + return; + + switch (*parv[3]) + { + case 'b': + mode_type = CHFL_BAN; + break; + + case 'e': + mode_type = CHFL_EXCEPTION; + needcap = CAP_EX; + break; + + case 'I': + mode_type = CHFL_INVEX; + needcap = CAP_IE; + break; + + /* maybe we should just blindly propagate this? */ + default: + return; + } + + parabuf[0] = '\0'; + s = banbuf; + strlcpy(s, parv[4], sizeof(banbuf)); + + /* only need to construct one buffer, for non-ts6 servers */ + mlen = ircsprintf(modebuf, ":%s MODE %s +", + source_p->name, chptr->chname); + mbuf = modebuf + mlen; + pbuf = parabuf; + + do { + if ((t = strchr(s, ' ')) != NULL) + *t++ = '\0'; + tlen = strlen(s); + + /* I dont even want to begin parsing this.. */ + if (tlen > MODEBUFLEN) + break; + + if (tlen && *s != ':' && add_id(source_p, chptr, s, mode_type)) + { + /* this new one wont fit.. */ + if (mbuf - modebuf + 2 + pbuf - parabuf + tlen > IRCD_BUFSIZE - 2 || + modecount >= MAXMODEPARAMS) + { + *mbuf = '\0'; + *(pbuf - 1) = '\0'; + + sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", + modebuf, parabuf); + sendto_server(client_p, needcap, CAP_TS6, + "%s %s", modebuf, parabuf); + + mbuf = modebuf + mlen; + pbuf = parabuf; + modecount = 0; + } + + *mbuf++ = parv[3][0]; + pbuf += ircsprintf(pbuf, "%s ", s); + modecount++; + } + + s = t; + } while (s != NULL); + + if (modecount) + { + *mbuf = *(pbuf - 1) = '\0'; + sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf); + sendto_server(client_p, needcap, CAP_TS6, + "%s %s", modebuf, parabuf); + } + + /* assumption here is that since the server sent BMASK, they are TS6, so they have an ID */ + sendto_server(client_p, CAP_TS6|needcap, NOCAPS, + ":%s BMASK %lu %s %s :%s", + source_p->id, (unsigned long)chptr->channelts, chptr->chname, + parv[3], parv[4]); +} + +static struct Message mode_msgtab = { + "MODE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_mode, m_mode, m_ignore, m_mode, m_ignore} +}; + +static struct Message tmode_msgtab = { + "TMODE", 0, 0, 4, MAXPARA, MFLG_SLOW, 0, + {m_ignore, m_ignore, ms_tmode, m_ignore, m_ignore, m_ignore} +}; + +static struct Message bmask_msgtab = { + "BMASK", 0, 0, 5, MAXPARA, MFLG_SLOW, 0, + {m_ignore, m_ignore, ms_bmask, m_ignore, m_ignore, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&mode_msgtab); + mod_add_cmd(&tmode_msgtab); + mod_add_cmd(&bmask_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&mode_msgtab); + mod_del_cmd(&tmode_msgtab); + mod_del_cmd(&bmask_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_CORE +}; diff --git a/modules/core/m_nick.c b/modules/core/m_nick.c new file mode 100644 index 0000000..68f4e57 --- /dev/null +++ b/modules/core/m_nick.c @@ -0,0 +1,1004 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_nick.c: Sets a users nick. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "hash.h" +#include "fdlist.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "conf.h" +#include "s_user.h" +#include "whowas.h" +#include "s_serv.h" +#include "send.h" +#include "channel.h" +#include "channel_mode.h" +#include "log.h" +#include "resv.h" +#include "parse.h" +#include "modules.h" +#include "packet.h" +#include "watch.h" + + +static void nick_from_server(struct Client *, struct Client *, int, char **, + time_t, const char *, char *, char *); +static void uid_from_server(struct Client *, struct Client *, int, char **, + time_t, const char *, char *, char *); +static int check_clean_nick(struct Client *client_p, struct Client *source_p, + char *nick, struct Client *server_p); +static int check_clean_user(struct Client *client_p, char *nick, char *user, + struct Client *server_p); +static int check_clean_host(struct Client *client_p, char *nick, char *host, + struct Client *server_p); + +static int clean_user_name(const char *); +static int clean_host_name(const char *); +static void perform_nick_collides(struct Client *, struct Client *, struct Client *, + int, char **, time_t, const char *, char *, char *, char *); + + +/* set_initial_nick() + * + * inputs + * output + * side effects - + * + * This function is only called to set up an initially registering + * client. + */ +static void +set_initial_nick(struct Client *source_p, const char *nick) +{ + /* Client setting NICK the first time */ + + /* This had to be copied here to avoid problems.. */ + source_p->tsinfo = CurrentTime; + source_p->localClient->registration &= ~REG_NEED_NICK; + + if (source_p->name[0]) + hash_del_client(source_p); + + strlcpy(source_p->name, nick, sizeof(source_p->name)); + hash_add_client(source_p); + + /* fd_desc is long enough */ + fd_note(&source_p->localClient->fd, "Nick: %s", nick); + + if (!source_p->localClient->registration) + register_local_user(source_p); +} + +/* change_local_nick() + * + * inputs - pointer to server + * - pointer to client + * - nick + * output - + * side effects - changes nick of a LOCAL user + */ +static void +change_local_nick(struct Client *source_p, const char *nick) +{ + assert(source_p->name[0] && !EmptyString(nick)); + assert(MyConnect(source_p)); + + /* + * Client just changing his/her nick. If he/she is + * on a channel, send note of change to all clients + * on that channel. Propagate notice to other servers. + */ + if ((source_p->localClient->last_nick_change + + ConfigFileEntry.max_nick_time) < CurrentTime) + source_p->localClient->number_of_nick_changes = 0; + source_p->localClient->last_nick_change = CurrentTime; + source_p->localClient->number_of_nick_changes++; + + if ((ConfigFileEntry.anti_nick_flood && + (source_p->localClient->number_of_nick_changes + <= ConfigFileEntry.max_nick_changes)) || + !ConfigFileEntry.anti_nick_flood || + (HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.no_oper_flood)) + { + int samenick = !irccmp(source_p->name, nick); + + if (!samenick) + { + source_p->tsinfo = CurrentTime; + clear_ban_cache_client(source_p); + watch_check_hash(source_p, RPL_LOGOFF); + + if (HasUMode(source_p, UMODE_REGISTERED)) + { + unsigned int oldmodes = source_p->umodes; + char modebuf[IRCD_BUFSIZE] = { '\0' }; + + DelUMode(source_p, UMODE_REGISTERED); + send_umode(source_p, source_p, oldmodes, 0xffffffff, modebuf); + } + } + + /* XXX - the format of this notice should eventually be changed + * to either %s[%s@%s], or even better would be get_client_name() -bill + */ + sendto_realops_flags(UMODE_NCHANGE, L_ALL, "Nick change: From %s to %s [%s@%s]", + source_p->name, nick, source_p->username, source_p->host); + sendto_common_channels_local(source_p, 1, ":%s!%s@%s NICK :%s", + source_p->name, source_p->username, + source_p->host, nick); + add_history(source_p, 1); + + sendto_server(source_p, CAP_TS6, NOCAPS, + ":%s NICK %s :%lu", + ID(source_p), nick, (unsigned long)source_p->tsinfo); + sendto_server(source_p, NOCAPS, CAP_TS6, + ":%s NICK %s :%lu", + source_p->name, nick, (unsigned long)source_p->tsinfo); + + hash_del_client(source_p); + strcpy(source_p->name, nick); + hash_add_client(source_p); + + if (!samenick) + watch_check_hash(source_p, RPL_LOGON); + + /* fd_desc is long enough */ + fd_note(&source_p->localClient->fd, "Nick: %s", nick); + } + else + sendto_one(source_p, form_str(ERR_NICKTOOFAST), + me.name, source_p->name, source_p->name, + nick, ConfigFileEntry.max_nick_time); +} + +/*! \brief NICK command handler (called by unregistered, + * locally connected clients) + * + * \param client_p Pointer to allocated Client struct with physical connection + * to this server, i.e. with an open socket connected. + * \param source_p Pointer to allocated Client struct from which the message + * originally comes from. This can be a local or remote client. + * \param parc Integer holding the number of supplied arguments. + * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL + * pointers. + * \note Valid arguments for this command are: + * - parv[0] = sender prefix + * - parv[1] = nickname + */ +static void +mr_nick(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + char nick[NICKLEN + 1]; + char *s = NULL; + + if (parc < 2 || EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, + source_p->name[0] ? source_p->name : "*"); + return; + } + + /* Terminate the nick at the first ~ */ + if ((s = strchr(parv[1], '~')) != NULL) + *s = '\0'; + + /* copy the nick and terminate it */ + strlcpy(nick, parv[1], sizeof(nick)); + + /* check the nickname is ok */ + if (!valid_nickname(nick, 1)) + { + sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, + source_p->name[0] ? source_p->name : "*", parv[1]); + return; + } + + /* check if the nick is resv'd */ + if (find_matching_name_conf(NRESV_TYPE, nick, NULL, NULL, 0) && + !IsExemptResv(source_p)) + { + sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, + source_p->name[0] ? source_p->name : "*", nick); + sendto_realops_flags(L_ALL, UMODE_REJ, + "Forbidding reserved nick [%s] from user %s", + nick, get_client_name(client_p, HIDE_IP)); + return; + } + + if ((target_p = hash_find_client(nick)) == NULL) + set_initial_nick(source_p, nick); + else if (source_p == target_p) + strlcpy(source_p->name, nick, sizeof(source_p->name)); + else + sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, "*", nick); +} + + +/*! \brief NICK command handler (called by already registered, + * locally connected clients) + * + * \param client_p Pointer to allocated Client struct with physical connection + * to this server, i.e. with an open socket connected. + * \param source_p Pointer to allocated Client struct from which the message + * originally comes from. This can be a local or remote client. + * \param parc Integer holding the number of supplied arguments. + * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL + * pointers. + * \note Valid arguments for this command are: + * - parv[0] = sender prefix + * - parv[1] = nickname + */ +static void +m_nick(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char nick[NICKLEN + 1]; + struct Client *target_p = NULL; + + assert(source_p == client_p); + + if (parc < 2 || EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), + me.name, source_p->name); + return; + } + + /* mark end of grace period, to prevent nickflooding */ + if (!IsFloodDone(source_p)) + flood_endgrace(source_p); + + /* terminate nick to NICKLEN */ + strlcpy(nick, parv[1], sizeof(nick)); + + /* check the nickname is ok */ + if (!valid_nickname(nick, 1)) + { + sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), + me.name, source_p->name, nick); + return; + } + + if (find_matching_name_conf(NRESV_TYPE, nick, + NULL, NULL, 0) && !IsExemptResv(source_p) && + !(HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.oper_pass_resv)) + { + sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), + me.name, source_p->name, nick); + sendto_realops_flags(L_ALL, UMODE_REJ, + "Forbidding reserved nick [%s] from user %s", + nick, get_client_name(client_p, HIDE_IP)); + return; + } + + if ((target_p = hash_find_client(nick)) == NULL) + change_local_nick(source_p, nick); + else if (target_p == source_p) + { + /* + * If (target_p == source_p) the client is changing nicks between + * equivalent nicknames ie: [nick] -> {nick} + */ + + /* check the nick isnt exactly the same */ + if (strcmp(target_p->name, nick)) + change_local_nick(source_p, nick); + } + else if (IsUnknown(target_p)) + { + /* + * if the client that has the nick isn't registered yet (nick but no + * user) then drop the unregged client + */ + exit_client(target_p, &me, "Overridden"); + change_local_nick(source_p, nick); + } + else + sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, + source_p->name, nick); +} + + +/*! \brief NICK command handler (called by servers and remotely + * connected clients) + * + * \param client_p Pointer to allocated Client struct with physical connection + * to this server, i.e. with an open socket connected. + * \param source_p Pointer to allocated Client struct from which the message + * originally comes from. This can be a local or remote client. + * \param parc Integer holding the number of supplied arguments. + * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL + * pointers. + * \note Valid arguments for this command are: + * + * server -> server nick change + * - parv[0] = sender prefix + * - parv[1] = nickname + * - parv[2] = TS when nick change + * + * server introducing new nick (without services support) + * - parv[0] = sender prefix + * - parv[1] = nickname + * - parv[2] = hop count + * - parv[3] = TS + * - parv[4] = umode + * - parv[5] = username + * - parv[6] = hostname + * - parv[7] = server + * - parv[8] = ircname + * + * server introducing new nick (with services support) + * - parv[0] = sender prefix + * - parv[1] = nickname + * - parv[2] = hop count + * - parv[3] = TS + * - parv[4] = umode + * - parv[5] = username + * - parv[6] = hostname + * - parv[7] = server + * - parv[8] = services id (timestamp) + * - parv[9] = ircname + */ +static void +ms_nick(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + time_t newts = 0; + const char *svsid = "0"; + + if (parc < 3 || EmptyString(parv[parc - 1])) + return; + + if (parc >= 9) + { + struct Client *server_p = hash_find_server(parv[7]); + + if (server_p == NULL) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "Invalid server %s from %s for NICK %s", + parv[7], source_p->name, parv[1]); + sendto_one(client_p, ":%s KILL %s :%s (Server doesn't exist!)", + me.name, parv[1], me.name); + return; + } + + if (check_clean_nick(client_p, source_p, parv[1], server_p) || + check_clean_user(client_p, parv[1], parv[5], server_p) || + check_clean_host(client_p, parv[1], parv[6], server_p)) + return; + + if (IsServer(source_p)) + newts = atol(parv[3]); + if (IsServer(source_p) && parc == 10) + svsid = parv[8]; + } + else if (parc == 3) + { + if (IsServer(source_p)) + /* Servers can't change nicks.. */ + return; + + if (check_clean_nick(client_p, source_p, parv[1], + source_p->servptr)) + return; + + newts = atol(parv[2]); + } + + /* if the nick doesnt exist, allow it and process like normal */ + if ((target_p = hash_find_client(parv[1])) == NULL) + nick_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]); + else if (IsUnknown(target_p)) + { + /* we're not living in the past anymore, an unknown client is local only. */ + exit_client(target_p, &me, "Overridden"); + nick_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]); + } + else if (target_p == source_p) + { + if (strcmp(target_p->name, parv[1])) + nick_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]); + } + else + perform_nick_collides(source_p, client_p, target_p, parc, parv, + newts, svsid, parv[1], parv[parc-1], NULL); +} + + +/*! \brief UID command handler (called by servers) + * + * \param client_p Pointer to allocated Client struct with physical connection + * to this server, i.e. with an open socket connected. + * \param source_p Pointer to allocated Client struct from which the message + * originally comes from. This can be a local or remote client. + * \param parc Integer holding the number of supplied arguments. + * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL + * pointers. + * \note Valid arguments for this command are: + * + * server introducing new nick (without services support) + * - parv[0] = sender prefix + * - parv[1] = nickname + * - parv[2] = hop count + * - parv[3] = TS + * - parv[4] = umode + * - parv[5] = username + * - parv[6] = hostname + * - parv[7] = ip + * - parv[8] = uid + * - parv[9] = ircname (gecos) + * + * server introducing new nick (with services support) + * - parv[ 0] = sender prefix + * - parv[ 1] = nickname + * - parv[ 2] = hop count + * - parv[ 3] = TS + * - parv[ 4] = umode + * - parv[ 5] = username + * - parv[ 6] = hostname + * - parv[ 7] = ip + * - parv[ 8] = uid + * - parv[ 9] = services id (timestamp) + * - parv[10] = ircname (gecos) + */ +static void +ms_uid(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + time_t newts = 0; + const char *svsid = "0"; + + if (parc < 10 || EmptyString(parv[parc-1])) + return; + + if (check_clean_nick(client_p, source_p, parv[1], source_p) || + check_clean_user(client_p, parv[1], parv[5], source_p) || + check_clean_host(client_p, parv[1], parv[6], source_p)) + return; + + newts = atol(parv[3]); + svsid = parc == 11 ? parv[9] : "0"; + + /* + * if there is an ID collision, kill our client, and kill theirs. + * this may generate 401's, but it ensures that both clients always + * go, even if the other server refuses to do the right thing. + */ + if ((target_p = hash_find_id(parv[8])) != NULL) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "ID collision on %s(%s <- %s)(both killed)", + target_p->name, target_p->from->name, + client_p->name); + kill_client_ll_serv_butone(NULL, target_p, "%s (ID collision)", + me.name); + + ++ServerStats.is_kill; + AddFlag(target_p, FLAGS_KILLED); + exit_client(target_p, &me, "ID Collision"); + return; + } + + if ((target_p = hash_find_client(parv[1])) == NULL) + uid_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]); + else if (IsUnknown(target_p)) + { + exit_client(target_p, &me, "Overridden"); + uid_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]); + } + else + perform_nick_collides(source_p, client_p, target_p, parc, parv, newts, svsid, parv[1], + parv[parc-1], parv[8]); +} + +/* check_clean_nick() + * + * input - pointer to source + * - + * - nickname + * - truncated nickname + * - origin of client + * - pointer to server nick is coming from + * output - none + * side effects - if nickname is erroneous, or a different length to + * truncated nickname, return 1 + */ +static int +check_clean_nick(struct Client *client_p, struct Client *source_p, + char *nick, struct Client *server_p) +{ + /* the old code did some wacky stuff here, if the nick is invalid, kill it + * and dont bother messing at all + */ + if (!valid_nickname(nick, 0)) + { + ++ServerStats.is_kill; + sendto_realops_flags(UMODE_DEBUG, L_ALL, + "Bad/long Nick: %s From: %s(via %s)", + nick, server_p->name, client_p->name); + + sendto_one(client_p, ":%s KILL %s :%s (Bad Nickname)", + me.name, nick, me.name); + + /* bad nick change */ + if (source_p != client_p) + { + kill_client_ll_serv_butone(client_p, source_p, + "%s (Bad Nickname)", + me.name); + AddFlag(source_p, FLAGS_KILLED); + exit_client(source_p, &me, "Bad Nickname"); + } + + return 1; + } + + return 0; +} + +/* check_clean_user() + * + * input - pointer to client sending data + * - nickname + * - username to check + * - origin of NICK + * output - none + * side effects - if username is erroneous, return 1 + */ +static int +check_clean_user(struct Client *client_p, char *nick, + char *user, struct Client *server_p) +{ + if (!clean_user_name(user)) + { + ++ServerStats.is_kill; + sendto_realops_flags(UMODE_DEBUG, L_ALL, + "Bad/Long Username: %s Nickname: %s From: %s(via %s)", + user, nick, server_p->name, client_p->name); + sendto_one(client_p, ":%s KILL %s :%s (Bad Username)", + me.name, nick, me.name); + return 1; + } + + return 0; +} + +/* check_clean_host() + * + * input - pointer to client sending us data + * - nickname + * - hostname to check + * - source name + * output - none + * side effects - if hostname is erroneous, return 1 + */ +static int +check_clean_host(struct Client *client_p, char *nick, + char *host, struct Client *server_p) +{ + if (!clean_host_name(host)) + { + ++ServerStats.is_kill; + sendto_realops_flags(UMODE_DEBUG, L_ALL, + "Bad/Long Hostname: %s Nickname: %s From: %s(via %s)", + host, nick, server_p->name, client_p->name); + sendto_one(client_p, ":%s KILL %s :%s (Bad Hostname)", + me.name, nick, me.name); + return 1; + } + + return 0; +} + +/* clean_user_name() + * + * input - username + * output - none + * side effects - walks through the username, returning 0 if erroneous + */ +static int +clean_user_name(const char *user) +{ + const char *p = user; + + assert(user && *user); + + for (; *p; ++p) + if (!IsUserChar(*p)) + return 0; + + return p - user <= USERLEN; +} + +/* clean_host_name() + * input - hostname + * output - none + * side effects - walks through the hostname, returning 0 if erroneous + */ +static int +clean_host_name(const char *host) +{ + const char *p = host; + + assert(host && *host); + + for (; *p; ++p) + if (!IsHostChar(*p)) + return 0; + + return p - host <= HOSTLEN; +} + +/* + * nick_from_server() + */ +static void +nick_from_server(struct Client *client_p, struct Client *source_p, int parc, + char *parv[], time_t newts, const char *svsid, char *nick, char *ngecos) +{ + int samenick = 0; + + if (IsServer(source_p)) + { + /* A server introducing a new client, change source */ + source_p = make_client(client_p); + dlinkAdd(source_p, &source_p->node, &global_client_list); + + if (parc > 2) + source_p->hopcount = atoi(parv[2]); + if (newts) + source_p->tsinfo = newts; + else + { + newts = source_p->tsinfo = CurrentTime; + ts_warn("Remote nick %s (%s) introduced without a TS", nick, parv[0]); + } + + strlcpy(source_p->svid, svsid, sizeof(source_p->svid)); + strlcpy(source_p->info, ngecos, sizeof(source_p->info)); + /* copy the nick in place */ + strlcpy(source_p->name, nick, sizeof(source_p->name)); + hash_add_client(source_p); + + if (parc > 8) + { + const char *m; + + /* parse usermodes */ + for (m = &parv[4][1]; *m; ++m) + { + unsigned int flag = user_modes[(unsigned char)*m]; + + if ((flag & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE)) + ++Count.invisi; + if ((flag & UMODE_OPER) && !HasUMode(source_p, UMODE_OPER)) + ++Count.oper; + + source_p->umodes |= flag & SEND_UMODES; + } + + register_remote_user(source_p, parv[5], parv[6], + parv[7], ngecos); + return; + } + } + else if (source_p->name[0]) + { + samenick = !irccmp(source_p->name, nick); + + /* client changing their nick */ + if (!samenick) + { + DelUMode(source_p, UMODE_REGISTERED); + watch_check_hash(source_p, RPL_LOGOFF); + source_p->tsinfo = newts ? newts : CurrentTime; + } + + sendto_common_channels_local(source_p, 1, ":%s!%s@%s NICK :%s", + source_p->name,source_p->username, + source_p->host, nick); + + add_history(source_p, 1); + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s NICK %s :%lu", + ID(source_p), nick, (unsigned long)source_p->tsinfo); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s NICK %s :%lu", + source_p->name, nick, (unsigned long)source_p->tsinfo); + } + + /* set the new nick name */ + if (source_p->name[0]) + hash_del_client(source_p); + + strlcpy(source_p->name, nick, sizeof(source_p->name)); + hash_add_client(source_p); + + if (!samenick) + watch_check_hash(source_p, RPL_LOGON); +} + +/* + * client_from_server() + */ +static void +uid_from_server(struct Client *client_p, struct Client *source_p, int parc, + char *parv[], time_t newts, const char *svsid, char *nick, char *ugecos) +{ + const char *m = NULL; + const char *servername = source_p->name; + + source_p = make_client(client_p); + dlinkAdd(source_p, &source_p->node, &global_client_list); + + source_p->hopcount = atoi(parv[2]); + source_p->tsinfo = newts; + strlcpy(source_p->svid, svsid, sizeof(source_p->svid)); + + /* copy the nick in place */ + strcpy(source_p->name, nick); + strlcpy(source_p->id, parv[8], sizeof(source_p->id)); + strlcpy(source_p->sockhost, parv[7], sizeof(source_p->sockhost)); + strlcpy(source_p->info, ugecos, sizeof(source_p->info)); + + hash_add_client(source_p); + hash_add_id(source_p); + + /* parse usermodes */ + for (m = &parv[4][1]; *m; ++m) + { + unsigned int flag = user_modes[(unsigned char)*m]; + + if ((flag & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE)) + ++Count.invisi; + if ((flag & UMODE_OPER) && !HasUMode(source_p, UMODE_OPER)) + ++Count.oper; + + source_p->umodes |= flag & SEND_UMODES; + } + + register_remote_user(source_p, parv[5], parv[6], + servername, ugecos); +} + +static void +perform_nick_collides(struct Client *source_p, struct Client *client_p, + struct Client *target_p, int parc, char *parv[], + time_t newts, const char *svsid, char *nick, char *gecos, char *uid) +{ + int sameuser; + + /* server introducing new nick */ + if (IsServer(source_p)) + { + /* if we dont have a ts, or their TS's are the same, kill both */ + if (!newts || !target_p->tsinfo || (newts == target_p->tsinfo)) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "Nick collision on %s(%s <- %s)(both killed)", + target_p->name, target_p->from->name, + client_p->name); + + /* if we have a UID, issue a kill for it */ + if (uid) + sendto_one(client_p, ":%s KILL %s :%s (Nick collision (new))", + me.id, uid, me.name); + + kill_client_ll_serv_butone(NULL, target_p, + "%s (Nick collision (new))", + me.name); + ++ServerStats.is_kill; + sendto_one(target_p, form_str(ERR_NICKCOLLISION), + me.name, target_p->name, target_p->name); + + AddFlag(target_p, FLAGS_KILLED); + exit_client(target_p, &me, "Nick collision (new)"); + return; + } + /* the timestamps are different */ + else + { + sameuser = !irccmp(target_p->username, parv[5]) && + !irccmp(target_p->host, parv[6]); + + /* if the users are the same (loaded a client on a different server) + * and the new users ts is older, or the users are different and the + * new users ts is newer, ignore the new client and let it do the kill + */ + if ((sameuser && newts < target_p->tsinfo) || + (!sameuser && newts > target_p->tsinfo)) + { + if (uid) + sendto_one(client_p, ":%s KILL %s :%s (Nick collision (new))", + me.id, uid, me.name); + return; + } + else + { + if (sameuser) + sendto_realops_flags(UMODE_ALL, L_ALL, + "Nick collision on %s(%s <- %s)(older killed)", + target_p->name, target_p->from->name, + client_p->name); + else + sendto_realops_flags(UMODE_ALL, L_ALL, + "Nick collision on %s(%s <- %s)(newer killed)", + target_p->name, target_p->from->name, + client_p->name); + + ++ServerStats.is_kill; + sendto_one(target_p, form_str(ERR_NICKCOLLISION), + me.name, target_p->name, target_p->name); + + /* if it came from a LL server, itd have been source_p, + * so we dont need to mark target_p as known + */ + kill_client_ll_serv_butone(source_p, target_p, + "%s (Nick collision (new))", + me.name); + + AddFlag(target_p, FLAGS_KILLED); + exit_client(target_p, &me, "Nick collision"); + + if (!uid && (parc == 9 || parc == 10)) + nick_from_server(client_p, source_p, parc, parv, newts, svsid, nick, gecos); + else if (uid && (parc == 10 || parc == 11)) + uid_from_server(client_p, source_p, parc, parv, newts, svsid, nick, gecos); + + return; + } + } + } + + /* its a client changing nick and causing a collide */ + if (!newts || !target_p->tsinfo || (newts == target_p->tsinfo)) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "Nick change collision from %s to %s(%s <- %s)(both killed)", + source_p->name, target_p->name, target_p->from->name, + client_p->name); + + sendto_one(target_p, form_str(ERR_NICKCOLLISION), me.name, + target_p->name, target_p->name); + + ++ServerStats.is_kill; + kill_client_ll_serv_butone(NULL, source_p, "%s (Nick change collision)", + me.name); + + ++ServerStats.is_kill; + kill_client_ll_serv_butone(NULL, target_p, "%s (Nick change collision)", + me.name); + + AddFlag(target_p, FLAGS_KILLED); + exit_client(target_p, &me, "Nick collision (new)"); + + AddFlag(source_p, FLAGS_KILLED); + exit_client(source_p, &me, "Nick collision (old)"); + return; + } + else + { + sameuser = !irccmp(target_p->username, source_p->username) && + !irccmp(target_p->host, source_p->host); + + if ((sameuser && newts < target_p->tsinfo) || + (!sameuser && newts > target_p->tsinfo)) + { + if (sameuser) + sendto_realops_flags(UMODE_ALL, L_ALL, + "Nick change collision from %s to %s(%s <- %s)(older killed)", + source_p->name, target_p->name, target_p->from->name, + client_p->name); + else + sendto_realops_flags(UMODE_ALL, L_ALL, + "Nick change collision from %s to %s(%s <- %s)(newer killed)", + source_p->name, target_p->name, target_p->from->name, + client_p->name); + + ++ServerStats.is_kill; + kill_client_ll_serv_butone(client_p, source_p, + "%s (Nick change collision)", + me.name); + + AddFlag(source_p, FLAGS_KILLED); + + if (sameuser) + exit_client(source_p, &me, "Nick collision (old)"); + else + exit_client(source_p, &me, "Nick collision (new)"); + return; + } + else + { + if (sameuser) + sendto_realops_flags(UMODE_ALL, L_ALL, + "Nick collision on %s(%s <- %s)(older killed)", + target_p->name, target_p->from->name, + client_p->name); + else + sendto_realops_flags(UMODE_ALL, L_ALL, + "Nick collision on %s(%s <- %s)(newer killed)", + target_p->name, target_p->from->name, + client_p->name); + + kill_client_ll_serv_butone(source_p, target_p, + "%s (Nick collision)", + me.name); + + ++ServerStats.is_kill; + sendto_one(target_p, form_str(ERR_NICKCOLLISION), + me.name, target_p->name, target_p->name); + + AddFlag(target_p, FLAGS_KILLED); + exit_client(target_p, &me, "Nick collision"); + } + } + + /* we should only ever call nick_from_server() here, as + * this is a client changing nick, not a new client + */ + nick_from_server(client_p, source_p, parc, parv, newts, svsid, nick, gecos); +} + +static struct Message nick_msgtab = { + "NICK", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {mr_nick, m_nick, ms_nick, m_ignore, m_nick, m_ignore} +}; + +static struct Message uid_msgtab = { + "UID", 0, 0, 10, MAXPARA, MFLG_SLOW, 0, + {m_ignore, m_ignore, ms_uid, m_ignore, m_ignore, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&uid_msgtab); + mod_add_cmd(&nick_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&uid_msgtab); + mod_del_cmd(&nick_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_CORE +}; diff --git a/modules/core/m_part.c b/modules/core/m_part.c new file mode 100644 index 0000000..3d1e83a --- /dev/null +++ b/modules/core/m_part.c @@ -0,0 +1,167 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_part.c: Parts a user from a channel. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "s_serv.h" +#include "parse.h" +#include "modules.h" +#include "conf.h" +#include "packet.h" + + +/* part_one_client() + * + * inputs - pointer to server + * - pointer to source client to remove + * - char pointer of name of channel to remove from + * output - none + * side effects - remove ONE client given the channel name + */ +static void +part_one_client(struct Client *client_p, struct Client *source_p, + const char *name, const char *reason) +{ + struct Channel *chptr = NULL; + struct Membership *ms = NULL; + + if ((chptr = hash_find_channel(name)) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, name); + return; + } + + if ((ms = find_channel_link(source_p, chptr)) == NULL) + { + sendto_one(source_p, form_str(ERR_NOTONCHANNEL), + me.name, source_p->name, name); + return; + } + + if (MyConnect(source_p) && !HasUMode(source_p, UMODE_OPER)) + check_spambot_warning(source_p, NULL); + + /* + * Remove user from the old channel (if any) + * only allow /part reasons in -m chans + */ + if (reason[0] && (!MyConnect(source_p) || + ((can_send(chptr, source_p, ms) && + (source_p->localClient->firsttime + ConfigFileEntry.anti_spam_exit_message_time) + < CurrentTime)))) + { + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s PART %s :%s", ID(source_p), chptr->chname, + reason); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s PART %s :%s", source_p->name, chptr->chname, + reason); + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s PART %s :%s", + source_p->name, source_p->username, + source_p->host, chptr->chname, reason); + } + else + { + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s PART %s", ID(source_p), chptr->chname); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s PART %s", source_p->name, chptr->chname); + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s PART %s", + source_p->name, source_p->username, + source_p->host, chptr->chname); + } + + remove_user_from_channel(ms); +} + +/* +** m_part +** parv[0] = sender prefix +** parv[1] = channel +** parv[2] = reason +*/ +static void +m_part(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *p = NULL, *name = NULL; + char reason[KICKLEN + 1] = { '\0' }; + + if (IsServer(source_p)) + return; + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "PART"); + return; + } + + if (parc > 2) + strlcpy(reason, parv[2], sizeof(reason)); + + /* Finish the flood grace period... */ + if (MyClient(source_p) && !IsFloodDone(source_p)) + flood_endgrace(source_p); + + for (name = strtoken(&p, parv[1], ","); name; + name = strtoken(&p, NULL, ",")) + part_one_client(client_p, source_p, name, reason); +} + +static struct Message part_msgtab = { + "PART", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_part, m_part, m_ignore, m_part, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&part_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&part_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_CORE +}; diff --git a/modules/core/m_quit.c b/modules/core/m_quit.c new file mode 100644 index 0000000..ca73e2e --- /dev/null +++ b/modules/core/m_quit.c @@ -0,0 +1,98 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_quit.c: Makes a user quit from IRC. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "irc_string.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "conf.h" + + +/* +** m_quit +** parv[0] = sender prefix +** parv[1] = comment +*/ +static void +m_quit(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *comment = (parc > 1 && parv[1]) ? parv[1] : client_p->name; + char reason[KICKLEN + 1] = "Quit: "; + + if (*comment && (HasUMode(source_p, UMODE_OPER) || + (source_p->localClient->firsttime + ConfigFileEntry.anti_spam_exit_message_time) + < CurrentTime)) + strlcpy(reason+6, comment, sizeof(reason)-6); + + exit_client(source_p, source_p, reason); +} + +/* +** ms_quit +** parv[0] = sender prefix +** parv[1] = comment +*/ +static void +ms_quit(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *comment = (parc > 1 && parv[1]) ? parv[1] : client_p->name; + + if (strlen(comment) > (size_t)KICKLEN) + comment[KICKLEN] = '\0'; + + exit_client(source_p, source_p, comment); +} + +static struct Message quit_msgtab = { + "QUIT", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {m_quit, m_quit, ms_quit, m_ignore, m_quit, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&quit_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&quit_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_CORE +}; diff --git a/modules/core/m_server.c b/modules/core/m_server.c new file mode 100644 index 0000000..6054a34 --- /dev/null +++ b/modules/core/m_server.c @@ -0,0 +1,624 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_server.c: Introduces a server. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" /* client struct */ +#include "event.h" +#include "hash.h" /* add_to_client_hash_table */ +#include "irc_string.h" +#include "ircd.h" /* me */ +#include "numeric.h" /* ERR_xxx */ +#include "conf.h" /* struct AccessItem */ +#include "log.h" /* log level defines */ +#include "s_serv.h" /* server_estab, check_server */ +#include "s_user.h" +#include "send.h" /* sendto_one */ +#include "parse.h" +#include "modules.h" + + +static void set_server_gecos(struct Client *, const char *); + +/* mr_server() + * parv[0] = sender prefix + * parv[1] = servername + * parv[2] = serverinfo/hopcount + * parv[3] = serverinfo + */ +static void +mr_server(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *name; + struct Client *target_p; + int hop; + + if (EmptyString(parv[3])) + { + sendto_one(client_p, "ERROR :No servername"); + exit_client(client_p, client_p, "Wrong number of args"); + return; + } + + name = parv[1]; + hop = atoi(parv[2]); + + /* + * Reject a direct nonTS server connection if we're TS_ONLY -orabidoo + */ + if (!DoesTS(client_p)) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Unauthorized server connection attempt from %s: Non-TS server " + "for server %s", get_client_name(client_p, HIDE_IP), name); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Unauthorized server connection attempt from %s: Non-TS server " + "for server %s", get_client_name(client_p, MASK_IP), name); + exit_client(client_p, client_p, "Non-TS server"); + return; + } + + if (!valid_servname(name)) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Unauthorized server connection attempt from %s: Bogus server name " + "for server %s", get_client_name(client_p, HIDE_IP), name); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Unauthorized server connection attempt from %s: Bogus server name " + "for server %s", get_client_name(client_p, MASK_IP), name); + exit_client(client_p, client_p, "Bogus server name"); + return; + } + + /* Now we just have to call check_server and everything should + * be check for us... -A1kmm. + */ + switch (check_server(name, client_p)) + { + case -1: + if (ConfigFileEntry.warn_no_nline) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Unauthorized server connection attempt from %s: No entry for " + "servername %s", get_client_name(client_p, HIDE_IP), name); + + sendto_realops_flags(UMODE_ALL, L_OPER, + "Unauthorized server connection attempt from %s: No entry for " + "servername %s", get_client_name(client_p, MASK_IP), name); + } + + exit_client(client_p, client_p, "Invalid servername."); + return; + /* NOT REACHED */ + break; + + case -2: + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Unauthorized server connection attempt from %s: Bad password " + "for server %s", get_client_name(client_p, HIDE_IP), name); + + sendto_realops_flags(UMODE_ALL, L_OPER, + "Unauthorized server connection attempt from %s: Bad password " + "for server %s", get_client_name(client_p, MASK_IP), name); + + exit_client(client_p, client_p, "Invalid password."); + return; + /* NOT REACHED */ + break; + + case -3: + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Unauthorized server connection attempt from %s: Invalid host " + "for server %s", get_client_name(client_p, HIDE_IP), name); + + sendto_realops_flags(UMODE_ALL, L_OPER, + "Unauthorized server connection attempt from %s: Invalid host " + "for server %s", get_client_name(client_p, MASK_IP), name); + + exit_client(client_p, client_p, "Invalid host."); + return; + /* NOT REACHED */ + break; + } + + if ((client_p->id[0] && (target_p = hash_find_id(client_p->id))) + || (target_p = hash_find_server(name))) + { + /* This link is trying feed me a server that I already have + * access through another path -- multiple paths not accepted + * currently, kill this link immediately!! + * + * Rather than KILL the link which introduced it, KILL the + * youngest of the two links. -avalon + * + * Definitely don't do that here. This is from an unregistered + * connect - A1kmm. + */ + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Attempt to re-introduce server %s SID %s from %s", + name, client_p->id, + get_client_name(client_p, HIDE_IP)); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Attempt to re-introduce server %s SID %s from %s", + name, client_p->id, + get_client_name(client_p, MASK_IP)); + sendto_one(client_p, "ERROR :Server ID already exists."); + exit_client(client_p, client_p, "Server ID Exists"); + return; + } + + /* XXX If somehow there is a connect in progress and + * a connect comes in with same name toss the pending one, + * but only if it's not the same client! - Dianora + */ + if ((target_p = find_servconn_in_progress(name))) + if (target_p != client_p) + exit_client(target_p, &me, "Overridden"); + + /* if we are connecting (Handshake), we already have the name from the + * connect{} block in client_p->name + */ + strlcpy(client_p->name, name, sizeof(client_p->name)); + set_server_gecos(client_p, parv[3]); + client_p->hopcount = hop; + server_estab(client_p); +} + +/* ms_server() + * parv[0] = sender prefix + * parv[1] = servername + * parv[2] = serverinfo/hopcount + * parv[3] = serverinfo + */ +static void +ms_server(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *name; + struct Client *target_p; + struct AccessItem *aconf; + int hop; + int hlined = 0; + int llined = 0; + dlink_node *ptr = NULL; + + /* Just to be sure -A1kmm. */ + if (!IsServer(source_p)) + return; + + if (EmptyString(parv[3])) + { + sendto_one(client_p, "ERROR :No servername"); + return; + } + + name = parv[1]; + hop = atoi(parv[2]); + + if (!valid_servname(name)) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Link %s introduced server with bogus server name %s", + get_client_name(client_p, SHOW_IP), name); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Link %s introduced server with bogus server name %s", + get_client_name(client_p, MASK_IP), name); + sendto_one(client_p, "ERROR :Bogus server name introduced"); + exit_client(client_p, &me, "Bogus server name intoduced"); + return; + } + + if ((target_p = hash_find_server(name))) + { + /* This link is trying feed me a server that I already have + * access through another path -- multiple paths not accepted + * currently, kill this link immediately!! + * + * Rather than KILL the link which introduced it, KILL the + * youngest of the two links. -avalon + * + * I think that we should exit the link itself, not the introducer, + * and we should always exit the most recently received(i.e. the + * one we are receiving this SERVER for. -A1kmm + * + * You *cant* do this, if you link somewhere, it bursts you a server + * that already exists, then sends you a client burst, you squit the + * server, but you keep getting the burst of clients on a server that + * doesnt exist, although ircd can handle it, its not a realistic + * solution.. --fl_ + */ + sendto_one(client_p, "ERROR :Server %s already exists", name); + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Link %s cancelled, server %s already exists", + get_client_name(client_p, SHOW_IP), name); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Link %s cancelled, server %s already exists", + client_p->name, name); + exit_client(client_p, &me, "Server Exists"); + return; + } + + /* XXX If somehow there is a connect in progress and + * a connect comes in with same name toss the pending one, + * but only if it's not the same client! - Dianora + */ + if ((target_p = find_servconn_in_progress(name))) + if (target_p != client_p) + exit_client(target_p, &me, "Overridden"); + + aconf = map_to_conf(client_p->localClient->confs.head->data); + + /* See if the newly found server is behind a guaranteed + * leaf. If so, close the link. + */ + DLINK_FOREACH(ptr, aconf->leaf_list.head) + if (match(ptr->data, name)) + { + llined = 1; + break; + } + + DLINK_FOREACH(ptr, aconf->hub_list.head) + if (match(ptr->data, name)) + { + hlined = 1; + break; + } + + /* Ok, this way this works is + * + * A server can have a CONF_HUB allowing it to introduce servers + * behind it. + * + * connect { + * name = "irc.bighub.net"; + * hub_mask="*"; + * ... + * + * That would allow "irc.bighub.net" to introduce anything it wanted.. + * + * However + * + * connect { + * name = "irc.somehub.fi"; + * hub_mask="*"; + * leaf_mask="*.edu"; + *... + * Would allow this server in finland to hub anything but + * .edu's + */ + + /* Ok, check client_p can hub the new server */ + if (!hlined) + { + /* OOOPs nope can't HUB */ + sendto_realops_flags(UMODE_ALL, L_ADMIN, "Non-Hub link %s introduced %s.", + get_client_name(client_p, HIDE_IP), name); + sendto_realops_flags(UMODE_ALL, L_OPER, "Non-Hub link %s introduced %s.", + get_client_name(client_p, MASK_IP), name); + exit_client(source_p, &me, "No matching hub_mask."); + return; + } + + /* Check for the new server being leafed behind this HUB */ + if (llined) + { + /* OOOPs nope can't HUB this leaf */ + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Link %s introduced leafed server %s.", + get_client_name(client_p, HIDE_IP), name); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Link %s introduced leafed server %s.", + get_client_name(client_p, MASK_IP), name); + /* If it is new, we are probably misconfigured, so split the + * non-hub server introducing this. Otherwise, split the new + * server. -A1kmm. + */ + /* wastes too much bandwidth, generates too many errors on + * larger networks, dont bother. --fl_ + */ + exit_client(client_p, &me, "Leafed Server."); + return; + } + + target_p = make_client(client_p); + make_server(target_p); + target_p->hopcount = hop; + target_p->servptr = source_p; + + strlcpy(target_p->name, name, sizeof(target_p->name)); + + set_server_gecos(target_p, parv[3]); + SetServer(target_p); + + if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(SERVICE_TYPE, target_p->name, NULL, NULL, 0)) + AddFlag(target_p, FLAGS_SERVICE); + + dlinkAdd(target_p, &target_p->node, &global_client_list); + dlinkAdd(target_p, make_dlink_node(), &global_serv_list); + dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->server_list); + + hash_add_client(target_p); + + sendto_server(client_p, NOCAPS, NOCAPS, ":%s SERVER %s %d :%s%s", + source_p->name, target_p->name, hop + 1, + IsHidden(target_p) ? "(H) " : "", target_p->info); + + sendto_realops_flags(UMODE_EXTERNAL, L_ALL, + "Server %s being introduced by %s", + target_p->name, source_p->name); +} + +/* ms_sid() + * parv[0] = sender prefix + * parv[1] = servername + * parv[2] = serverinfo/hopcount + * parv[3] = sid of new server + * parv[4] = serverinfo + */ +static void +ms_sid(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p; + struct AccessItem *aconf = NULL; + int hlined = 0; + int llined = 0; + dlink_node *ptr = NULL; + int hop; + + /* Just to be sure -A1kmm. */ + if (!IsServer(source_p)) + return; + + if (EmptyString(parv[4])) + { + sendto_one(client_p, "ERROR :No servername"); + return; + } + + hop = atoi(parv[2]); + + if (!valid_servname(parv[1])) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Link %s introduced server with bogus server name %s", + get_client_name(client_p, SHOW_IP), parv[1]); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Link %s introduced server with bogus server name %s", + get_client_name(client_p, MASK_IP), parv[1]); + sendto_one(client_p, "ERROR :Bogus server name introduced"); + exit_client(client_p, &me, "Bogus server name intoduced"); + return; + } + + if (!valid_sid(parv[3])) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Link %s introduced server with bogus server ID %s", + get_client_name(client_p, SHOW_IP), parv[3]); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Link %s introduced server with bogus server ID %s", + get_client_name(client_p, MASK_IP), parv[3]); + sendto_one(client_p, "ERROR :Bogus server ID introduced"); + exit_client(client_p, &me, "Bogus server ID intoduced"); + return; + } + + /* collision on SID? */ + if ((target_p = hash_find_id(parv[3]))) + { + sendto_one(client_p, "ERROR :SID %s already exists", parv[3]); + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Link %s cancelled, SID %s already exists", + get_client_name(client_p, SHOW_IP), parv[3]); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Link %s cancelled, SID %s already exists", + client_p->name, parv[3]); + exit_client(client_p, &me, "SID Exists"); + return; + } + + /* collision on name? */ + if ((target_p = hash_find_server(parv[1]))) + { + sendto_one(client_p, "ERROR :Server %s already exists", parv[1]); + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Link %s cancelled, server %s already exists", + get_client_name(client_p, SHOW_IP), parv[1]); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Link %s cancelled, server %s already exists", + client_p->name, parv[1]); + exit_client(client_p, &me, "Server Exists"); + return; + } + + /* XXX If somehow there is a connect in progress and + * a connect comes in with same name toss the pending one, + * but only if it's not the same client! - Dianora + */ + if ((target_p = find_servconn_in_progress(parv[1]))) + if (target_p != client_p) + exit_client(target_p, &me, "Overridden"); + + aconf = map_to_conf(client_p->localClient->confs.head->data); + + /* See if the newly found server is behind a guaranteed + * leaf. If so, close the link. + */ + DLINK_FOREACH(ptr, aconf->leaf_list.head) + if (match(ptr->data, parv[1])) + { + llined = 1; + break; + } + + DLINK_FOREACH(ptr, aconf->hub_list.head) + if (match(ptr->data, parv[1])) + { + hlined = 1; + break; + } + + + /* Ok, this way this works is + * + * A server can have a CONF_HUB allowing it to introduce servers + * behind it. + * + * connect { + * name = "irc.bighub.net"; + * hub_mask="*"; + * ... + * + * That would allow "irc.bighub.net" to introduce anything it wanted.. + * + * However + * + * connect { + * name = "irc.somehub.fi"; + * hub_mask="*"; + * leaf_mask="*.edu"; + *... + * Would allow this server in finland to hub anything but + * .edu's + */ + + /* Ok, check client_p can hub the new server, and make sure it's not a LL */ + if (!hlined) + { + /* OOOPs nope can't HUB */ + sendto_realops_flags(UMODE_ALL, L_ADMIN, "Non-Hub link %s introduced %s.", + get_client_name(client_p, SHOW_IP), parv[1]); + sendto_realops_flags(UMODE_ALL, L_OPER, "Non-Hub link %s introduced %s.", + get_client_name(client_p, MASK_IP), parv[1]); + exit_client(source_p, &me, "No matching hub_mask."); + return; + } + + /* Check for the new server being leafed behind this HUB */ + if (llined) + { + /* OOOPs nope can't HUB this leaf */ + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Link %s introduced leafed server %s.", + get_client_name(client_p, SHOW_IP), parv[1]); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Link %s introduced leafed server %s.", + get_client_name(client_p, MASK_IP), parv[1]); + exit_client(client_p, &me, "Leafed Server."); + return; + } + + target_p = make_client(client_p); + make_server(target_p); + target_p->hopcount = hop; + target_p->servptr = source_p; + + strlcpy(target_p->name, parv[1], sizeof(target_p->name)); + strlcpy(target_p->id, parv[3], sizeof(target_p->id)); + + set_server_gecos(target_p, parv[4]); + SetServer(target_p); + + if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(SERVICE_TYPE, target_p->name, NULL, NULL, 0)) + AddFlag(target_p, FLAGS_SERVICE); + + dlinkAdd(target_p, &target_p->node, &global_client_list); + dlinkAdd(target_p, make_dlink_node(), &global_serv_list); + dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->server_list); + + hash_add_client(target_p); + hash_add_id(target_p); + + sendto_server(client_p, CAP_TS6, NOCAPS, ":%s SID %s %d %s :%s%s", + ID_or_name(source_p, client_p), target_p->name, hop + 1, + target_p->id, IsHidden(target_p) ? "(H) " : "", target_p->info); + sendto_server(client_p, NOCAPS, CAP_TS6, ":%s SERVER %s %d :%s%s", + source_p->name, target_p->name, hop + 1, + IsHidden(target_p) ? "(H) " : "", target_p->info); + + sendto_realops_flags(UMODE_EXTERNAL, L_ALL, + "Server %s being introduced by %s", + target_p->name, source_p->name); +} + +/* set_server_gecos() + * + * input - pointer to client + * output - NONE + * side effects - servers gecos field is set + */ +static void +set_server_gecos(struct Client *client_p, const char *info) +{ + const char *s = info; + + /* check for (H) which is a hidden server */ + if (!strncmp(s, "(H) ", 4)) + { + SetHidden(client_p); + s = s + 4; + } + + if (!EmptyString(s)) + strlcpy(client_p->info, s, sizeof(client_p->info)); + else + strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info)); +} + +static struct Message server_msgtab = { + "SERVER", 0, 0, 4, MAXPARA, MFLG_SLOW, 0, + {mr_server, m_registered, ms_server, m_ignore, m_registered, m_ignore} +}; + +static struct Message sid_msgtab = { + "SID", 0, 0, 5, MAXPARA, MFLG_SLOW, 0, + {rfc1459_command_send_error, m_ignore, ms_sid, m_ignore, m_ignore, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&sid_msgtab); + mod_add_cmd(&server_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&sid_msgtab); + mod_del_cmd(&server_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_CORE +}; diff --git a/modules/core/m_sjoin.c b/modules/core/m_sjoin.c new file mode 100644 index 0000000..72f1bda --- /dev/null +++ b/modules/core/m_sjoin.c @@ -0,0 +1,850 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_sjoin.c: Joins a user to a channel. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "s_serv.h" +#include "conf.h" +#include "s_misc.h" + + +static char modebuf[MODEBUFLEN]; +static char parabuf[MODEBUFLEN]; +static char sendbuf[MODEBUFLEN]; +static const char *para[MAXMODEPARAMS]; +static char *mbuf; +static int pargs; + +static void set_final_mode(struct Mode *, struct Mode *); +static void remove_our_modes(struct Channel *, struct Client *); +static void remove_a_mode(struct Channel *, struct Client *, int, char); +static void remove_ban_list(struct Channel *, struct Client *, dlink_list *, char, int); + + +/* ms_sjoin() + * + * parv[0] - sender + * parv[1] - TS + * parv[2] - channel + * parv[3] - modes + n arguments (key and/or limit) + * parv[4+n] - flags+nick list (all in one parameter) + * + * process a SJOIN, taking the TS's into account to either ignore the + * incoming modes or undo the existing ones or merge them, and JOIN + * all the specified users while sending JOIN/MODEs to local clients + */ +static void +ms_sjoin(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Channel *chptr = NULL; + struct Client *target_p = NULL; + time_t newts; + time_t oldts; + time_t tstosend; + struct Mode mode, *oldmode; + int args = 0; + char keep_our_modes = 1; + char keep_new_modes = 1; + char have_many_nicks = 0; + int lcount; + char nick_prefix[4]; + char uid_prefix[4]; + char *np, *up; + int len_nick = 0; + int len_uid = 0; + int isnew = 0; + int buflen = 0; + int slen; + unsigned int fl; + char *s; + char *sptr; + char nick_buf[IRCD_BUFSIZE]; /* buffer for modes and prefix */ + char uid_buf[IRCD_BUFSIZE]; /* buffer for modes/prefixes for CAP_TS6 servers */ + char *nick_ptr, *uid_ptr; /* pointers used for making the two mode/prefix buffers */ + char *p; /* pointer used making sjbuf */ + dlink_node *m; + const char *servername = (ConfigServerHide.hide_servers || IsHidden(source_p)) ? + me.name : source_p->name; + + if (IsClient(source_p) || parc < 5) + return; + + if (!check_channel_name(parv[2], 0)) + { + sendto_realops_flags(UMODE_DEBUG, L_ALL, + "*** Too long or invalid channel name from %s: %s", + client_p->name, parv[2]); + return; + } + + modebuf[0] = '\0'; + mbuf = modebuf; + pargs = 0; + newts = atol(parv[1]); + + mode.mode = 0; + mode.limit = 0; + mode.key[0] = '\0'; + + for (s = parv[3]; *s; ++s) + { + switch (*s) + { + case 't': + mode.mode |= MODE_TOPICLIMIT; + break; + case 'n': + mode.mode |= MODE_NOPRIVMSGS; + break; + case 's': + mode.mode |= MODE_SECRET; + break; + case 'm': + mode.mode |= MODE_MODERATED; + break; + case 'i': + mode.mode |= MODE_INVITEONLY; + break; + case 'p': + mode.mode |= MODE_PRIVATE; + break; + case 'r': + mode.mode |= MODE_REGISTERED; + break; + case 'O': + mode.mode |= MODE_OPERONLY; + break; + case 'S': + mode.mode |= MODE_SSLONLY; + break; + case 'k': + strlcpy(mode.key, parv[4 + args], sizeof(mode.key)); + args++; + + if (parc < 5 + args) + return; + break; + case 'l': + mode.limit = atoi(parv[4 + args]); + args++; + + if (parc < 5 + args) + return; + break; + } + } + + if ((chptr = hash_find_channel(parv[2])) == NULL) + { + isnew = 1; + chptr = make_channel(parv[2]); + } + + parabuf[0] = '\0'; + oldts = chptr->channelts; + oldmode = &chptr->mode; + + if (ConfigFileEntry.ignore_bogus_ts) + { + if (newts < 800000000) + { + sendto_realops_flags(UMODE_DEBUG, L_ALL, + "*** Bogus TS %lu on %s ignored from %s", + (unsigned long)newts, chptr->chname, + client_p->name); + + newts = (oldts == 0) ? 0 : 800000000; + } + } + else + { + if (!newts && !isnew && oldts) + { + sendto_channel_local(ALL_MEMBERS, 0, chptr, + ":%s NOTICE %s :*** Notice -- TS for %s changed from %lu to 0", + me.name, chptr->chname, chptr->chname, (unsigned long)oldts); + sendto_realops_flags(UMODE_ALL, L_ALL, + "Server %s changing TS on %s from %lu to 0", + source_p->name, chptr->chname, (unsigned long)oldts); + } + } + + if (isnew) + chptr->channelts = tstosend = newts; + else if (newts == 0 || oldts == 0) + chptr->channelts = tstosend = 0; + else if (newts == oldts) + tstosend = oldts; + else if (newts < oldts) + { + keep_our_modes = 0; + chptr->channelts = tstosend = newts; + } + else + { + keep_new_modes = 0; + tstosend = oldts; + } + + if (!keep_new_modes) + mode = *oldmode; + else if (keep_our_modes) + { + mode.mode |= oldmode->mode; + if (oldmode->limit > mode.limit) + mode.limit = oldmode->limit; + if (strcmp(mode.key, oldmode->key) < 0) + strcpy(mode.key, oldmode->key); + } + set_final_mode(&mode, oldmode); + chptr->mode = mode; + + /* Lost the TS, other side wins, so remove modes on this side */ + if (!keep_our_modes) + { + remove_our_modes(chptr, source_p); + + if (chptr->topic[0]) + { + set_channel_topic(chptr, "", "", 0); + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s TOPIC %s :", + (IsHidden(source_p) || + ConfigServerHide.hide_servers) ? + me.name : source_p->name, chptr->chname); + } + + sendto_channel_local(ALL_MEMBERS, 0, chptr, + ":%s NOTICE %s :*** Notice -- TS for %s changed from %lu to %lu", + me.name, chptr->chname, chptr->chname, + (unsigned long)oldts, (unsigned long)newts); + } + + if (*modebuf != '\0') + { + /* This _SHOULD_ be to ALL_MEMBERS + * It contains only +imnpstlk, etc */ + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s %s %s", + servername, chptr->chname, modebuf, parabuf); + } + + if (parv[3][0] != '0' && keep_new_modes) + { + channel_modes(chptr, source_p, modebuf, parabuf); + } + else + { + modebuf[0] = '0'; + modebuf[1] = '\0'; + } + + buflen = ircsprintf(nick_buf, ":%s SJOIN %lu %s %s %s:", + source_p->name, (unsigned long)tstosend, + chptr->chname, modebuf, parabuf); + nick_ptr = nick_buf + buflen; + + buflen = ircsprintf(uid_buf, ":%s SJOIN %lu %s %s %s:", + ID(source_p), (unsigned long)tstosend, + chptr->chname, modebuf, parabuf); + uid_ptr = uid_buf + buflen; + + /* check we can fit a nick on the end, as well as \r\n and a prefix " + * @%+", and a space. + */ + if (buflen >= (IRCD_BUFSIZE - IRCD_MAX(NICKLEN, IDLEN) - 2 - 3 - 1)) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "Long SJOIN from server: %s(via %s) (ignored)", + source_p->name, client_p->name); + return; + } + + mbuf = modebuf; + sendbuf[0] = '\0'; + pargs = 0; + + *mbuf++ = '+'; + + s = parv[args + 4]; + while (*s == ' ') + s++; + if ((p = strchr(s, ' ')) != NULL) + { + *p++ = '\0'; + while (*p == ' ') + p++; + have_many_nicks = *p; + } + + while (*s) + { + int valid_mode = 1; + fl = 0; + + do + { + switch (*s) + { + case '@': + fl |= CHFL_CHANOP; + s++; + break; +#ifdef HALFOPS + case '%': + fl |= CHFL_HALFOP; + s++; + break; +#endif + case '+': + fl |= CHFL_VOICE; + s++; + break; + default: + valid_mode = 0; + break; + } + } while (valid_mode); + + target_p = find_chasing(client_p, source_p, s, NULL); + + /* + * if the client doesnt exist, or if its fake direction/server, skip. + * we cannot send ERR_NOSUCHNICK here because if its a UID, we cannot + * lookup the nick, and its better to never send the numeric than only + * sometimes. + */ + if (target_p == NULL || + target_p->from != client_p || + !IsClient(target_p)) + { + goto nextnick; + } + + len_nick = strlen(target_p->name); + len_uid = strlen(ID(target_p)); + + np = nick_prefix; + up = uid_prefix; + + if (keep_new_modes) + { + if (fl & CHFL_CHANOP) + { + *np++ = '@'; + *up++ = '@'; + len_nick++; + len_uid++; + } +#ifdef HALFOPS + if (fl & CHFL_HALFOP) + { + *np++ = '%'; + *up++ = '%'; + len_nick++; + len_uid++; + } +#endif + if (fl & CHFL_VOICE) + { + *np++ = '+'; + *up++ = '+'; + len_nick++; + len_uid++; + } + } + else + { + if (fl & (CHFL_CHANOP|CHFL_HALFOP)) + fl = CHFL_DEOPPED; + else + fl = 0; + } + *np = *up = '\0'; + + if ((nick_ptr - nick_buf + len_nick) > (IRCD_BUFSIZE - 2)) + { + sendto_server(client_p, 0, CAP_TS6, "%s", nick_buf); + + buflen = ircsprintf(nick_buf, ":%s SJOIN %lu %s %s %s:", + source_p->name, (unsigned long)tstosend, + chptr->chname, modebuf, parabuf); + nick_ptr = nick_buf + buflen; + } + + nick_ptr += ircsprintf(nick_ptr, "%s%s ", nick_prefix, target_p->name); + + if ((uid_ptr - uid_buf + len_uid) > (IRCD_BUFSIZE - 2)) + { + sendto_server(client_p, CAP_TS6, 0, "%s", uid_buf); + + buflen = ircsprintf(uid_buf, ":%s SJOIN %lu %s %s %s:", + ID(source_p), (unsigned long)tstosend, + chptr->chname, modebuf, parabuf); + uid_ptr = uid_buf + buflen; + } + + uid_ptr += ircsprintf(uid_ptr, "%s%s ", uid_prefix, ID(target_p)); + + if (!IsMember(target_p, chptr)) + { + add_user_to_channel(chptr, target_p, fl, !have_many_nicks); + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s JOIN :%s", + target_p->name, target_p->username, + target_p->host, chptr->chname); + } + + if (fl & CHFL_CHANOP) + { + *mbuf++ = 'o'; + para[pargs++] = target_p->name; + + if (pargs >= MAXMODEPARAMS) + { + /* + * Ok, the code is now going to "walk" through + * sendbuf, filling in para strings. So, I will use sptr + * to point into the sendbuf. + * Notice, that ircsprintf() returns the number of chars + * successfully inserted into string. + * - Dianora + */ + + sptr = sendbuf; + *mbuf = '\0'; + for(lcount = 0; lcount < MAXMODEPARAMS; lcount++) + { + slen = ircsprintf(sptr, " %s", para[lcount]); /* see? */ + sptr += slen; /* ready for next */ + } + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s %s%s", + servername, chptr->chname, modebuf, sendbuf); + mbuf = modebuf; + *mbuf++ = '+'; + + sendbuf[0] = '\0'; + pargs = 0; + } + } +#ifdef HALFOPS + if (fl & CHFL_HALFOP) + { + *mbuf++ = 'h'; + para[pargs++] = target_p->name; + + if (pargs >= MAXMODEPARAMS) + { + sptr = sendbuf; + *mbuf = '\0'; + for(lcount = 0; lcount < MAXMODEPARAMS; lcount++) + { + slen = ircsprintf(sptr, " %s", para[lcount]); + sptr += slen; + } + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s %s%s", + servername, chptr->chname, modebuf, sendbuf); + + mbuf = modebuf; + *mbuf++ = '+'; + + sendbuf[0] = '\0'; + pargs = 0; + } + } +#endif + if (fl & CHFL_VOICE) + { + *mbuf++ = 'v'; + para[pargs++] = target_p->name; + + if (pargs >= MAXMODEPARAMS) + { + sptr = sendbuf; + *mbuf = '\0'; + for (lcount = 0; lcount < MAXMODEPARAMS; lcount++) + { + slen = ircsprintf(sptr, " %s", para[lcount]); + sptr += slen; + } + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s %s%s", + servername, chptr->chname, modebuf, sendbuf); + + mbuf = modebuf; + *mbuf++ = '+'; + + sendbuf[0] = '\0'; + pargs = 0; + } + } + + nextnick: + if ((s = p) == NULL) + break; + while (*s == ' ') + s++; + if ((p = strchr(s, ' ')) != NULL) + { + *p++ = 0; + while (*p == ' ') + p++; + } + } + + *mbuf = '\0'; + *(nick_ptr - 1) = '\0'; + *(uid_ptr - 1) = '\0'; + + /* + * checking for lcount < MAXMODEPARAMS at this time is wrong + * since the code has already verified above that pargs < MAXMODEPARAMS + * checking for para[lcount] != '\0' is also wrong, since + * there is no place where para[lcount] is set! + * - Dianora + */ + + if (pargs != 0) + { + sptr = sendbuf; + + for (lcount = 0; lcount < pargs; lcount++) + { + slen = ircsprintf(sptr, " %s", para[lcount]); + sptr += slen; + } + + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s MODE %s %s%s", + servername, chptr->chname, modebuf, sendbuf); + } + + /* If this happens, its the result of a malformed SJOIN + * a remnant from the old persistent channel code. *sigh* + * Or it could be the result of a client just leaving + * and leaving us with a channel formed just as the client parts. + * - Dianora + */ + + if ((dlink_list_length(&chptr->members) == 0) && isnew) + { + destroy_channel(chptr); + return; + } + + if (parv[4 + args][0] == '\0') + return; + + /* relay the SJOIN to other servers */ + DLINK_FOREACH(m, serv_list.head) + { + target_p = m->data; + + if (target_p == client_p) + continue; + + if (IsCapable(target_p, CAP_TS6)) + sendto_one(target_p, "%s", uid_buf); + else + sendto_one(target_p, "%s", nick_buf); + } + + if (HasID(source_p) && !keep_our_modes) + { + if (dlink_list_length(&chptr->banlist) > 0) + remove_ban_list(chptr, client_p, &chptr->banlist, + 'b', NOCAPS); + + if (dlink_list_length(&chptr->exceptlist) > 0) + remove_ban_list(chptr, client_p, &chptr->exceptlist, + 'e', CAP_EX); + + if (dlink_list_length(&chptr->invexlist) > 0) + remove_ban_list(chptr, client_p, &chptr->invexlist, + 'I', CAP_IE); + clear_ban_cache(chptr); + } +} + +/* set_final_mode + * + * inputs - channel mode + * - old channel mode + * output - NONE + * side effects - walk through all the channel modes turning off modes + * that were on in oldmode but aren't on in mode. + * Then walk through turning on modes that are on in mode + * but were not set in oldmode. + */ +static void +set_final_mode(struct Mode *mode, struct Mode *oldmode) +{ + const struct mode_letter *tab; + char *pbuf = parabuf; + int len; + + *mbuf++ = '-'; + + for (tab = chan_modes; tab->letter; ++tab) + { + if ((tab->mode & oldmode->mode) && + !(tab->mode & mode->mode)) + *mbuf++ = tab->letter; + } + + if (oldmode->limit != 0 && mode->limit == 0) + *mbuf++ = 'l'; + + if (oldmode->key[0] && !mode->key[0]) + { + *mbuf++ = 'k'; + len = ircsprintf(pbuf, "%s ", oldmode->key); + pbuf += len; + pargs++; + } + + if (*(mbuf-1) == '-') + *(mbuf-1) = '+'; + else + *mbuf++ = '+'; + + for (tab = chan_modes; tab->letter; ++tab) + { + if ((tab->mode & mode->mode) && + !(tab->mode & oldmode->mode)) + *mbuf++ = tab->letter; + } + + if (mode->limit != 0 && oldmode->limit != mode->limit) + { + *mbuf++ = 'l'; + len = ircsprintf(pbuf, "%d ", mode->limit); + pbuf += len; + pargs++; + } + + if (mode->key[0] && strcmp(oldmode->key, mode->key)) + { + *mbuf++ = 'k'; + len = ircsprintf(pbuf, "%s ", mode->key); + pbuf += len; + pargs++; + } + if (*(mbuf-1) == '+') + *(mbuf-1) = '\0'; + else + *mbuf = '\0'; +} + +/* remove_our_modes() + * + * inputs - pointer to channel to remove modes from + * - client pointer + * output - NONE + * side effects - Go through the local members, remove all their + * chanop modes etc., this side lost the TS. + */ +static void +remove_our_modes(struct Channel *chptr, struct Client *source_p) +{ + remove_a_mode(chptr, source_p, CHFL_CHANOP, 'o'); +#ifdef HALFOPS + remove_a_mode(chptr, source_p, CHFL_HALFOP, 'h'); +#endif + remove_a_mode(chptr, source_p, CHFL_VOICE, 'v'); +} + +/* remove_a_mode() + * + * inputs - pointer to channel + * - server or client removing the mode + * - mask o/h/v mask to be removed + * - flag o/h/v to be removed + * output - NONE + * side effects - remove ONE mode from all members of a channel + */ +static void +remove_a_mode(struct Channel *chptr, struct Client *source_p, + int mask, char flag) +{ + dlink_node *ptr; + struct Membership *ms; + char lmodebuf[MODEBUFLEN]; + char *sp=sendbuf; + const char *lpara[MAXMODEPARAMS]; + int count = 0; + int i; + int l; + + mbuf = lmodebuf; + *mbuf++ = '-'; + *sp = '\0'; + + DLINK_FOREACH(ptr, chptr->members.head) + { + ms = ptr->data; + + if ((ms->flags & mask) == 0) + continue; + + ms->flags &= ~mask; + + lpara[count++] = ms->client_p->name; + + *mbuf++ = flag; + + if (count >= MAXMODEPARAMS) + { + for(i = 0; i < MAXMODEPARAMS; i++) + { + l = ircsprintf(sp, " %s", lpara[i]); + sp += l; + } + + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, 0, chptr, + ":%s MODE %s %s%s", + (IsHidden(source_p) || + ConfigServerHide.hide_servers) ? + me.name : source_p->name, + chptr->chname, lmodebuf, sendbuf); + mbuf = lmodebuf; + *mbuf++ = '-'; + count = 0; + sp = sendbuf; + *sp = '\0'; + } + } + + if (count != 0) + { + *mbuf = '\0'; + for(i = 0; i < count; i++) + { + l = ircsprintf(sp, " %s", lpara[i]); + sp += l; + } + sendto_channel_local(ALL_MEMBERS, 0, chptr, + ":%s MODE %s %s%s", + (IsHidden(source_p) || ConfigServerHide.hide_servers) ? + me.name : source_p->name, + chptr->chname, lmodebuf, sendbuf); + } +} + +/* remove_ban_list() + * + * inputs - channel, source, list to remove, char of mode, caps required + * outputs - none + * side effects - given ban list is removed, modes are sent to local clients and + * non-ts6 servers linked through another uplink other than source_p + */ +static void +remove_ban_list(struct Channel *chptr, struct Client *source_p, + dlink_list *list, char c, int cap) +{ + char lmodebuf[MODEBUFLEN]; + char lparabuf[IRCD_BUFSIZE]; + struct Ban *banptr = NULL; + dlink_node *ptr = NULL; + dlink_node *next_ptr = NULL; + char *pbuf = NULL; + int count = 0; + int cur_len, mlen, plen; + + pbuf = lparabuf; + + cur_len = mlen = ircsprintf(lmodebuf, ":%s MODE %s -", + source_p->name, chptr->chname); + mbuf = lmodebuf + mlen; + + DLINK_FOREACH_SAFE(ptr, next_ptr, list->head) + { + banptr = ptr->data; + + plen = banptr->len + 4; /* another +b and "!@ " */ + if (count >= MAXMODEPARAMS || + (cur_len + 1 /* space between */ + (plen - 1)) > IRCD_BUFSIZE - 2) + { + /* NUL-terminate and remove trailing space */ + *mbuf = *(pbuf - 1) = '\0'; + sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", + lmodebuf, lparabuf); + sendto_server(source_p, cap, CAP_TS6, + "%s %s", lmodebuf, lparabuf); + + cur_len = mlen; + mbuf = lmodebuf + mlen; + pbuf = lparabuf; + count = 0; + } + + *mbuf++ = c; + cur_len += plen; + pbuf += ircsprintf(pbuf, "%s!%s@%s ", banptr->name, banptr->username, + banptr->host); + ++count; + + remove_ban(banptr, list); + } + + *mbuf = *(pbuf - 1) = '\0'; + sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", lmodebuf, lparabuf); + sendto_server(source_p, cap, CAP_TS6, + "%s %s", lmodebuf, lparabuf); +} + +static struct Message sjoin_msgtab = { + "SJOIN", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_ignore, ms_sjoin, m_ignore, m_ignore, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&sjoin_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&sjoin_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_CORE +}; diff --git a/modules/core/m_squit.c b/modules/core/m_squit.c new file mode 100644 index 0000000..0995c47 --- /dev/null +++ b/modules/core/m_squit.c @@ -0,0 +1,184 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_squit.c: Makes a server quit. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "conf.h" +#include "log.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" + + +/* mo_squit - SQUIT message handler + * parv[0] = sender prefix + * parv[1] = server name + * parv[2] = comment + */ +static void +mo_squit(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + struct Client *p; + dlink_node *ptr; + char *comment; + const char *server; + char def_reason[] = "No reason"; + + if (parc < 2 || EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "SQUIT"); + return; + } + + server = parv[1]; + + /* The following allows wild cards in SQUIT. Only + * useful when the command is issued by an oper. + */ + DLINK_FOREACH(ptr, global_serv_list.head) + { + p = ptr->data; + + if (IsServer(p) || IsMe(p)) + { + if (match(server, p->name)) + { + target_p = p; + break; + } + } + } + + if ((target_p == NULL) || IsMe(target_p)) + { + sendto_one(source_p, form_str(ERR_NOSUCHSERVER), + me.name, source_p->name, server); + return; + } + + if (!MyConnect(target_p) && !HasOFlag(source_p, OPER_FLAG_REMOTE)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + + comment = (parc > 2 && parv[2]) ? parv[2] : def_reason; + + if (strlen(comment) > (size_t)REASONLEN) + comment[REASONLEN] = '\0'; + + if (MyConnect(target_p)) + { + sendto_realops_flags(UMODE_ALL, L_ALL, "Received SQUIT %s from %s (%s)", + target_p->name, get_client_name(source_p, HIDE_IP), comment); + ilog(LOG_TYPE_IRCD, "Received SQUIT %s from %s (%s)", + target_p->name, get_client_name(source_p, HIDE_IP), comment); + } + + exit_client(target_p, source_p, comment); +} + +/** NOTE: I removed wildcard lookups here, because a wildcarded + ** SQUIT should/can never happen in ms_squit. -Michael + **/ + +/* ms_squit - SQUIT message handler + * parv[0] = sender prefix + * parv[1] = server name + * parv[2] = comment + */ +static void +ms_squit(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + const char *comment = NULL; + + if (parc < 2 || EmptyString(parv[parc - 1])) + return; + + if ((target_p = hash_find_server(parv[1])) == NULL) + return; + + if (!IsServer(target_p) && !IsMe(target_p)) + return; + + if (IsMe(target_p)) + target_p = client_p; + + comment = (parc > 2 && parv[parc - 1]) ? parv[parc - 1] : client_p->name; + + if (MyConnect(target_p)) + { + sendto_wallops_flags(UMODE_WALLOP, &me, "Remote SQUIT %s from %s (%s)", + target_p->name, source_p->name, comment); + sendto_server(NULL, CAP_TS6, NOCAPS, + ":%s WALLOPS :Remote SQUIT %s from %s (%s)", + me.id, target_p->name, source_p->name, comment); + sendto_server(NULL, NOCAPS, CAP_TS6, + ":%s WALLOPS :Remote SQUIT %s from %s (%s)", + me.name, target_p->name, source_p->name, comment); + ilog(LOG_TYPE_IRCD, "SQUIT From %s : %s (%s)", source_p->name, + target_p->name, comment); + } + + exit_client(target_p, source_p, comment); +} + +static struct Message squit_msgtab = { + "SQUIT", 0, 0, 1, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, ms_squit, m_ignore, mo_squit, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&squit_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&squit_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_CORE +}; diff --git a/modules/m_accept.c b/modules/m_accept.c new file mode 100644 index 0000000..3fff6c1 --- /dev/null +++ b/modules/m_accept.c @@ -0,0 +1,221 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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 + */ + +/*! \file m_accept.c + * \brief Includes required functions for processing the ACCEPT command. + * \version $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "list.h" +#include "numeric.h" +#include "conf.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" + + +/*! \brief Creates and sends a list of nick!user\@host masks a Client + * has on its acceptlist. + * + * \param source_p The actual Client the list will be sent to. + */ +static void +list_accepts(struct Client *source_p) +{ + int len = 0; + char nicks[IRCD_BUFSIZE] = { '\0' }; + char *t = nicks; + const dlink_node *ptr = NULL; + + len = strlen(me.name) + strlen(source_p->name) + 12; + + DLINK_FOREACH(ptr, source_p->localClient->acceptlist.head) + { + const struct split_nuh_item *accept_p = ptr->data; + size_t masklen = strlen(accept_p->nickptr) + + strlen(accept_p->userptr) + + strlen(accept_p->hostptr) + 2 /* !@ */ ; + + if ((t - nicks) + masklen + len > IRCD_BUFSIZE) + { + *(t - 1) = '\0'; + sendto_one(source_p, form_str(RPL_ACCEPTLIST), + me.name, source_p->name, nicks); + t = nicks; + } + + t += ircsprintf(t, "%s!%s@%s ", + accept_p->nickptr, + accept_p->userptr, accept_p->hostptr); + } + + if (nicks[0] != '\0') + { + *(t - 1) = '\0'; + sendto_one(source_p, form_str(RPL_ACCEPTLIST), + me.name, source_p->name, nicks); + } + + sendto_one(source_p, form_str(RPL_ENDOFACCEPT), + me.name, source_p->name); +} + +/*! \brief Allocates and adds a split_nuh_item holding a nick!user\@host + * mask to a Client's acceptlist. + * + * \param nuh A split_nuh_item already prepared with required masks. + * \param source_p The actual Client the new accept is added to. + */ +static void +add_accept(const struct split_nuh_item *nuh, struct Client *source_p) +{ + struct split_nuh_item *accept_p = MyMalloc(sizeof(*accept_p)); + + DupString(accept_p->nickptr, nuh->nickptr); + DupString(accept_p->userptr, nuh->userptr); + DupString(accept_p->hostptr, nuh->hostptr); + + dlinkAdd(accept_p, &accept_p->node, &source_p->localClient->acceptlist); + + list_accepts(source_p); +} + +/*! \brief ACCEPT command handler + * + * \param client_p Pointer to allocated Client struct with physical connection + * to this server, i.e. with an open socket connected. + * \param source_p Pointer to allocated Client struct from which the message + * originally comes from. This can be a local or remote client. + * \param parc Integer holding the number of supplied arguments. + * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL + * pointers. + * \note Valid arguments for this command are: + * - parv[0] = sender prefix + * - parv[1] = list of masks to be accepted or removed (optional) + */ +static void +m_accept(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *mask = NULL; + char *p = NULL; + char nick[NICKLEN + 1]; + char user[USERLEN + 1]; + char host[HOSTLEN + 1]; + struct split_nuh_item nuh; + struct split_nuh_item *accept_p = NULL; + + if (EmptyString(parv[1]) || !irccmp(parv[1], "*")) + { + list_accepts(source_p); + return; + } + + for (mask = strtoken(&p, parv[1], ","); mask != NULL; + mask = strtoken(&p, NULL, ",")) + { + if (*mask == '-' && *++mask != '\0') + { + nuh.nuhmask = mask; + nuh.nickptr = nick; + nuh.userptr = user; + nuh.hostptr = host; + + nuh.nicksize = sizeof(nick); + nuh.usersize = sizeof(user); + nuh.hostsize = sizeof(host); + + split_nuh(&nuh); + + if ((accept_p = find_accept(nick, user, host, source_p, 0)) == NULL) + { + sendto_one(source_p, form_str(ERR_ACCEPTNOT), + me.name, source_p->name, nick, user, host); + continue; + } + + del_accept(accept_p, source_p); + } + else if (*mask != '\0') + { + if (dlink_list_length(&source_p->localClient->acceptlist) >= + ConfigFileEntry.max_accept) + { + sendto_one(source_p, form_str(ERR_ACCEPTFULL), + me.name, source_p->name); + return; + } + + nuh.nuhmask = mask; + nuh.nickptr = nick; + nuh.userptr = user; + nuh.hostptr = host; + + nuh.nicksize = sizeof(nick); + nuh.usersize = sizeof(user); + nuh.hostsize = sizeof(host); + + split_nuh(&nuh); + + if ((accept_p = find_accept(nick, user, host, source_p, 0)) != NULL) + { + sendto_one(source_p, form_str(ERR_ACCEPTEXIST), + me.name, source_p->name, nick, user, host); + continue; + } + + add_accept(&nuh, source_p); + } + } +} + +static struct Message accept_msgtab = { + "ACCEPT", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_accept, m_ignore, m_ignore, m_accept, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&accept_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&accept_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_admin.c b/modules/m_admin.c new file mode 100644 index 0000000..b66f649 --- /dev/null +++ b/modules/m_admin.c @@ -0,0 +1,157 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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 + */ + +/*! \file m_admin.c + * \brief Includes required functions for processing the ADMIN command. + * \version $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "conf.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "irc_string.h" + + + +/*! \brief Sends administrative information about this server. + * + * \param source_p Pointer to client to report to + */ +static void +do_admin(struct Client *source_p) +{ + const char *me_name = ID_or_name(&me, source_p->from); + const char *nick = ID_or_name(source_p, source_p->from); + + sendto_realops_flags(UMODE_SPY, L_ALL, + "ADMIN requested by %s (%s@%s) [%s]", + source_p->name, source_p->username, + source_p->host, source_p->servptr->name); + + sendto_one(source_p, form_str(RPL_ADMINME), + me_name, nick, me.name); + + if (AdminInfo.name != NULL) + sendto_one(source_p, form_str(RPL_ADMINLOC1), + me_name, nick, AdminInfo.name); + if (AdminInfo.description != NULL) + sendto_one(source_p, form_str(RPL_ADMINLOC2), + me_name, nick, AdminInfo.description); + if (AdminInfo.email != NULL) + sendto_one(source_p, form_str(RPL_ADMINEMAIL), + me_name, nick, AdminInfo.email); +} + +/*! \brief NICK command handler (called by already registered, + * locally connected clients) + * + * \param client_p Pointer to allocated Client struct with physical connection + * to this server, i.e. with an open socket connected. + * \param source_p Pointer to allocated Client struct from which the message + * originally comes from. This can be a local or remote client. + * \param parc Integer holding the number of supplied arguments. + * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL + * pointers. + * \note Valid arguments for this command are: + * - parv[0] = sender prefix + * - parv[1] = nickname/servername + */ +static void +m_admin(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + static time_t last_used = 0; + + if ((last_used + ConfigFileEntry.pace_wait_simple) > CurrentTime) + { + sendto_one(source_p,form_str(RPL_LOAD2HI), + me.name, source_p->name); + return; + } + + last_used = CurrentTime; + + if (!ConfigFileEntry.disable_remote) + if (hunt_server(client_p, source_p, ":%s ADMIN :%s", 1, + parc, parv) != HUNTED_ISME) + return; + + do_admin(source_p); +} + +/*! \brief ADMIN command handler (called by operators and + * remotely connected clients) + * + * \param client_p Pointer to allocated Client struct with physical connection + * to this server, i.e. with an open socket connected. + * \param source_p Pointer to allocated Client struct from which the message + * originally comes from. This can be a local or remote client. + * \param parc Integer holding the number of supplied arguments. + * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL + * pointers. + * \note Valid arguments for this command are: + * - parv[0] = sender prefix + * - parv[1] = nickname/servername + */ +static void +ms_admin(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (hunt_server(client_p, source_p, ":%s ADMIN :%s", 1, + parc, parv) != HUNTED_ISME) + return; + + if (IsClient(source_p)) + do_admin(source_p); +} + +static struct Message admin_msgtab = { + "ADMIN", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_admin, ms_admin, m_ignore, ms_admin, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&admin_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&admin_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_away.c b/modules/m_away.c new file mode 100644 index 0000000..700494f --- /dev/null +++ b/modules/m_away.c @@ -0,0 +1,144 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_away.c: Sets/removes away status on a user. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "conf.h" +#include "s_serv.h" +#include "packet.h" +#include "s_user.h" + + +/* + * m_away + * parv[0] = sender prefix + * parv[1] = away message + */ +static void +m_away(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (!IsFloodDone(source_p)) + flood_endgrace(source_p); + + if (parc < 2 || EmptyString(parv[1])) + { + /* Marking as not away */ + if (source_p->away[0]) + { + /* we now send this only if they were away before --is */ + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s AWAY", ID(source_p)); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s AWAY", source_p->name); + source_p->away[0] = '\0'; + } + + sendto_one(source_p, form_str(RPL_UNAWAY), + me.name, source_p->name); + return; + } + + if ((CurrentTime - source_p->localClient->last_away) < ConfigFileEntry.pace_wait) + { + sendto_one(source_p, form_str(RPL_LOAD2HI), + me.name, source_p->name); + return; + } + + source_p->localClient->last_away = CurrentTime; + strlcpy(source_p->away, parv[1], sizeof(source_p->away)); + + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s AWAY :%s", ID(source_p), source_p->away); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s AWAY :%s", source_p->name, source_p->away); + sendto_one(source_p, form_str(RPL_NOWAWAY), me.name, source_p->name); +} + +static void +ms_away(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (!IsClient(source_p)) + return; + + if (parc < 2 || EmptyString(parv[1])) + { + /* Marking as not away */ + if (source_p->away[0]) + { + /* we now send this only if they were away before --is */ + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s AWAY", ID(source_p)); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s AWAY", source_p->name); + source_p->away[0] = '\0'; + } + + return; + } + + strlcpy(source_p->away, parv[1], sizeof(source_p->away)); + + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s AWAY :%s", ID(source_p), source_p->away); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s AWAY :%s", source_p->name, source_p->away); +} + +static struct Message away_msgtab = { + "AWAY", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_away, ms_away, m_ignore, m_away, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&away_msgtab); + add_isupport("AWAYLEN", NULL, AWAYLEN); +} + +static void +module_exit(void) +{ + mod_del_cmd(&away_msgtab); + delete_isupport("AWAYLEN"); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_cap.c b/modules/m_cap.c new file mode 100644 index 0000000..0633da3 --- /dev/null +++ b/modules/m_cap.c @@ -0,0 +1,433 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2004 Kevin L. Mitchell <klmitch@mit.edu> + * Copyright (C) 2006-2012 Hybrid 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 + * + * $Id$ + */ + +/** @file + * @brief Capability negotiation commands + * @version $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "hash.h" +#include "ircd.h" +#include "numeric.h" +#include "conf.h" +#include "s_user.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "packet.h" +#include "irc_string.h" + + +#define CAPFL_HIDDEN 0x0001 /**< Do not advertize this capability */ +#define CAPFL_PROHIBIT 0x0002 /**< Client may not set this capability */ +#define CAPFL_PROTO 0x0004 /**< Cap must be acknowledged by client */ +#define CAPFL_STICKY 0x0008 /**< Cap may not be cleared once set */ + +typedef int (*bqcmp)(const void *, const void *); + +static struct capabilities +{ + unsigned int cap; + unsigned int flags; + const char *name; + size_t namelen; +} capab_list[] = { +#define _CAP(cap, flags, name) \ + { (cap), (flags), (name), sizeof(name) - 1 } + _CAP(CAP_MULTI_PREFIX, 0, "multi-prefix") +#undef _CAP +}; + +#define CAPAB_LIST_LEN (sizeof(capab_list) / sizeof(struct capabilities)) + +static int +capab_sort(const struct capabilities *cap1, const struct capabilities *cap2) +{ + return strcasecmp(cap1->name, cap2->name); +} + +static int +capab_search(const char *key, const struct capabilities *cap) +{ + const char *rb = cap->name; + + while (ToLower(*key) == ToLower(*rb)) /* walk equivalent part of strings */ + if (*key++ == '\0') /* hit the end, all right... */ + return 0; + else /* OK, let's move on... */ + rb++; + + /* + * If the character they differ on happens to be a space, and it happens + * to be the same length as the capability name, then we've found a + * match; otherwise, return the difference of the two. + */ + return (IsSpace(*key) && *rb == '\0') ? 0 : (ToLower(*key) - ToLower(*rb)); +} + +static struct capabilities * +find_cap(const char **caplist_p, int *neg_p) +{ + static int inited = 0; + const char *caplist = *caplist_p; + struct capabilities *cap = NULL; + + *neg_p = 0; /* clear negative flag... */ + + if (!inited) + { + /* First, let's sort the array... */ + qsort(capab_list, CAPAB_LIST_LEN, sizeof(struct capabilities), (bqcmp)capab_sort); + ++inited; + } + + /* Next, find first non-whitespace character... */ + while (*caplist && IsSpace(*caplist)) + ++caplist; + + /* We are now at the beginning of an element of the list; is it negative? */ + if (*caplist == '-') + { + ++caplist; /* yes; step past the flag... */ + *neg_p = 1; /* remember that it is negative... */ + } + + /* OK, now see if we can look up the capability... */ + if (*caplist) + { + if (!(cap = bsearch(caplist, capab_list, CAPAB_LIST_LEN, + sizeof(struct capabilities), + (bqcmp)capab_search))) + { + /* Couldn't find the capability; advance to first whitespace character */ + while (*caplist && !IsSpace(*caplist)) + ++caplist; + } + else + caplist += cap->namelen; /* advance to end of capability name */ + } + + assert(caplist != *caplist_p || !*caplist); /* we *must* advance */ + + /* move ahead in capability list string--or zero pointer if we hit end */ + *caplist_p = *caplist ? caplist : 0; + + return cap; /* and return the capability (if any) */ +} + +/** Send a CAP \a subcmd list of capability changes to \a source_p. + * If more than one line is necessary, each line before the last has + * an added "*" parameter before that line's capability list. + * @param[in] source_p Client receiving capability list. + * @param[in] set Capabilities to show as set (with ack and sticky modifiers). + * @param[in] rem Capabalities to show as removed (with no other modifier). + * @param[in] subcmd Name of capability subcommand. + */ +static int +send_caplist(struct Client *source_p, unsigned int set, + unsigned int rem, const char *subcmd) +{ + char capbuf[IRCD_BUFSIZE] = "", pfx[16]; + char cmdbuf[IRCD_BUFSIZE] = ""; + unsigned int i, loc, len, flags, pfx_len, clen; + + /* set up the buffer for the final LS message... */ + clen = snprintf(cmdbuf, sizeof(capbuf), ":%s CAP %s %s ", me.name, + source_p->name[0] ? source_p->name : "*", subcmd); + + for (i = 0, loc = 0; i < CAPAB_LIST_LEN; ++i) + { + flags = capab_list[i].flags; + + /* + * This is a little bit subtle, but just involves applying de + * Morgan's laws to the obvious check: We must display the + * capability if (and only if) it is set in \a rem or \a set, or + * if both are null and the capability is hidden. + */ + if (!(rem && (rem & capab_list[i].cap)) && + !(set && (set & capab_list[i].cap)) && + (rem || set || (flags & CAPFL_HIDDEN))) + continue; + + /* Build the prefix (space separator and any modifiers needed). */ + pfx_len = 0; + + if (loc) + pfx[pfx_len++] = ' '; + if (rem && (rem & capab_list[i].cap)) + pfx[pfx_len++] = '-'; + else + { + if (flags & CAPFL_PROTO) + pfx[pfx_len++] = '~'; + if (flags & CAPFL_STICKY) + pfx[pfx_len++] = '='; + } + + pfx[pfx_len] = '\0'; + + len = capab_list[i].namelen + pfx_len; /* how much we'd add... */ + + if (sizeof(capbuf) < (clen + loc + len + 15)) + { + /* would add too much; must flush */ + sendto_one(source_p, "%s* :%s", cmdbuf, capbuf); + capbuf[(loc = 0)] = '\0'; /* re-terminate the buffer... */ + } + + loc += snprintf(capbuf + loc, sizeof(capbuf) - loc, + "%s%s", pfx, capab_list[i].name); + } + + sendto_one(source_p, "%s:%s", cmdbuf, capbuf); + + return 0; /* convenience return */ +} + +static int +cap_ls(struct Client *source_p, const char *caplist) +{ + if (IsUnknown(source_p)) /* registration hasn't completed; suspend it... */ + source_p->localClient->registration |= REG_NEED_CAP; + + return send_caplist(source_p, 0, 0, "LS"); /* send list of capabilities */ +} + +static int +cap_req(struct Client *source_p, const char *caplist) +{ + const char *cl = caplist; + struct capabilities *cap = NULL; + unsigned int set = 0, rem = 0; + unsigned int cs = source_p->localClient->cap_client; /* capability set */ + unsigned int as = source_p->localClient->cap_active; /* active set */ + int neg = 0; + + if (IsUnknown(source_p)) /* registration hasn't completed; suspend it... */ + source_p->localClient->registration |= REG_NEED_CAP; + + while (cl) { /* walk through the capabilities list... */ + if (!(cap = find_cap(&cl, &neg)) /* look up capability... */ + || (!neg && (cap->flags & CAPFL_PROHIBIT)) /* is it prohibited? */ + || (neg && (cap->flags & CAPFL_STICKY))) { /* is it sticky? */ + sendto_one(source_p, ":%s CAP %s NAK :%s", me.name, + source_p->name[0] ? source_p->name : "*", caplist); + return 0; /* can't complete requested op... */ + } + + if (neg) + { + /* set or clear the capability... */ + rem |= cap->cap; + set &= ~cap->cap; + cs &= ~cap->cap; + + if (!(cap->flags & CAPFL_PROTO)) + as &= ~cap->cap; + } + else + { + rem &= ~cap->cap; + set |= cap->cap; + cs |= cap->cap; + + if (!(cap->flags & CAPFL_PROTO)) + as |= cap->cap; + } + } + + /* Notify client of accepted changes and copy over results. */ + send_caplist(source_p, set, rem, "ACK"); + + source_p->localClient->cap_client = cs; + source_p->localClient->cap_active = as; + + return 0; +} + +static int +cap_ack(struct Client *source_p, const char *caplist) +{ + const char *cl = caplist; + struct capabilities *cap = NULL; + int neg = 0; + + /* + * Coming from the client, this generally indicates that the client + * is using a new backwards-incompatible protocol feature. As such, + * it does not require further response from the server. + */ + while (cl) + { + /* walk through the capabilities list... */ + if (!(cap = find_cap(&cl, &neg)) || /* look up capability... */ + (neg ? (source_p->localClient->cap_active & cap->cap) : + !(source_p->localClient->cap_active & cap->cap))) /* uh... */ + continue; + + if (neg) /* set or clear the active capability... */ + source_p->localClient->cap_active &= ~cap->cap; + else + source_p->localClient->cap_active |= cap->cap; + } + + return 0; +} + +static int +cap_clear(struct Client *source_p, const char *caplist) +{ + struct capabilities *cap = NULL; + unsigned int ii; + unsigned int cleared = 0; + + for (ii = 0; ii < CAPAB_LIST_LEN; ++ii) + { + cap = &capab_list[ii]; + + /* Only clear active non-sticky capabilities. */ + if (!(source_p->localClient->cap_active & cap->cap) || (cap->flags & CAPFL_STICKY)) + continue; + + cleared |= cap->cap; + source_p->localClient->cap_client &= ~cap->cap; + + if (!(cap->flags & CAPFL_PROTO)) + source_p->localClient->cap_active &= ~cap->cap; + } + + return send_caplist(source_p, 0, cleared, "ACK"); +} + +static int +cap_end(struct Client *source_p, const char *caplist) +{ + if (!IsUnknown(source_p)) /* registration has completed... */ + return 0; /* so just ignore the message... */ + + /* capability negotiation is now done... */ + source_p->localClient->registration &= ~REG_NEED_CAP; + + /* if client is now done... */ + if (!source_p->localClient->registration) + { + register_local_user(source_p); + return 0; + } + + return 0; /* Can't do registration yet... */ +} + +static int +cap_list(struct Client *source_p, const char *caplist) +{ + /* Send the list of the client's capabilities */ + return send_caplist(source_p, source_p->localClient->cap_client, 0, "LIST"); +} + +static struct subcmd +{ + const char *cmd; + int (*proc)(struct Client *, const char *); +} cmdlist[] = { + { "ACK", cap_ack }, + { "CLEAR", cap_clear }, + { "END", cap_end }, + { "LIST", cap_list }, + { "LS", cap_ls }, + { "NAK", NULL }, + { "REQ", cap_req } +}; + +static int +subcmd_search(const char *cmd, const struct subcmd *elem) +{ + return strcasecmp(cmd, elem->cmd); +} + +/** Handle a capability request or response from a client. + * \param client_p Client that sent us the message. + * \param source_p Original source of message. + * \param parc Number of arguments. + * \param parv Argument vector. + */ +static void +m_cap(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) +{ + const char *subcmd = NULL, *caplist = NULL; + struct subcmd *cmd = NULL; + + if (EmptyString(parv[1])) /* a subcommand is required */ + return; + + subcmd = parv[1]; + + if (parc > 2) /* a capability list was provided */ + caplist = parv[2]; + + /* find the subcommand handler */ + if (!(cmd = bsearch(subcmd, cmdlist, + sizeof(cmdlist) / sizeof(struct subcmd), + sizeof(struct subcmd), (bqcmp)subcmd_search))) + { + sendto_one(source_p, form_str(ERR_INVALIDCAPCMD), me.name, + source_p->name[0] ? source_p->name : "*", subcmd); + return; + } + + /* then execute it... */ + if (cmd->proc) + (cmd->proc)(source_p, caplist); +} + +static struct Message cap_msgtab = { + "CAP", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_cap, m_cap, m_ignore, m_ignore, m_cap, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&cap_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&cap_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_capab.c b/modules/m_capab.c new file mode 100644 index 0000000..7714ce2 --- /dev/null +++ b/modules/m_capab.c @@ -0,0 +1,89 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_capab.c: Negotiates capabilities with a remote server. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "irc_string.h" +#include "s_serv.h" +#include "conf.h" +#include "parse.h" +#include "modules.h" + + +/* + * mr_capab - CAPAB message handler + * parv[0] = sender prefix + * parv[1] = space-separated list of capabilities + * + */ +static void +mr_capab(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + int i; + int cap; + char *p = NULL; + char *s = NULL; + + if (client_p->localClient->caps && !(IsCapable(client_p, CAP_TS6))) + { + exit_client(client_p, client_p, "CAPAB received twice"); + return; + } + + SetCapable(client_p, CAP_CAP); + + for (i = 1; i < parc; ++i) + for (s = strtoken(&p, parv[i], " "); s; + s = strtoken(&p, NULL, " ")) + if ((cap = find_capability(s))) + SetCapable(client_p, cap); +} + +static struct Message capab_msgtab = { + "CAPAB", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { mr_capab, m_ignore, m_ignore, m_ignore, m_ignore, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&capab_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&capab_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_challenge.c b/modules/m_challenge.c new file mode 100644 index 0000000..4c24b3a --- /dev/null +++ b/modules/m_challenge.c @@ -0,0 +1,207 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_challenge.c: Allows an IRC Operator to securely authenticate. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "modules.h" +#include "numeric.h" +#include "send.h" +#include "conf.h" +#include "rsa.h" +#include "parse.h" +#include "irc_string.h" +#include "log.h" +#include "s_user.h" + + +#ifdef HAVE_LIBCRYPTO +/* failed_challenge_notice() + * + * inputs - pointer to client doing /oper ... + * - pointer to nick they tried to oper as + * - pointer to reason they have failed + * output - nothing + * side effects - notices all opers of the failed oper attempt if enabled + */ +static void +failed_challenge_notice(struct Client *source_p, const char *name, + const char *reason) +{ + if (ConfigFileEntry.failed_oper_notice) + sendto_realops_flags(UMODE_ALL, L_ALL, "Failed CHALLENGE attempt as %s " + "by %s (%s@%s) - %s", name, source_p->name, + source_p->username, source_p->host, reason); + + ilog(LOG_TYPE_OPER, "Failed CHALLENGE attempt as %s " + "by %s (%s@%s) - %s", name, source_p->name, + source_p->username, source_p->host, reason); +} + +/* + * m_challenge - generate RSA challenge for wouldbe oper + * parv[0] = sender prefix + * parv[1] = operator to challenge for, or +response + * + */ +static void +m_challenge(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *challenge = NULL; + struct ConfItem *conf = NULL; + struct AccessItem *aconf = NULL; + + if (*parv[1] == '+') + { + /* Ignore it if we aren't expecting this... -A1kmm */ + if (source_p->localClient->response == NULL) + return; + + if (irccmp(source_p->localClient->response, ++parv[1])) + { + sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, + source_p->name); + failed_challenge_notice(source_p, source_p->localClient->auth_oper, + "challenge failed"); + return; + } + + conf = find_exact_name_conf(OPER_TYPE, source_p, + source_p->localClient->auth_oper, NULL, NULL); + if (conf == NULL) + { + /* XXX: logging */ + sendto_one (source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name); + return; + } + + if (attach_conf(source_p, conf) != 0) + { + sendto_one(source_p,":%s NOTICE %s :Can't attach conf!", + me.name, source_p->name); + failed_challenge_notice(source_p, conf->name, "can't attach conf!"); + return; + } + + oper_up(source_p); + + ilog(LOG_TYPE_OPER, "OPER %s by %s!%s@%s", + source_p->localClient->auth_oper, source_p->name, source_p->username, + source_p->host); + + MyFree(source_p->localClient->response); + MyFree(source_p->localClient->auth_oper); + source_p->localClient->response = NULL; + source_p->localClient->auth_oper = NULL; + return; + } + + MyFree(source_p->localClient->response); + MyFree(source_p->localClient->auth_oper); + source_p->localClient->response = NULL; + source_p->localClient->auth_oper = NULL; + + if ((conf = find_conf_exact(OPER_TYPE, + parv[1], source_p->username, source_p->host + )) != NULL) + aconf = map_to_conf(conf); + else if ((conf = find_conf_exact(OPER_TYPE, + parv[1], source_p->username, + source_p->sockhost)) != NULL) + aconf = map_to_conf(conf); + + if (aconf == NULL) + { + sendto_one (source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name); + conf = find_exact_name_conf(OPER_TYPE, NULL, parv[1], NULL, NULL); + failed_challenge_notice(source_p, parv[1], (conf != NULL) + ? "host mismatch" : "no oper {} block"); + return; + } + + if (aconf->rsa_public_key == NULL) + { + sendto_one (source_p, ":%s NOTICE %s :I'm sorry, PK authentication " + "is not enabled for your oper{} block.", me.name, + source_p->name); + return; + } + + if (!generate_challenge(&challenge, &(source_p->localClient->response), + aconf->rsa_public_key)) + sendto_one(source_p, form_str(RPL_RSACHALLENGE), + me.name, source_p->name, challenge); + + DupString(source_p->localClient->auth_oper, conf->name); + MyFree(challenge); +} + +static void +mo_challenge(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + sendto_one(source_p, form_str(RPL_YOUREOPER), + me.name, source_p->name); +} + +static struct Message challenge_msgtab = { + "CHALLENGE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_challenge, m_ignore, m_ignore, mo_challenge, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&challenge_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&challenge_msgtab); +} + +#else + +static void +module_init(void) +{ +} + +static void +module_exit(void) +{ +} +#endif + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_close.c b/modules/m_close.c new file mode 100644 index 0000000..4395935 --- /dev/null +++ b/modules/m_close.c @@ -0,0 +1,90 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_close.c: Closes all unregistered connections. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "parse.h" +#include "modules.h" + + +/* + * mo_close - CLOSE message handler + * - added by Darren Reed Jul 13 1992. + */ +static void +mo_close(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + dlink_node *ptr = NULL, *ptr_next = NULL; + unsigned int closed = dlink_list_length(&unknown_list); + + + DLINK_FOREACH_SAFE(ptr, ptr_next, unknown_list.head) + { + struct Client *target_p = ptr->data; + + sendto_one(source_p, form_str(RPL_CLOSING), me.name, source_p->name, + get_client_name(target_p, SHOW_IP), target_p->status); + + /* + * exit here is safe, because it is guaranteed not to be source_p + * because it is unregistered and source_p is an oper. + */ + exit_client(target_p, target_p, "Oper Closing"); + } + + sendto_one(source_p, form_str(RPL_CLOSEEND), + me.name, source_p->name, closed); +} + +static struct Message close_msgtab = { + "CLOSE", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_close, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&close_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&close_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_connect.c b/modules/m_connect.c new file mode 100644 index 0000000..10870e1 --- /dev/null +++ b/modules/m_connect.c @@ -0,0 +1,322 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_connect.c: Connects to a remote IRC server. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "irc_string.h" +#include "numeric.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "conf.h" +#include "log.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "hash.h" +#include "modules.h" + + +/* + * mo_connect - CONNECT command handler + * + * Added by Jto 11 Feb 1989 + * + * m_connect + * parv[0] = sender prefix + * parv[1] = servername + * parv[2] = port number + * parv[3] = remote server + */ +static void +mo_connect(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + int port; + int tmpport; + struct ConfItem *conf = NULL; + struct AccessItem *aconf = NULL; + const struct Client *target_p = NULL; + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "CONNECT"); + return; + } + + if (parc > 3) + { + if (!HasOFlag(source_p, OPER_FLAG_REMOTE)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "connect"); + return; + } + + if (hunt_server(client_p, source_p, ":%s CONNECT %s %s :%s", 3, + parc, parv) != HUNTED_ISME) + return; + } + + if ((target_p = hash_find_server(parv[1]))) + { + sendto_one(source_p, + ":%s NOTICE %s :Connect: Server %s already exists from %s.", + me.name, source_p->name, parv[1], target_p->from->name); + return; + } + + /* + * try to find the name, then host, if both fail notify ops and bail + */ + if ((conf = find_matching_name_conf(SERVER_TYPE, + parv[1], NULL, NULL, 0)) != NULL) + aconf = (struct AccessItem *)map_to_conf(conf); + else if ((conf = find_matching_name_conf(SERVER_TYPE, + NULL, NULL, parv[1], 0)) != NULL) + aconf = (struct AccessItem *)map_to_conf(conf); + + if (conf == NULL || aconf == NULL) + { + sendto_one(source_p, + ":%s NOTICE %s :Connect: Host %s not listed in ircd.conf", + me.name, source_p->name, parv[1]); + return; + } + + /* Get port number from user, if given. If not specified, + * use the default form configuration structure. If missing + * from there, then use the precompiled default. + */ + tmpport = port = aconf->port; + + if (parc > 2 && !EmptyString(parv[2])) + { + if ((port = atoi(parv[2])) <= 0) + { + sendto_one(source_p, ":%s NOTICE %s :Connect: Illegal port number", + me.name, source_p->name); + return; + } + } + else if (port <= 0 && (port = PORTNUM) <= 0) + { + sendto_one(source_p, ":%s NOTICE %s :Connect: missing port number", + me.name, source_p->name); + return; + } + + if (find_servconn_in_progress(conf->name)) + { + sendto_one(source_p, ":%s NOTICE %s :Connect: a connection to %s " + "is already in progress.", me.name, source_p->name, conf->name); + return; + } + + /* + * Notify all operators about remote connect requests + */ + ilog(LOG_TYPE_IRCD, "CONNECT From %s : %s %s", + source_p->name, parv[1], parv[2] ? parv[2] : ""); + + aconf->port = port; + + /* at this point we should be calling connect_server with a valid + * C:line and a valid port in the C:line + */ + if (serv_connect(aconf, source_p)) + { + if (!ConfigServerHide.hide_server_ips && HasUMode(source_p, UMODE_ADMIN)) + sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s[%s].%d", + me.name, source_p->name, aconf->host, + conf->name, aconf->port); + else + sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s.%d", + me.name, source_p->name, conf->name, aconf->port); + } + else + { + sendto_one(source_p, ":%s NOTICE %s :*** Couldn't connect to %s.%d", + me.name, source_p->name, conf->name, aconf->port); + } + + /* client is either connecting with all the data it needs or has been + * destroyed + */ + aconf->port = tmpport; +} + +/* + * ms_connect - CONNECT command handler + * + * Added by Jto 11 Feb 1989 + * + * m_connect + * parv[0] = sender prefix + * parv[1] = servername + * parv[2] = port number + * parv[3] = remote server + */ +static void +ms_connect(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + int port; + int tmpport; + struct ConfItem *conf = NULL; + struct AccessItem *aconf = NULL; + const struct Client *target_p = NULL; + + if (hunt_server(client_p, source_p, + ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME) + return; + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "CONNECT"); + return; + } + + if ((target_p = hash_find_server(parv[1]))) + { + sendto_one(source_p, + ":%s NOTICE %s :Connect: Server %s already exists from %s.", + me.name, source_p->name, parv[1], target_p->from->name); + return; + } + + /* + * try to find the name, then host, if both fail notify ops and bail + */ + if ((conf = find_matching_name_conf(SERVER_TYPE, + parv[1], NULL, NULL, 0)) != NULL) + aconf = map_to_conf(conf); + else if ((conf = find_matching_name_conf(SERVER_TYPE, + NULL, NULL, parv[1], 0)) != NULL) + aconf = map_to_conf(conf); + + if (conf == NULL || aconf == NULL) + { + sendto_one(source_p, + ":%s NOTICE %s :Connect: Host %s not listed in ircd.conf", + me.name, source_p->name, parv[1]); + return; + } + + /* Get port number from user, if given. If not specified, + * use the default form configuration structure. If missing + * from there, then use the precompiled default. + */ + tmpport = port = aconf->port; + + if (parc > 2 && !EmptyString(parv[2])) + { + port = atoi(parv[2]); + + /* if someone sends port 0, and we have a config port.. use it */ + if (port == 0 && aconf->port) + port = aconf->port; + else if (port <= 0) + { + sendto_one(source_p, ":%s NOTICE %s :Connect: Illegal port number", + me.name, source_p->name); + return; + } + } + else if (port <= 0 && (port = PORTNUM) <= 0) + { + sendto_one(source_p, ":%s NOTICE %s :Connect: missing port number", + me.name, source_p->name); + return; + } + + if (find_servconn_in_progress(conf->name)) + { + sendto_one(source_p, ":%s NOTICE %s :Connect: a connection to %s " + "is already in progress.", me.name, source_p->name, conf->name); + return; + } + + /* + * Notify all operators about remote connect requests + */ + sendto_wallops_flags(UMODE_WALLOP, &me, "Remote CONNECT %s %d from %s", + parv[1], port, source_p->name); + sendto_server(NULL, NOCAPS, CAP_TS6, + ":%s WALLOPS :Remote CONNECT %s %d from %s", + me.name, parv[1], port, source_p->name); + sendto_server(NULL, CAP_TS6, NOCAPS, + ":%s WALLOPS :Remote CONNECT %s %d from %s", + me.id, parv[1], port, source_p->name); + + ilog(LOG_TYPE_IRCD, "CONNECT From %s : %s %d", + source_p->name, parv[1], port); + + aconf->port = port; + + /* + * At this point we should be calling connect_server with a valid + * C:line and a valid port in the C:line + */ + if (serv_connect(aconf, source_p)) + sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s.%d", + me.name, source_p->name, conf->name, aconf->port); + else + sendto_one(source_p, ":%s NOTICE %s :*** Couldn't connect to %s.%d", + me.name, source_p->name, conf->name, aconf->port); + /* + * Client is either connecting with all the data it needs or has been + * destroyed + */ + aconf->port = tmpport; +} + +static struct Message connect_msgtab = { + "CONNECT", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, ms_connect, m_ignore, mo_connect, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&connect_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&connect_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_dline.c b/modules/m_dline.c new file mode 100644 index 0000000..182489b --- /dev/null +++ b/modules/m_dline.c @@ -0,0 +1,592 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_dline.c: Bans a user. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "client.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "hostmask.h" +#include "numeric.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "conf.h" +#include "log.h" +#include "s_misc.h" +#include "send.h" +#include "hash.h" +#include "s_serv.h" +#include "s_gline.h" +#include "parse.h" +#include "modules.h" + + +/* apply_tdline() + * + * inputs - + * output - NONE + * side effects - tkline as given is placed + */ +static void +apply_tdline(struct Client *source_p, struct ConfItem *conf, + const char *current_date, int tkline_time) +{ + struct AccessItem *aconf; + + aconf = map_to_conf(conf); + aconf->hold = CurrentTime + tkline_time; + SetConfTemporary(aconf); + add_conf_by_address(CONF_DLINE, aconf); + + + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s added temporary %d min. D-Line for [%s] [%s]", + get_oper_name(source_p), tkline_time/60, + aconf->host, aconf->reason); + + sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. D-Line [%s]", + MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from), + source_p->name, tkline_time/60, aconf->host); + ilog(LOG_TYPE_DLINE, "%s added temporary %d min. D-Line for [%s] [%s]", + source_p->name, tkline_time/60, aconf->host, aconf->reason); + + rehashed_klines = 1; +} + +/* static int remove_tdline_match(const char *host, const char *user) + * Input: An ip to undline. + * Output: returns YES on success, NO if no tdline removed. + * Side effects: Any matching tdlines are removed. + */ +static int +remove_tdline_match(const char *host) +{ + struct irc_ssaddr iphost, *piphost; + struct AccessItem *aconf; + int t; + + if ((t = parse_netmask(host, &iphost, NULL)) != HM_HOST) + { +#ifdef IPV6 + if (t == HM_IPV6) + t = AF_INET6; + else +#endif + t = AF_INET; + piphost = &iphost; + } + else + { + t = 0; + piphost = NULL; + } + + if ((aconf = find_conf_by_address(host, piphost, CONF_DLINE, t, NULL, NULL, 0))) + { + if (IsConfTemporary(aconf)) + { + delete_one_address_conf(host, aconf); + return 1; + } + } + + return 0; +} + +/* mo_dline() + * + * inputs - pointer to server + * - pointer to client + * - parameter count + * - parameter list + * output - + * side effects - D line is added + * + */ +static void +mo_dline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char def_reason[] = "<No reason specified>"; + char *dlhost = NULL, *oper_reason = NULL, *reason = NULL; + char *target_server = NULL; + const char *creason; + const struct Client *target_p = NULL; + struct irc_ssaddr daddr; + struct ConfItem *conf=NULL; + struct AccessItem *aconf=NULL; + time_t tkline_time=0; + int bits, t; + const char *current_date = NULL; + time_t cur_time; + char hostip[HOSTIPLEN + 1]; + char buffer[IRCD_BUFSIZE]; + + if (!HasOFlag(source_p, OPER_FLAG_DLINE)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "dline"); + return; + } + + if (parse_aline("DLINE", source_p, parc, parv, AWILD, &dlhost, + NULL, &tkline_time, &target_server, &reason) < 0) + return; + + if (target_server != NULL) + { + if (HasID(source_p)) + { + sendto_server(NULL, CAP_DLN|CAP_TS6, NOCAPS, + ":%s DLINE %s %lu %s :%s", + source_p->id, target_server, (unsigned long)tkline_time, + dlhost, reason); + sendto_server(NULL, CAP_DLN, CAP_TS6, + ":%s DLINE %s %lu %s :%s", + source_p->name, target_server, (unsigned long)tkline_time, + dlhost, reason); + } + else + sendto_server(NULL, CAP_DLN, NOCAPS, + ":%s DLINE %s %lu %s :%s", + source_p->name, target_server, (unsigned long)tkline_time, + dlhost, reason); + + /* Allow ON to apply local kline as well if it matches */ + if (!match(target_server, me.name)) + return; + } + else + cluster_a_line(source_p, "DLINE", CAP_DLN, SHARED_DLINE, + "%d %s :%s", tkline_time, dlhost, reason); + + if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST) + { + if ((target_p = find_chasing(client_p, source_p, dlhost, NULL)) == NULL) + return; + + if (!MyConnect(target_p)) + { + sendto_one(source_p, + ":%s NOTICE %s :Can't DLINE nick on another server", + me.name, source_p->name); + return; + } + + if (IsExemptKline(target_p)) + { + sendto_one(source_p, + ":%s NOTICE %s :%s is E-lined", me.name, + source_p->name, target_p->name); + return; + } + + getnameinfo((struct sockaddr *)&target_p->localClient->ip, + target_p->localClient->ip.ss_len, hostip, + sizeof(hostip), NULL, 0, NI_NUMERICHOST); + dlhost = hostip; + t = parse_netmask(dlhost, NULL, &bits); + assert(t == HM_IPV4 || t == HM_IPV6); + } + + if (bits < 8) + { + sendto_one(source_p, + ":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.", + me.name, source_p->name); + return; + } + +#ifdef IPV6 + if (t == HM_IPV6) + t = AF_INET6; + else +#endif + t = AF_INET; + + parse_netmask(dlhost, &daddr, NULL); + + if ((aconf = find_dline_conf(&daddr, t)) != NULL) + { + creason = aconf->reason ? aconf->reason : def_reason; + if (IsConfExemptKline(aconf)) + sendto_one(source_p, + ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s", + me.name, source_p->name, dlhost, aconf->host, creason); + else + sendto_one(source_p, + ":%s NOTICE %s :[%s] already D-lined by [%s] - %s", + me.name, source_p->name, dlhost, aconf->host, creason); + return; + } + + cur_time = CurrentTime; + current_date = smalldate(cur_time); + + /* Look for an oper reason */ + if ((oper_reason = strchr(reason, '|')) != NULL) + *oper_reason++ = '\0'; + + if (!valid_comment(source_p, reason, 1)) + return; + + conf = make_conf_item(DLINE_TYPE); + aconf = map_to_conf(conf); + DupString(aconf->host, dlhost); + + if (tkline_time != 0) + { + snprintf(buffer, sizeof(buffer), "Temporary D-line %d min. - %s (%s)", + (int)(tkline_time/60), reason, current_date); + DupString(aconf->reason, buffer); + if (oper_reason != NULL) + DupString(aconf->oper_reason, oper_reason); + apply_tdline(source_p, conf, current_date, tkline_time); + } + else + { + snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date); + DupString(aconf->reason, buffer); + if (oper_reason != NULL) + DupString(aconf->oper_reason, oper_reason); + add_conf_by_address(CONF_DLINE, aconf); + write_conf_line(source_p, conf, current_date, cur_time); + } + + rehashed_klines = 1; +} + +static void +ms_dline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char def_reason[] = "<No reason specified>"; + char *dlhost, *oper_reason, *reason; + const char *creason; + const struct Client *target_p = NULL; + struct irc_ssaddr daddr; + struct ConfItem *conf=NULL; + struct AccessItem *aconf=NULL; + time_t tkline_time=0; + int bits, t; + const char *current_date = NULL; + time_t cur_time; + char hostip[HOSTIPLEN + 1]; + char buffer[IRCD_BUFSIZE]; + + if (parc != 5 || EmptyString(parv[4])) + return; + + /* parv[0] parv[1] parv[2] parv[3] parv[4] */ + /* oper target_server tkline_time host reason */ + sendto_match_servs(source_p, parv[1], CAP_DLN, + "DLINE %s %s %s :%s", + parv[1], parv[2], parv[3], parv[4]); + + if (!match(parv[1], me.name)) + return; + + tkline_time = valid_tkline(parv[2], TK_SECONDS); + dlhost = parv[3]; + reason = parv[4]; + + if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(ULINE_TYPE, source_p->servptr->name, + source_p->username, source_p->host, + SHARED_DLINE)) + { + if (!IsClient(source_p)) + return; + if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST) + { + if ((target_p = find_chasing(client_p, source_p, dlhost, NULL)) == NULL) + return; + + if (!MyConnect(target_p)) + { + sendto_one(source_p, + ":%s NOTICE %s :Can't DLINE nick on another server", + me.name, source_p->name); + return; + } + + if (IsExemptKline(target_p)) + { + sendto_one(source_p, + ":%s NOTICE %s :%s is E-lined", me.name, + source_p->name, target_p->name); + return; + } + + getnameinfo((struct sockaddr *)&target_p->localClient->ip, + target_p->localClient->ip.ss_len, hostip, + sizeof(hostip), NULL, 0, NI_NUMERICHOST); + dlhost = hostip; + t = parse_netmask(dlhost, NULL, &bits); + assert(t == HM_IPV4 || t == HM_IPV6); + } + + if (bits < 8) + { + sendto_one(source_p, + ":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.", + me.name, source_p->name); + return; + } + +#ifdef IPV6 + if (t == HM_IPV6) + t = AF_INET6; + else +#endif + t = AF_INET; + + parse_netmask(dlhost, &daddr, NULL); + + if ((aconf = find_dline_conf(&daddr, t)) != NULL) + { + creason = aconf->reason ? aconf->reason : def_reason; + if (IsConfExemptKline(aconf)) + sendto_one(source_p, + ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s", + me.name, source_p->name, dlhost, aconf->host, creason); + else + sendto_one(source_p, + ":%s NOTICE %s :[%s] already D-lined by [%s] - %s", + me.name, source_p->name, dlhost, aconf->host, creason); + return; + } + + cur_time = CurrentTime; + current_date = smalldate(cur_time); + + /* Look for an oper reason */ + if ((oper_reason = strchr(reason, '|')) != NULL) + *oper_reason++ = '\0'; + + if (!valid_comment(source_p, reason, 1)) + return; + + conf = make_conf_item(DLINE_TYPE); + aconf = map_to_conf(conf); + DupString(aconf->host, dlhost); + + if (tkline_time != 0) + { + snprintf(buffer, sizeof(buffer), "Temporary D-line %d min. - %s (%s)", + (int)(tkline_time/60), reason, current_date); + DupString(aconf->reason, buffer); + if (oper_reason != NULL) + DupString(aconf->oper_reason, oper_reason); + apply_tdline(source_p, conf, current_date, tkline_time); + } + else + { + snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date); + DupString(aconf->reason, buffer); + if (oper_reason != NULL) + DupString(aconf->oper_reason, oper_reason); + add_conf_by_address(CONF_DLINE, aconf); + write_conf_line(source_p, conf, current_date, cur_time); + } + + rehashed_klines = 1; + } +} + +/* +** m_undline +** added May 28th 2000 by Toby Verrall <toot@melnet.co.uk> +** based totally on m_unkline +** added to hybrid-7 7/11/2000 --is +** +** parv[0] = sender nick +** parv[1] = dline to remove +*/ +static void +mo_undline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *addr = NULL, *user = NULL; + char *target_server = NULL; + + if (!HasOFlag(source_p, OPER_FLAG_UNDLINE)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "undline"); + return; + } + + if (parc < 2 || EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "UNDLINE"); + return; + } + + if (parse_aline("UNDLINE", source_p, parc, parv, 0, &user, + &addr, NULL, &target_server, NULL) < 0) + return; + + if (target_server != NULL) + { + sendto_match_servs(source_p, target_server, CAP_UNDLN, + "UNDLINE %s %s", target_server, addr); + + /* Allow ON to apply local unkline as well if it matches */ + if (!match(target_server, me.name)) + return; + } + else + cluster_a_line(source_p, "UNDLINE", CAP_UNDLN, SHARED_UNDLINE, + "%s", addr); + + if (remove_tdline_match(addr)) + { + sendto_one(source_p, + ":%s NOTICE %s :Un-Dlined [%s] from temporary D-Lines", + me.name, source_p->name, addr); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has removed the temporary D-Line for: [%s]", + get_oper_name(source_p), addr); + ilog(LOG_TYPE_DLINE, "%s removed temporary D-Line for [%s]", + source_p->name, addr); + return; + } + + if (remove_conf_line(DLINE_TYPE, source_p, addr, NULL) > 0) + { + sendto_one(source_p, ":%s NOTICE %s :D-Line for [%s] is removed", + me.name, source_p->name, addr); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has removed the D-Line for: [%s]", + get_oper_name(source_p), addr); + ilog(LOG_TYPE_DLINE, "%s removed D-Line for [%s]", + get_oper_name(source_p), addr); + } + else + sendto_one(source_p, ":%s NOTICE %s :No D-Line for [%s] found", + me.name, source_p->name, addr); +} + +static void +me_undline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *addr = NULL; + + if (parc != 3 || EmptyString(parv[2])) + return; + + addr = parv[2]; + + if (!IsClient(source_p) || !match(parv[1], me.name)) + return; + + if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(ULINE_TYPE, + source_p->servptr->name, + source_p->username, source_p->host, + SHARED_UNDLINE)) + { + if (remove_tdline_match(addr)) + { + sendto_one(source_p, + ":%s NOTICE %s :Un-Dlined [%s] from temporary D-Lines", + me.name, source_p->name, addr); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has removed the temporary D-Line for: [%s]", + get_oper_name(source_p), addr); + ilog(LOG_TYPE_DLINE, "%s removed temporary D-Line for [%s]", + source_p->name, addr); + return; + } + + if (remove_conf_line(DLINE_TYPE, source_p, addr, NULL) > 0) + { + sendto_one(source_p, ":%s NOTICE %s :D-Line for [%s] is removed", + me.name, source_p->name, addr); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has removed the D-Line for: [%s]", + get_oper_name(source_p), addr); + ilog(LOG_TYPE_DLINE, "%s removed D-Line for [%s]", + get_oper_name(source_p), addr); + } + else + sendto_one(source_p, ":%s NOTICE %s :No D-Line for [%s] found", + me.name, source_p->name, addr); + } +} + +static void +ms_undline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc != 3 || EmptyString(parv[2])) + return; + + sendto_match_servs(source_p, parv[1], CAP_UNDLN, + "UNDLINE %s %s %s", + parv[1], parv[2]); + + me_undline(client_p, source_p, parc, parv); +} + +static struct Message dline_msgtab = { + "DLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, ms_dline, m_ignore, mo_dline, m_ignore} +}; + +static struct Message undline_msgtab = { + "UNDLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, ms_undline, m_ignore, mo_undline, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&dline_msgtab); + mod_add_cmd(&undline_msgtab); + add_capability("DLN", CAP_DLN, 1); + add_capability("UNDLN", CAP_UNDLN, 1); +} + +static void +module_exit(void) +{ + mod_del_cmd(&dline_msgtab); + mod_del_cmd(&undline_msgtab); + delete_capability("UNDLN"); + delete_capability("DLN"); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_encap.c b/modules/m_encap.c new file mode 100644 index 0000000..bb312d4 --- /dev/null +++ b/modules/m_encap.c @@ -0,0 +1,138 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_encap.c: encapsulated command propagation and parsing + * + * Copyright (C) 2003 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "parse.h" +#include "sprintf_irc.h" +#include "s_serv.h" +#include "send.h" +#include "modules.h" +#include "irc_string.h" + + +/* + * ms_encap() + * + * inputs - destination server, subcommand, parameters + * output - none + * side effects - propagates subcommand to locally connected servers + */ +static void +ms_encap(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char buffer[IRCD_BUFSIZE], *ptr = buffer; + unsigned int cur_len = 0, len, i; +#ifdef NOT_USED_YET + int paramcount, mpara = 0; +#endif + struct Message *mptr = NULL; + MessageHandler handler = 0; + + for (i = 1; i < (unsigned int)parc - 1; i++) + { + len = strlen(parv[i]) + 1; + + if ((cur_len + len) >= sizeof(buffer)) + return; + + snprintf(ptr, sizeof(buffer) - cur_len, "%s ", parv[i]); + cur_len += len; + ptr += len; + } + + len = strlen(parv[i]); + + /* + * if the final parameter crosses our buffer size, should we bail, + * like the rest, or should we truncate? ratbox seems to think truncate, + * so i'll do that for now until i can talk to lee. -bill + */ + + if (parc == 3) + snprintf(ptr, sizeof(buffer) - cur_len, "%s", parv[2]); + else + snprintf(ptr, sizeof(buffer) - cur_len, ":%s", parv[parc - 1]); + + if ((cur_len + len) >= sizeof(buffer)) + buffer[sizeof(buffer) - 1] = '\0'; + + sendto_match_servs(source_p, parv[1], CAP_ENCAP, + "ENCAP %s", buffer); + + if (!match(parv[1], me.name)) + return; + + if ((mptr = find_command(parv[2])) == NULL) + return; + +#ifdef NOT_USED_YET + paramcount = mptr->parameters; + mpara = mptr->maxpara; +#endif + mptr->bytes += strlen(buffer); + + /* + * yes this is an ugly hack, but it is quicker than copying the entire array again + * note: this hack wouldnt be needed if parv[0] were set to the command name, rather + * than being derived from the prefix, as it should have been from the beginning. + */ + ptr = parv[0]; + parv += 2; + parc -= 2; + parv[0] = ptr; + + if ((handler = mptr->handlers[ENCAP_HANDLER])) + (*handler)(client_p, source_p, parc, parv); +} + +static struct Message encap_msgtab = { + "ENCAP", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + {m_ignore, m_ignore, ms_encap, m_ignore, m_ignore, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&encap_msgtab); + add_capability("ENCAP", CAP_ENCAP, 1); +} + +static void +module_exit(void) +{ + mod_del_cmd(&encap_msgtab); + delete_capability("ENCAP"); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_eob.c b/modules/m_eob.c new file mode 100644 index 0000000..ceeff0c --- /dev/null +++ b/modules/m_eob.c @@ -0,0 +1,76 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_eob.c: Signifies the end of a server burst. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "send.h" +#include "parse.h" +#include "modules.h" + + +/* + * ms_eob - EOB command handler + * parv[0] = sender prefix + * parv[1] = servername + */ +static void +ms_eob(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + assert(IsServer(source_p)); + assert(client_p == source_p); + + sendto_realops_flags(UMODE_ALL, L_ALL, "End of burst from %s (%u seconds)", + source_p->name, + (unsigned int)(CurrentTime - source_p->localClient->firsttime)); + AddFlag(source_p, FLAGS_EOB); +} + +static struct Message eob_msgtab = { + "EOB", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_ignore, ms_eob, m_ignore, m_ignore, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&eob_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&eob_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_etrace.c b/modules/m_etrace.c new file mode 100644 index 0000000..28b80ae --- /dev/null +++ b/modules/m_etrace.c @@ -0,0 +1,233 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_etrace.c: Traces a path to a client/server. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "conf.h" + + +static void report_this_status(struct Client *, struct Client *, int); + +/* + * do_etrace() + */ +static void +do_etrace(struct Client *source_p, int parc, char *parv[]) +{ + const char *tname = NULL; + struct Client *target_p = NULL; + int wilds = 0; + int do_all = 0; + int full_etrace = 0; + dlink_node *ptr; + + sendto_realops_flags(UMODE_SPY, L_ALL, + "ETRACE requested by %s (%s@%s) [%s]", + source_p->name, source_p->username, + source_p->host, source_p->servptr->name); + + if (parc > 1) + { + if (irccmp(parv[1], "-full") == 0) + { + ++parv; + --parc; + full_etrace = 1; + } + } + + if (parc > 1) + { + tname = parv[1]; + + if (tname != NULL) + wilds = has_wildcards(tname); + else + tname = "*"; + } + else + { + do_all = 1; + tname = "*"; + } + + if (HasUMode(source_p, UMODE_CCONN_FULL)) + full_etrace = 1; + + if (!wilds && !do_all) + { + target_p = hash_find_client(tname); + + if (target_p && MyClient(target_p)) + report_this_status(source_p, target_p, full_etrace); + + sendto_one(source_p, form_str(RPL_ENDOFTRACE), me.name, + source_p->name, tname); + return; + } + + DLINK_FOREACH(ptr, local_client_list.head) + { + target_p = ptr->data; + + if (wilds) + { + if (match(tname, target_p->name)) + report_this_status(source_p, target_p, full_etrace); + } + else + report_this_status(source_p, target_p, full_etrace); + } + + sendto_one(source_p, form_str(RPL_ENDOFTRACE), me.name, + source_p->name, tname); +} + +/* mo_etrace() + * parv[0] = sender prefix + * parv[1] = servername + */ +static void +mo_etrace(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + do_etrace(source_p, parc, parv); +} + +/* report_this_status() + * + * inputs - pointer to client to report to + * - pointer to client to report about + * - flag full etrace or not + * output - NONE + * side effects - NONE + */ +static void +report_this_status(struct Client *source_p, struct Client *target_p, + int full_etrace) +{ + const char *name; + const char *class_name; + + name = get_client_name(target_p, HIDE_IP); + class_name = get_client_class(target_p); + + set_time(); + + if (target_p->status == STAT_CLIENT) + { + if (full_etrace) + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_ETRACE_FULL), + me.name, + source_p->name, + HasUMode(target_p, UMODE_OPER) ? "Oper" : "User", + class_name, + target_p->name, + target_p->username, + target_p->host, + IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost, + IsIPSpoof(target_p) ? "<hidden>" : target_p->localClient->client_host, + IsIPSpoof(target_p) ? "<hidden>" : target_p->localClient->client_server, + target_p->info); + else + sendto_one(source_p, form_str(RPL_ETRACE_FULL), + me.name, + source_p->name, + HasUMode(target_p, UMODE_OPER) ? "Oper" : "User", + class_name, + target_p->name, + target_p->username, + target_p->host, + target_p->sockhost, + target_p->localClient->client_host, + target_p->localClient->client_server, + target_p->info); + } + else + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_ETRACE), + me.name, + source_p->name, + HasUMode(target_p, UMODE_OPER) ? "Oper" : "User", + class_name, + target_p->name, + target_p->username, + target_p->host, + IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost, + target_p->info); + else + sendto_one(source_p, form_str(RPL_ETRACE), + me.name, + source_p->name, + HasUMode(target_p, UMODE_OPER) ? "Oper" : "User", + class_name, + target_p->name, + target_p->username, + target_p->host, + target_p->sockhost, + target_p->info); + } + } +} + +static struct Message etrace_msgtab = { + "ETRACE", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_etrace, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&etrace_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&etrace_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_gline.c b/modules/m_gline.c new file mode 100644 index 0000000..1b29445 --- /dev/null +++ b/modules/m_gline.c @@ -0,0 +1,575 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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 + */ + +/*! \file m_gline.c + * \brief Includes required functions for processing the GLINE command. + * \version $Id$ + */ + +#include "stdinc.h" +#include "list.h" +#include "s_gline.h" +#include "channel.h" +#include "client.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "hostmask.h" +#include "numeric.h" +#include "s_bsd.h" +#include "conf.h" +#include "s_misc.h" +#include "send.h" +#include "s_serv.h" +#include "hash.h" +#include "parse.h" +#include "modules.h" +#include "log.h" + +#define GLINE_NOT_PLACED 0 +#define GLINE_ALREADY_VOTED -1 +#define GLINE_PLACED 1 + + +/*! \brief Adds a GLINE to the configuration subsystem. + * + * \param source_p Operator requesting gline + * \param user Username covered by the gline + * \param host Hostname covered by the gline + * \param reason Reason for the gline + */ +static void +set_local_gline(const struct Client *source_p, const char *user, + const char *host, const char *reason) +{ + char buffer[IRCD_BUFSIZE]; + struct ConfItem *conf; + struct AccessItem *aconf; + + + conf = make_conf_item(GLINE_TYPE); + aconf = map_to_conf(conf); + + snprintf(buffer, sizeof(buffer), "%s (%s)", reason, smalldate(CurrentTime)); + DupString(aconf->reason, buffer); + DupString(aconf->user, user); + DupString(aconf->host, host); + + aconf->hold = CurrentTime + ConfigFileEntry.gline_time; + SetConfTemporary(aconf); + add_conf_by_address(CONF_GLINE, aconf); + + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s added G-Line for [%s@%s] [%s]", + get_oper_name(source_p), + aconf->user, aconf->host, aconf->reason); + ilog(LOG_TYPE_GLINE, "%s added G-Line for [%s@%s] [%s]", + get_oper_name(source_p), aconf->user, aconf->host, aconf->reason); + + /* Now, activate gline against current online clients */ + rehashed_klines = 1; +} + +/*! \brief Removes a GLINE from the configuration subsystem. + * + * \param user Username covered by the gline + * \param host Hostname covered by the gline + */ +static int +remove_gline_match(const char *user, const char *host) +{ + struct irc_ssaddr iphost, *piphost; + struct AccessItem *aconf; + int t; + + if ((t = parse_netmask(host, &iphost, NULL)) != HM_HOST) + { +#ifdef IPV6 + if (t == HM_IPV6) + t = AF_INET6; + else +#endif + t = AF_INET; + piphost = &iphost; + } + else + { + t = 0; + piphost = NULL; + } + + if ((aconf = find_conf_by_address(host, piphost, CONF_GLINE, t, user, NULL, 0))) + { + if (IsConfTemporary(aconf)) + { + delete_one_address_conf(host, aconf); + return 1; + } + } + + return 0; +} + +/*! \brief This function is called once a majority of opers have agreed on a + * GLINE/GUNGLINE, and it can be placed. The information about an + * operator being passed to us happens to be the operator who pushed us + * over the "majority" level needed. See check_majority() for more + * information. + * + * \param source_p Operator requesting gline + * \param user Username covered by the gline + * \param host Hostname covered by the gline + * \param reason Reason for the gline + * \param type Valid values are either GLINE_PENDING_ADD_TYPE, or + * GLINE_PENDING_DEL_TYPE + */ +static void +add_new_majority(const struct Client *source_p, const char *user, + const char *host, const char *reason, const unsigned int type) +{ + struct gline_pending *pending = MyMalloc(sizeof(struct gline_pending)); + + strlcpy(pending->vote_1.oper_nick, source_p->name, sizeof(pending->vote_1.oper_nick)); + strlcpy(pending->vote_1.oper_user, source_p->username, sizeof(pending->vote_1.oper_user)); + strlcpy(pending->vote_1.oper_host, source_p->host, sizeof(pending->vote_1.oper_host)); + strlcpy(pending->vote_1.oper_server, source_p->servptr->name, sizeof(pending->vote_1.oper_server)); + + strlcpy(pending->user, user, sizeof(pending->user)); + strlcpy(pending->host, host, sizeof(pending->host)); + strlcpy(pending->vote_1.reason, reason, sizeof(pending->vote_1.reason)); + + pending->last_gline_time = CurrentTime; + pending->vote_1.time_request = CurrentTime; + + dlinkAdd(pending, &pending->node, &pending_glines[type]); +} + +/*! \brief See if there is a majority agreement on a GLINE on the given user. + * There must be at least 3 different opers agreeing on this + * GLINE/GUNGLINE + * + * \param source_p Operator requesting gline + * \param user Username covered by the gline + * \param host Hostname covered by the gline + * \param reason Reason for the gline + * \param type Valid values are either GLINE_PENDING_ADD_TYPE, or + * GLINE_PENDING_DEL_TYPE + * + * \return + * - GLINE_ALREADY_VOTED returned if oper/server has already voted + * - GLINE_PLACED returned if this triggers a gline + * - GLINE_NOT_PLACED returned if not triggered + */ +static int +check_majority(const struct Client *source_p, const char *user, + const char *host, const char *reason, const int type) +{ + dlink_node *dn_ptr = NULL; + + cleanup_glines(NULL); + + /* if its already glined, why bother? :) -- fl_ */ + if ((type == GLINE_PENDING_ADD_TYPE) && find_is_glined(host, user)) + return GLINE_NOT_PLACED; + + DLINK_FOREACH(dn_ptr, pending_glines[type].head) + { + struct gline_pending *gp_ptr = dn_ptr->data; + + if (irccmp(gp_ptr->user, user) || + irccmp(gp_ptr->host, host)) + continue; + + if ((!irccmp(gp_ptr->vote_1.oper_user, source_p->username) && + !irccmp(gp_ptr->vote_1.oper_host, source_p->host)) || + !irccmp(gp_ptr->vote_1.oper_server, source_p->servptr->name)) + return GLINE_ALREADY_VOTED; + + if (gp_ptr->vote_2.oper_user[0] != '\0') + { + /* if two other opers on two different servers have voted yes */ + if ((!irccmp(gp_ptr->vote_2.oper_user, source_p->username) && + !irccmp(gp_ptr->vote_2.oper_host, source_p->host)) || + !irccmp(gp_ptr->vote_2.oper_server, source_p->servptr->name)) + return GLINE_ALREADY_VOTED; + + if (type == GLINE_PENDING_DEL_TYPE) + { + if (remove_gline_match(user, host)) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has removed the G-Line for: [%s@%s]", + get_oper_name(source_p), user, host); + ilog(LOG_TYPE_GLINE, "%s removed G-Line for [%s@%s]", + get_oper_name(source_p), user, host); + } + } + else + /* trigger the gline using the original reason --fl */ + set_local_gline(source_p, user, host, gp_ptr->vote_1.reason); + + cleanup_glines(gp_ptr); + return GLINE_PLACED; + } + + strlcpy(gp_ptr->vote_2.oper_nick, source_p->name, + sizeof(gp_ptr->vote_2.oper_nick)); + strlcpy(gp_ptr->vote_2.oper_user, source_p->username, + sizeof(gp_ptr->vote_2.oper_user)); + strlcpy(gp_ptr->vote_2.oper_host, source_p->host, + sizeof(gp_ptr->vote_2.oper_host)); + strlcpy(gp_ptr->vote_2.reason, reason, + sizeof(gp_ptr->vote_2.reason)); + strlcpy(gp_ptr->vote_2.oper_server, source_p->servptr->name, + sizeof(gp_ptr->vote_2.oper_server)); + gp_ptr->last_gline_time = CurrentTime; + gp_ptr->vote_2.time_request = CurrentTime; + return GLINE_NOT_PLACED; + } + + /* + * Didn't find this user@host gline in pending gline list + * so add it. + */ + add_new_majority(source_p, user, host, reason, type); + return GLINE_NOT_PLACED; +} + +static void +do_sgline(struct Client *source_p, int parc, char *parv[], int prop) +{ + const char *reason = NULL; /* reason for "victims" demise */ + const char *user = NULL; + const char *host = NULL; /* user and host of GLINE "victim" */ + + if (!IsClient(source_p)) + return; + + if (parc != 4 || EmptyString(parv[3])) + return; + + assert(source_p->servptr != NULL); + + user = parv[1]; + host = parv[2]; + reason = parv[3]; + + sendto_server(source_p->from, CAP_GLN|CAP_TS6, NOCAPS, + ":%s GLINE %s %s :%s", + ID(source_p), user, host, reason); + sendto_server(source_p->from, CAP_GLN, CAP_TS6, + ":%s GLINE %s %s :%s", + source_p->name, user, host, reason); + + if (ConfigFileEntry.glines) + { + if (!valid_wild_card(source_p, 1, 2, user, host)) + return; + + if (IsClient(source_p)) + { + const char *p = NULL; + + if ((p = strchr(host, '/'))) + { + int bitlen = strtol(++p, NULL, 10); + int min_bitlen = strchr(host, ':') ? ConfigFileEntry.gline_min_cidr6 : + ConfigFileEntry.gline_min_cidr; + + if (bitlen < min_bitlen) + { + sendto_realops_flags(UMODE_ALL, L_ALL, "%s!%s@%s on %s is requesting " + "a GLINE with a CIDR mask < %d for [%s@%s] [%s]", + source_p->name, source_p->username, source_p->host, + source_p->servptr->name, min_bitlen, user, host, reason); + return; + } + } + } + + /* If at least 3 opers agree this user should be G lined then do it */ + if (check_majority(source_p, user, host, reason, GLINE_PENDING_ADD_TYPE) == + GLINE_ALREADY_VOTED) + { + sendto_realops_flags(UMODE_ALL, L_ALL, "oper or server has already voted"); + return; + } + + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s requesting G-Line for [%s@%s] [%s]", + get_oper_name(source_p), + user, host, reason); + ilog(LOG_TYPE_GLINE, "#gline for %s@%s [%s] requested by %s", + user, host, reason, get_oper_name(source_p)); + } +} + + +/*! \brief GLINE command handler (called by operators) + * + * \param client_p Pointer to allocated Client struct with physical connection + * to this server, i.e. with an open socket connected. + * \param source_p Pointer to allocated Client struct from which the message + * originally comes from. This can be a local or remote client. + * \param parc Integer holding the number of supplied arguments. + * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL + * pointers. + * \note Valid arguments for this command are: + * - parv[0] = sender prefix + * - parv[1] = user\@host mask + * - parv[2] = reason + */ +static void +mo_gline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *user = NULL; + char *host = NULL; + char *reason = NULL; + char *p; + + if (!HasOFlag(source_p, OPER_FLAG_GLINE)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "gline"); + return; + } + + if (!ConfigFileEntry.glines) + { + sendto_one(source_p, ":%s NOTICE %s :GLINE disabled", + me.name, source_p->name); + return; + } + + if (parse_aline("GLINE", source_p, parc, parv, AWILD, + &user, &host, NULL, NULL, &reason) < 0) + return; + + if ((p = strchr(host, '/')) != NULL) + { + int bitlen = strtol(++p, NULL, 10); + int min_bitlen = strchr(host, ':') ? ConfigFileEntry.gline_min_cidr6 : + ConfigFileEntry.gline_min_cidr; + if (bitlen < min_bitlen) + { + sendto_one(source_p, ":%s NOTICE %s :Cannot set G-Lines with CIDR length < %d", + me.name, source_p->name, min_bitlen); + return; + } + } + + /* If at least 3 opers agree this user should be G lined then do it */ + if (check_majority(source_p, user, host, reason, GLINE_PENDING_ADD_TYPE) == + GLINE_ALREADY_VOTED) + { + sendto_one(source_p, + ":%s NOTICE %s :This server or oper has already voted", + me.name, source_p->name); + return; + } + + /* + * call these two functions first so the 'requesting' notice always comes + * before the 'has triggered' notice. -bill + */ + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s requesting G-Line for [%s@%s] [%s]", + get_oper_name(source_p), + user, host, reason); + ilog(LOG_TYPE_GLINE, "#gline for %s@%s [%s] requested by %s!%s@%s", + user, host, reason, source_p->name, source_p->username, + source_p->host); + + /* 4 param version for hyb-7 servers */ + sendto_server(NULL, CAP_GLN|CAP_TS6, NOCAPS, + ":%s GLINE %s %s :%s", + ID(source_p), user, host, reason); + sendto_server(NULL, CAP_GLN, CAP_TS6, + ":%s GLINE %s %s :%s", + source_p->name, user, host, reason); +} + +/* ms_gline() + * me_gline() + * do_sgline() + * + * inputs - The usual for a m_ function + * output - + * side effects - + * + * Place a G line if 3 opers agree on the identical user@host + * + * Allow this server to pass along GLINE if received and + * GLINES is not defined. + * + * ENCAP'd GLINES are propagated by encap code. + */ + +static void +ms_gline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + do_sgline(source_p, parc, parv, 1); +} + +static void +me_gline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + do_sgline(source_p, parc, parv, 0); +} + +static void +do_sungline(struct Client *source_p, const char *user, + const char *host, const char *reason, int prop) +{ + assert(source_p->servptr != NULL); + + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s requesting UNG-Line for [%s@%s] [%s]", + get_oper_name(source_p), user, host, reason); + ilog(LOG_TYPE_GLINE, "#ungline for %s@%s [%s] requested by %s", + user, host, reason, get_oper_name(source_p)); + + /* If at least 3 opers agree this user should be un G lined then do it */ + if (check_majority(source_p, user, host, reason, GLINE_PENDING_DEL_TYPE) == + GLINE_ALREADY_VOTED) + sendto_realops_flags(UMODE_ALL, L_ALL, "oper or server has already voted"); + + if (prop) + { + sendto_server(source_p->from, CAP_ENCAP|CAP_TS6, NOCAPS, + ":%s ENCAP * GUNGLINE %s %s :%s", + ID(source_p), user, host, reason); + sendto_server(source_p->from, CAP_ENCAP, CAP_TS6, + ":%s ENCAP * GUNGLINE %s %s :%s", + source_p->name, user, host, reason); + } +} + +/*! \brief GUNGLINE command handler (called in response to an encapsulated + * GUNGLINE command) + * + * \param client_p Pointer to allocated Client struct with physical connection + * to this server, i.e. with an open socket connected. + * \param source_p Pointer to allocated Client struct from which the message + * originally comes from. This can be a local or remote client. + * \param parc Integer holding the number of supplied arguments. + * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL + * pointers. + * \note Valid arguments for this command are: + * - parv[0] = sender prefix + * - parv[1] = username + * - parv[2] = hostname + * - parv[3] = reason + */ +static void +me_gungline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (ConfigFileEntry.glines) + do_sungline(source_p, parv[1], parv[2], parv[3], 0); +} + +/*! \brief GUNGLINE command handler (called by operators) + * + * \param client_p Pointer to allocated Client struct with physical connection + * to this server, i.e. with an open socket connected. + * \param source_p Pointer to allocated Client struct from which the message + * originally comes from. This can be a local or remote client. + * \param parc Integer holding the number of supplied arguments. + * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL + * pointers. + * \note Valid arguments for this command are: + * - parv[0] = sender prefix + * - parv[1] = user\@host mask + * - parv[2] = reason + */ +static void +mo_gungline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *user = NULL; + char *host = NULL; + char *reason = NULL; + + if (!HasOFlag(source_p, OPER_FLAG_GLINE)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "gline"); + return; + } + + if (!ConfigFileEntry.glines) + { + sendto_one(source_p, ":%s NOTICE %s :GUNGLINE disabled", + me.name, source_p->name); + return; + } + + if (parse_aline("GUNGLINE", source_p, parc, parv, 0, &user, + &host, NULL, NULL, &reason) < 0) + return; + + do_sungline(source_p, user, host, reason, 1); +} + +/* + * gline enforces 3 parameters to force operator to give a reason + * a gline is not valid with "No reason" + * -db + */ +static struct Message gline_msgtab = { + "GLINE", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, ms_gline, me_gline, mo_gline, m_ignore } +}; + +static struct Message ungline_msgtab = { + "GUNGLINE", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, m_ignore, me_gungline, mo_gungline, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&gline_msgtab); + mod_add_cmd(&ungline_msgtab); + add_capability("GLN", CAP_GLN, 1); +} + +static void +module_exit(void) +{ + mod_del_cmd(&gline_msgtab); + mod_del_cmd(&ungline_msgtab); + delete_capability("GLN"); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_globops.c b/modules/m_globops.c new file mode 100644 index 0000000..9f9c2eb --- /dev/null +++ b/modules/m_globops.c @@ -0,0 +1,112 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "irc_string.h" +#include "numeric.h" +#include "send.h" +#include "s_user.h" +#include "s_serv.h" +#include "parse.h" +#include "modules.h" + + +/* + * mo_globops - GLOBOPS message handler + * (write to *all* local opers currently online) + * parv[0] = sender prefix + * parv[1] = message text + */ +static void +mo_globops(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *message = parv[1]; + + if (!HasOFlag(source_p, OPER_FLAG_GLOBOPS)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "globops"); + return; + } + + if (EmptyString(message)) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "GLOBOPS"); + return; + } + + sendto_server(NULL, CAP_TS6, NOCAPS, + ":%s GLOBOPS :%s", ID(source_p), message); + sendto_server(NULL, NOCAPS, CAP_TS6, + ":%s GLOBOPS :%s", source_p->name, message); + + sendto_globops_flags(UMODE_ALL, L_ALL, "from: %s: %s", + source_p->name, message); +} + +static void +ms_globops(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (EmptyString(parv[1])) + return; + + sendto_server(client_p, CAP_TS6, NOCAPS, ":%s GLOBOPS :%s", + ID(source_p), parv[1]); + sendto_server(client_p, NOCAPS, CAP_TS6, ":%s GLOBOPS :%s", + source_p->name, parv[1]); + + sendto_globops_flags(UMODE_ALL, L_ALL, "from: %s: %s", + source_p->name, parv[1]); +} + +static struct Message globops_msgtab = { + "GLOBOPS", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, ms_globops, m_ignore, mo_globops, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&globops_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&globops_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_hash.c b/modules/m_hash.c new file mode 100644 index 0000000..89bc89b --- /dev/null +++ b/modules/m_hash.c @@ -0,0 +1,190 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "s_user.h" +#include "resv.h" +#include "userhost.h" + + +static void +mo_hash(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + int i; + int max_chain = 0; + int buckets = 0; + int count = 0; + struct Client *cl; + struct Client *icl; + struct Channel *ch; + struct UserHost *ush; + struct ResvChannel *rch; + + for (i = 0; i < HASHSIZE; ++i) + { + if ((cl = hash_get_bucket(HASH_TYPE_CLIENT, i)) != NULL) + { + int len = 0; + + ++buckets; + for (; cl != NULL; cl = cl->hnext) + ++len; + if (len > max_chain) + max_chain = len; + count += len; + } + } + + sendto_one(source_p, ":%s NOTICE %s :Client: entries: %d buckets: %d " + "max chain: %d", me.name, source_p->name, count, buckets, + max_chain); + + count = 0; + buckets = 0; + max_chain = 0; + + for (i = 0; i < HASHSIZE; ++i) + { + if ((ch = hash_get_bucket(HASH_TYPE_CHANNEL, i)) != NULL) + { + int len = 0; + + ++buckets; + for (; ch != NULL; ch = ch->hnextch) + ++len; + if (len > max_chain) + max_chain = len; + count += len; + } + } + + sendto_one(source_p, ":%s NOTICE %s :Channel: entries: %d buckets: %d " + "max chain: %d", me.name, source_p->name, count, buckets, + max_chain); + + count = 0; + buckets = 0; + max_chain = 0; + + for (i = 0; i < HASHSIZE; ++i) + { + if ((rch = hash_get_bucket(HASH_TYPE_RESERVED, i)) != NULL) + { + int len = 0; + + ++buckets; + for (; rch != NULL; rch = rch->hnext) + ++len; + if (len > max_chain) + max_chain = len; + count += len; + } + } + + sendto_one(source_p, ":%s NOTICE %s :Resv: entries: %d buckets: %d " + "max chain: %d", me.name, source_p->name, count, buckets, + max_chain); + + count = 0; + buckets = 0; + max_chain = 0; + + for (i = 0; i < HASHSIZE; ++i) + { + if ((icl = hash_get_bucket(HASH_TYPE_ID, i)) != NULL) + { + int len = 0; + + ++buckets; + for (; icl != NULL; icl = icl->idhnext) + ++len; + if (len > max_chain) + max_chain = len; + count += len; + } + } + + sendto_one(source_p, ":%s NOTICE %s :Id: entries: %d buckets: %d " + "max chain: %d", me.name, source_p->name, count, buckets, + max_chain); + + count = 0; + buckets = 0; + max_chain = 0; + + for (i = 0; i < HASHSIZE; ++i) + { + if ((ush = hash_get_bucket(HASH_TYPE_USERHOST, i)) != NULL) + { + int len = 0; + + ++buckets; + for (; ush != NULL; ush = ush->next) + ++len; + if (len > max_chain) + max_chain = len; + count += len; + } + } + + sendto_one(source_p, ":%s NOTICE %s :UserHost: entries: %d buckets: %d " + "max chain: %d", me.name, source_p->name, count, buckets, + max_chain); +} + +static struct Message hash_msgtab = { + "HASH", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_hash, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&hash_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&hash_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_help.c b/modules/m_help.c new file mode 100644 index 0000000..2bd47a1 --- /dev/null +++ b/modules/m_help.c @@ -0,0 +1,230 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_help.c: Provides help information to a user/operator. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "conf.h" +#include "parse.h" +#include "modules.h" +#include "irc_string.h" + +#define HELPLEN 400 + +static void dohelp(struct Client *, const char *, char *); +static void sendhelpfile(struct Client *, const char *, const char *); + + +/* + * m_help - HELP message handler + * parv[0] = sender prefix + */ +static void +m_help(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + static time_t last_used = 0; + + /* HELP is always local */ + if ((last_used + ConfigFileEntry.pace_wait_simple) > CurrentTime) + { + /* safe enough to give this on a local connect only */ + sendto_one(source_p,form_str(RPL_LOAD2HI), + me.name, source_p->name); + return; + } + + last_used = CurrentTime; + + dohelp(source_p, UHPATH, parv[1]); +} + +/* + * mo_help - HELP message handler + * parv[0] = sender prefix + */ +static void +mo_help(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + dohelp(source_p, HPATH, parv[1]); +} + +/* + * mo_uhelp - HELP message handler + * This is used so that opers can view the user help file without deopering + * parv[0] = sender prefix + */ +static void +mo_uhelp(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + dohelp(source_p, UHPATH, parv[1]); +} + +static void +dohelp(struct Client *source_p, const char *hpath, char *topic) +{ + char h_index[] = "index"; + char path[PATH_MAX + 1]; + struct stat sb; + int i; + + if (topic != NULL) + { + if (*topic == '\0') + topic = h_index; + else + { + /* convert to lower case */ + for (i = 0; topic[i] != '\0'; ++i) + topic[i] = ToLower(topic[i]); + } + } + else + topic = h_index; /* list available help topics */ + + if (strpbrk(topic, "/\\")) + { + sendto_one(source_p, form_str(ERR_HELPNOTFOUND), + me.name, source_p->name, topic); + return; + } + + if (strlen(hpath) + strlen(topic) + 1 > PATH_MAX) + { + sendto_one(source_p, form_str(ERR_HELPNOTFOUND), + me.name, source_p->name, topic); + return; + } + + snprintf(path, sizeof(path), "%s/%s", hpath, topic); + + if (stat(path, &sb) < 0) + { + sendto_one(source_p, form_str(ERR_HELPNOTFOUND), + me.name, source_p->name, topic); + return; + } + + if (!S_ISREG(sb.st_mode)) + { + sendto_one(source_p, form_str(ERR_HELPNOTFOUND), + me.name, source_p->name, topic); + return; + } + + sendhelpfile(source_p, path, topic); +} + +static void +sendhelpfile(struct Client *source_p, const char *path, const char *topic) +{ + FILE *file; + char line[HELPLEN]; + char started = 0; + int type; + + if ((file = fopen(path, "r")) == NULL) + { + sendto_one(source_p, form_str(ERR_HELPNOTFOUND), + me.name, source_p->name, topic); + return; + } + + if (fgets(line, sizeof(line), file) == NULL) + { + sendto_one(source_p, form_str(ERR_HELPNOTFOUND), + me.name, source_p->name, topic); + return; + } + + else if (line[0] != '#') + { + line[strlen(line) - 1] = '\0'; + sendto_one(source_p, form_str(RPL_HELPSTART), + me.name, source_p->name, topic, line); + started = 1; + } + + while (fgets(line, sizeof(line), file)) + { + line[strlen(line) - 1] = '\0'; + if (line[0] != '#') + { + if (!started) + { + type = RPL_HELPSTART; + started = 1; + } + else + type = RPL_HELPTXT; + + sendto_one(source_p, form_str(RPL_HELPTXT), + me.name, source_p->name, topic, line); + } + } + + fclose(file); + sendto_one(source_p, form_str(RPL_HELPTXT), + me.name, source_p->name, topic, ""); + sendto_one(source_p, form_str(RPL_ENDOFHELP), + me.name, source_p->name, topic); +} + +static struct Message help_msgtab = { + "HELP", 0, 0, 0, 0, MFLG_SLOW, 0, + {m_unregistered, m_help, m_ignore, m_ignore, mo_help, m_ignore} +}; + +static struct Message uhelp_msgtab = { + "UHELP", 0, 0, 0, 0, MFLG_SLOW, 0, + {m_unregistered, m_help, m_ignore, m_ignore, mo_uhelp, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&help_msgtab); + mod_add_cmd(&uhelp_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&help_msgtab); + mod_del_cmd(&uhelp_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_info.c b/modules/m_info.c new file mode 100644 index 0000000..c3e81d7 --- /dev/null +++ b/modules/m_info.c @@ -0,0 +1,733 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_info.c: Sends information about the server. + * + * Copyright (C) 2005 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "client.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "s_serv.h" +#include "s_user.h" +#include "send.h" +#include "conf.h" +#include "parse.h" +#include "modules.h" + + +static void send_conf_options(struct Client *); +static void send_birthdate_online_time(struct Client *); +static void send_info_text(struct Client *); + +/* + * jdc -- Structure for our configuration value table + */ +struct InfoStruct +{ + const char *name; /* Displayed variable name */ + unsigned int output_type; /* See below #defines */ + void *option; /* Pointer reference to the value */ + const char *desc; /* ASCII description of the variable */ +}; + +/* Types for output_type in InfoStruct */ +#define OUTPUT_STRING 0x0001 /* Output option as %s w/ dereference */ +#define OUTPUT_STRING_PTR 0x0002 /* Output option as %s w/out deference */ +#define OUTPUT_DECIMAL 0x0004 /* Output option as decimal (%d) */ +#define OUTPUT_BOOLEAN 0x0008 /* Output option as "ON" or "OFF" */ +#define OUTPUT_BOOLEAN_YN 0x0010 /* Output option as "YES" or "NO" */ +#define OUTPUT_BOOLEAN2 0x0020 /* Output option as "YES/NO/MASKED" */ + +static const struct InfoStruct info_table[] = +{ + /* --[ START OF TABLE ]-------------------------------------------- */ + + { + "CPATH", + OUTPUT_STRING, + &ConfigFileEntry.configfile, + "Path to Main Configuration File" + }, + { + "DPATH", + OUTPUT_STRING, + &ConfigFileEntry.dpath, + "Directory Containing Configuration Files" + }, + { + "DLPATH", + OUTPUT_STRING, + &ConfigFileEntry.dlinefile, + "Path to D-line File" + }, + { + "KPATH", + OUTPUT_STRING, + &ConfigFileEntry.klinefile, + "Path to K-line File" + }, + { + "network_name", + OUTPUT_STRING, + &ServerInfo.network_name, + "Network name" + }, + { + "network_desc", + OUTPUT_STRING, + &ServerInfo.network_desc, + "Network description" + }, + { + "hub", + OUTPUT_BOOLEAN_YN, + &ServerInfo.hub, + "Server is a hub" + }, + { + "use_logging", + OUTPUT_BOOLEAN_YN, + &ConfigLoggingEntry.use_logging, + "Enable logging" + }, + { + "restrict_channels", + OUTPUT_BOOLEAN_YN, + &ConfigChannel.restrict_channels, + "Only reserved channels are allowed" + }, + { + "knock_delay", + OUTPUT_DECIMAL, + &ConfigChannel.knock_delay, + "Delay between a users KNOCK attempts" + }, + { + "knock_delay_channel", + OUTPUT_DECIMAL, + &ConfigChannel.knock_delay_channel, + "Delay between KNOCK attempts to a channel" + }, + { + "max_chans_per_user", + OUTPUT_DECIMAL, + &ConfigChannel.max_chans_per_user, + "Maximum number of channels a user can join" + }, + { + "max_chans_per_oper", + OUTPUT_DECIMAL, + &ConfigChannel.max_chans_per_oper, + "Maximum number of channels an oper can join" + }, + { + "quiet_on_ban", + OUTPUT_BOOLEAN_YN, + &ConfigChannel.quiet_on_ban, + "Banned users may not send text to a channel" + }, + { + "max_bans", + OUTPUT_DECIMAL, + &ConfigChannel.max_bans, + "Total +b/e/I modes allowed in a channel" + }, + { + "default_split_user_count", + OUTPUT_DECIMAL, + &ConfigChannel.default_split_user_count, + "Startup value of SPLITUSERS" + }, + { + "default_split_server_count", + OUTPUT_DECIMAL, + &ConfigChannel.default_split_server_count, + "Startup value of SPLITNUM" + }, + { + "no_create_on_split", + OUTPUT_BOOLEAN_YN, + &ConfigChannel.no_create_on_split, + "Disallow creation of channels when split" + }, + { + "no_join_on_split", + OUTPUT_BOOLEAN_YN, + &ConfigChannel.no_join_on_split, + "Disallow joining channels when split" + }, + { + "flatten_links", + OUTPUT_BOOLEAN_YN, + &ConfigServerHide.flatten_links, + "Flatten /links list" + }, + { + "links_delay", + OUTPUT_DECIMAL, + &ConfigServerHide.links_delay, + "Links rehash delay" + }, + { + "hidden", + OUTPUT_BOOLEAN_YN, + &ConfigServerHide.hidden, + "Hide this server from a flattened /links on remote servers" + }, + { + "hide_servers", + OUTPUT_BOOLEAN_YN, + &ConfigServerHide.hide_servers, + "Hide servernames from users" + }, + { + "hidden_name", + OUTPUT_STRING, + &ConfigServerHide.hidden_name, + "Server name users see if hide_servers = yes" + }, + { + "hide_server_ips", + OUTPUT_BOOLEAN_YN, + &ConfigServerHide.hide_server_ips, + "Prevent people from seeing server IPs" + }, + { + "gline_min_cidr", + OUTPUT_DECIMAL, + &ConfigFileEntry.gline_min_cidr, + "Minimum required length of a CIDR bitmask for IPv4 G-Lines" + }, + { + "gline_min_cidr6", + OUTPUT_DECIMAL, + &ConfigFileEntry.gline_min_cidr6, + "Minimum required length of a CIDR bitmask for IPv6 G-Lines" + }, + { + "invisible_on_connect", + OUTPUT_BOOLEAN_YN, + &ConfigFileEntry.invisible_on_connect, + "Automatically set mode +i on connecting users" + }, + { + "kill_chase_time_limit", + OUTPUT_DECIMAL, + &ConfigFileEntry.kill_chase_time_limit, + "Nick Change Tracker for KILL" + }, + { + "hide_spoof_ips", + OUTPUT_BOOLEAN_YN, + &ConfigFileEntry.hide_spoof_ips, + "Hide spoofed IP's" + }, + { + "ignore_bogus_ts", + OUTPUT_BOOLEAN_YN, + &ConfigFileEntry.ignore_bogus_ts, + "Ignore bogus timestamps from other servers" + }, + { + "disable_auth", + OUTPUT_BOOLEAN_YN, + &ConfigFileEntry.disable_auth, + "Completely disable ident lookups" + }, + { + "disable_remote_commands", + OUTPUT_BOOLEAN_YN, + &ConfigFileEntry.disable_remote, + "Prevent users issuing commands on remote servers" + }, + { + "tkline_expire_notices", + OUTPUT_BOOLEAN_YN, + &ConfigFileEntry.tkline_expire_notices, + "Show temporary kline/xline expire notices" + }, + { + "default_floodcount", + OUTPUT_DECIMAL, + &ConfigFileEntry.default_floodcount, + "Startup value of FLOODCOUNT" + }, + { + "failed_oper_notice", + OUTPUT_BOOLEAN, + &ConfigFileEntry.failed_oper_notice, + "Inform opers if someone /oper's with the wrong password" + }, + { + "dots_in_ident", + OUTPUT_DECIMAL, + &ConfigFileEntry.dots_in_ident, + "Number of permissable dots in an ident" + }, + { + "min_nonwildcard", + OUTPUT_DECIMAL, + &ConfigFileEntry.min_nonwildcard, + "Minimum non-wildcard chars in K/G lines" + }, + { + "min_nonwildcard_simple", + OUTPUT_DECIMAL, + &ConfigFileEntry.min_nonwildcard_simple, + "Minimum non-wildcards in gecos bans" + }, + { + "max_accept", + OUTPUT_DECIMAL, + &ConfigFileEntry.max_accept, + "Maximum nicknames on accept list" + }, + { + "anti_nick_flood", + OUTPUT_BOOLEAN, + &ConfigFileEntry.anti_nick_flood, + "NICK flood protection" + }, + { + "max_nick_time", + OUTPUT_DECIMAL, + &ConfigFileEntry.max_nick_time, + "NICK flood protection time interval" + }, + { + "max_nick_changes", + OUTPUT_DECIMAL, + &ConfigFileEntry.max_nick_changes, + "NICK change threshhold setting" + }, + { + "anti_spam_exit_message_time", + OUTPUT_DECIMAL, + &ConfigFileEntry.anti_spam_exit_message_time, + "Duration a client must be connected for to have an exit message" + }, + { + "ts_warn_delta", + OUTPUT_DECIMAL, + &ConfigFileEntry.ts_warn_delta, + "Maximum permitted TS delta before displaying a warning" + }, + { + "ts_max_delta", + OUTPUT_DECIMAL, + &ConfigFileEntry.ts_max_delta, + "Maximum permitted TS delta from another server" + }, + { + "warn_no_nline", + OUTPUT_BOOLEAN, + &ConfigFileEntry.warn_no_nline, + "Display warning if connecting server lacks N-line" + }, + { + "stats_o_oper_only", + OUTPUT_BOOLEAN_YN, + &ConfigFileEntry.stats_o_oper_only, + "STATS O output is only shown to operators" + }, + { + "stats_P_oper_only", + OUTPUT_BOOLEAN_YN, + &ConfigFileEntry.stats_P_oper_only, + "STATS P is only shown to operators" + }, + { + "stats_i_oper_only", + OUTPUT_BOOLEAN2, + &ConfigFileEntry.stats_i_oper_only, + "STATS I output is only shown to operators" + }, + { + "stats_k_oper_only", + OUTPUT_BOOLEAN2, + &ConfigFileEntry.stats_k_oper_only, + "STATS K output is only shown to operators" + }, + { + "caller_id_wait", + OUTPUT_DECIMAL, + &ConfigFileEntry.caller_id_wait, + "Minimum delay between notifying UMODE +g users of messages" + }, + { + "opers_bypass_callerid", + OUTPUT_BOOLEAN_YN, + &ConfigFileEntry.opers_bypass_callerid, + "Allows IRC operators to message users who are +g (callerid)" + }, + { + "pace_wait_simple", + OUTPUT_DECIMAL, + &ConfigFileEntry.pace_wait_simple, + "Minimum delay between less intensive commands" + }, + { + "pace_wait", + OUTPUT_DECIMAL, + &ConfigFileEntry.pace_wait, + "Minimum delay between uses of certain commands" + }, + { + "short_motd", + OUTPUT_BOOLEAN_YN, + &ConfigFileEntry.short_motd, + "Do not show MOTD; only tell clients they should read it" + }, + { + "ping_cookie", + OUTPUT_BOOLEAN, + &ConfigFileEntry.ping_cookie, + "Require ping cookies to connect" + }, + { + "no_oper_flood", + OUTPUT_BOOLEAN, + &ConfigFileEntry.no_oper_flood, + "Reduce flood control for operators" + }, + { + "true_no_oper_flood", + OUTPUT_BOOLEAN, + &ConfigFileEntry.true_no_oper_flood, + "Completely disable flood control for operators" + }, + { + "oper_pass_resv", + OUTPUT_BOOLEAN_YN, + &ConfigFileEntry.oper_pass_resv, + "Opers can over-ride RESVs" + }, + { + "max_targets", + OUTPUT_DECIMAL, + &ConfigFileEntry.max_targets, + "The maximum number of PRIVMSG/NOTICE targets" + }, + { + "throttle_time", + OUTPUT_DECIMAL, + &ConfigFileEntry.throttle_time, + "Minimum time between client reconnects" + }, + { + "glines", + OUTPUT_BOOLEAN, + &ConfigFileEntry.glines, + "G-line (network-wide K-line) support" + }, + { + "gline_duration", + OUTPUT_DECIMAL, + &ConfigFileEntry.gline_time, + "Expiry time for G-lines" + }, + + { + "gline_request_duration", + OUTPUT_DECIMAL, + &ConfigFileEntry.gline_request_time, + "Expiry time for pending G-lines" + }, + + /* --[ END OF TABLE ]---------------------------------------------- */ + { + NULL, + 0, + NULL, + 0 + } +}; + +/* +** m_info() +** parv[0] = sender prefix +** parv[1] = servername +*/ +static void +m_info(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + static time_t last_used = 0; + + if ((last_used + ConfigFileEntry.pace_wait) > CurrentTime) + { + /* safe enough to give this on a local connect only */ + sendto_one(source_p, form_str(RPL_LOAD2HI), + me.name, source_p->name); + return; + } + + last_used = CurrentTime; + + if (!ConfigFileEntry.disable_remote) + if (hunt_server(client_p,source_p, ":%s INFO :%s", 1, + parc, parv) != HUNTED_ISME) + return; + + send_info_text(source_p); +} + +/* +** mo_info() +** parv[0] = sender prefix +** parv[1] = servername +*/ +static void +mo_info(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (hunt_server(client_p, source_p, ":%s INFO :%s", 1, + parc, parv) != HUNTED_ISME) + return; + + send_info_text(source_p); +} + +/* +** ms_info() +** parv[0] = sender prefix +** parv[1] = servername +*/ +static void +ms_info(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (!IsClient(source_p)) + return; + + if (hunt_server(client_p, source_p, ":%s INFO :%s", 1, + parc, parv) != HUNTED_ISME) + return; + + send_info_text(source_p); +} + +/* send_info_text() + * + * inputs - client pointer to send info text to + * output - NONE + * side effects - info text is sent to client + */ +static void +send_info_text(struct Client *source_p) +{ + const char **text = infotext; + char *source, *target; + + sendto_realops_flags(UMODE_SPY, L_ALL, + "INFO requested by %s (%s@%s) [%s]", + source_p->name, source_p->username, + source_p->host, source_p->servptr->name); + + if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && + HasID(source_p)) + source = me.id, target = source_p->id; + else + source = me.name, target = source_p->name; + + while (*text) + { + const char *line = *text++; + + if (*line == '\0') + line = " "; + + sendto_one(source_p, form_str(RPL_INFO), + source, target, line); + } + + if (HasUMode(source_p, UMODE_OPER)) + send_conf_options(source_p); + + send_birthdate_online_time(source_p); + + sendto_one(source_p, form_str(RPL_ENDOFINFO), + me.name, source_p->name); +} + +/* send_birthdate_online_time() + * + * inputs - client pointer to send to + * output - NONE + * side effects - birthdate and online time are sent + */ +static void +send_birthdate_online_time(struct Client *source_p) +{ + if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p)) + { + sendto_one(source_p, ":%s %d %s :On-line since %s", + me.id, RPL_INFO, source_p->id, + myctime(me.localClient->firsttime)); + } + else + { + sendto_one(source_p, ":%s %d %s :On-line since %s", + me.name, RPL_INFO, source_p->name, + myctime(me.localClient->firsttime)); + } +} + +/* send_conf_options() + * + * inputs - client pointer to send to + * output - NONE + * side effects - send config options to client + */ +static void +send_conf_options(struct Client *source_p) +{ + const char *from, *to; + const struct InfoStruct *iptr = NULL; + + /* Now send them a list of all our configuration options + * (mostly from defaults.h and config.h) + */ + if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p)) + { + from = me.id; + to = source_p->id; + } + else + { + from = me.name; + to = source_p->name; + } + + /* + * Parse the info_table[] and do the magic. + */ + for (iptr = info_table; iptr->name; ++iptr) + { + switch (iptr->output_type) + { + /* For "char *" references */ + case OUTPUT_STRING: + { + const char *option = *((char **)iptr->option); + + sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]", + from, RPL_INFO, to, + iptr->name, option ? option : "NONE", + iptr->desc ? iptr->desc : "<none>"); + break; + } + + /* For "char foo[]" references */ + case OUTPUT_STRING_PTR: + { + const char *option = iptr->option; + + sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]", + from, RPL_INFO, to, + iptr->name, option ? option : "NONE", + iptr->desc ? iptr->desc : "<none>"); + break; + } + + /* Output info_table[i].option as a decimal value. */ + case OUTPUT_DECIMAL: + { + const int option = *((int *)iptr->option); + + sendto_one(source_p, ":%s %d %s :%-30s %-5d [%-30s]", + from, RPL_INFO, to, iptr->name, + option, iptr->desc ? iptr->desc : "<none>"); + break; + } + + /* Output info_table[i].option as "ON" or "OFF" */ + case OUTPUT_BOOLEAN: + { + const int option = *((int *)iptr->option); + + sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]", + from, RPL_INFO, to, + iptr->name, option ? "ON" : "OFF", + iptr->desc ? iptr->desc : "<none>"); + + break; + } + + /* Output info_table[i].option as "YES" or "NO" */ + case OUTPUT_BOOLEAN_YN: + { + int option = *((int *)iptr->option); + + sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]", + from, RPL_INFO, to, + iptr->name, option ? "YES" : "NO", + iptr->desc ? iptr->desc : "<none>"); + break; + } + + case OUTPUT_BOOLEAN2: + { + int option = *((int *)iptr->option); + + sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]", + from, RPL_INFO, to, + iptr->name, option ? ((option == 1) ? "MASK" : "YES") : "NO", + iptr->desc ? iptr->desc : "<none>"); + break; + } + } + } + + sendto_one(source_p, form_str(RPL_INFO), + from, to, ""); +} + +static struct Message info_msgtab = { + "INFO", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_info, ms_info, m_ignore, mo_info, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&info_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&info_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_invite.c b/modules/m_invite.c new file mode 100644 index 0000000..45ec444 --- /dev/null +++ b/modules/m_invite.c @@ -0,0 +1,179 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_invite.c: Invites the user to join a channel. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "conf.h" +#include "s_serv.h" +#include "parse.h" +#include "modules.h" +#include "packet.h" + + +/* +** m_invite +** parv[0] - sender prefix +** parv[1] - user to invite +** parv[2] - channel name +** parv[3] - invite timestamp +*/ +static void +m_invite(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + struct Channel *chptr = NULL; + struct Membership *ms = NULL; + + if (IsServer(source_p)) + return; + + if (EmptyString(parv[2])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "INVITE"); + return; + } + + if (MyClient(source_p) && !IsFloodDone(source_p)) + flood_endgrace(source_p); + + if ((target_p = find_person(client_p, parv[1])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, parv[1]); + return; + } + + if ((chptr = hash_find_channel(parv[2])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, parv[2]); + return; + } + + if (MyConnect(source_p) && (ms = find_channel_link(source_p, chptr)) == NULL) + { + sendto_one(source_p, form_str(ERR_NOTONCHANNEL), + me.name, source_p->name, chptr->chname); + return; + } + + if (MyConnect(source_p) && !has_member_flags(ms, CHFL_CHANOP)) + { + sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), + me.name, source_p->name, chptr->chname); + return; + } + + if (IsMember(target_p, chptr)) + { + sendto_one(source_p, form_str(ERR_USERONCHANNEL), + me.name, source_p->name, target_p->name, chptr->chname); + return; + } + + if (MyConnect(source_p)) + { + sendto_one(source_p, form_str(RPL_INVITING), me.name, + source_p->name, target_p->name, chptr->chname); + + if (target_p->away[0]) + sendto_one(source_p, form_str(RPL_AWAY), + me.name, source_p->name, target_p->name, + target_p->away); + } + else if (parc > 3 && IsDigit(*parv[3])) + if (atoi(parv[3]) > chptr->channelts) + return; + + if (MyConnect(target_p)) + { + sendto_one(target_p, ":%s!%s@%s INVITE %s :%s", + source_p->name, source_p->username, + source_p->host, + target_p->name, chptr->chname); + + if (chptr->mode.mode & MODE_INVITEONLY) + { + sendto_channel_local(CHFL_CHANOP, 0, chptr, + ":%s NOTICE @%s :%s is inviting %s to %s.", + me.name, chptr->chname, source_p->name, + target_p->name, chptr->chname); + + sendto_channel_remote(source_p, client_p, CHFL_CHANOP, + CAP_TS6, NOCAPS, chptr, + ":%s NOTICE @%s :%s is inviting %s to %s.", + ID(&me), chptr->chname, source_p->name, + target_p->name, chptr->chname); + sendto_channel_remote(source_p, client_p, CHFL_CHANOP, + NOCAPS, CAP_TS6, chptr, + ":%s NOTICE @%s :%s is inviting %s to %s.", + me.name, chptr->chname, source_p->name, + target_p->name, chptr->chname); + /* Add the invite if channel is +i */ + add_invite(chptr, target_p); + } + } + else if (target_p->from != client_p) + sendto_one(target_p, ":%s INVITE %s %s %lu", + ID_or_name(source_p, target_p->from), + ID_or_name(target_p, target_p->from), + chptr->chname, (unsigned long)chptr->channelts); +} + +static struct Message invite_msgtab = { + "INVITE", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_invite, m_invite, m_ignore, m_invite, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&invite_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&invite_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_ison.c b/modules/m_ison.c new file mode 100644 index 0000000..bcd0c8e --- /dev/null +++ b/modules/m_ison.c @@ -0,0 +1,134 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_ison.c: Provides a single line answer of whether a user is online. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "parse.h" +#include "modules.h" + + +static void +do_ison(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + char *nick; + char *p = NULL; + char *current_insert_point = NULL; + char buf[IRCD_BUFSIZE]; + int len; + int i; + int done = 0; + + len = snprintf(buf, sizeof(buf), form_str(RPL_ISON), me.name, source_p->name); + current_insert_point = buf + len; + + /* + * rfc1459 is ambigious about how to handle ISON + * this should handle both interpretations. + */ + for (i = 1; i < parc; i++) + { + for (nick = strtoken(&p, parv[i], " "); nick; + nick = strtoken(&p, NULL, " ")) + { + if ((target_p = find_person(client_p, nick))) + { + len = strlen(target_p->name); + + if ((current_insert_point + (len + 5)) < (buf + sizeof(buf))) + { + memcpy(current_insert_point, target_p->name, len); + current_insert_point += len; + *current_insert_point++ = ' '; + } + else + { + done = 1; + break; + } + } + } + + if (done) + break; + } + + /* + * current_insert_point--; + * Do NOT take out the trailing space, it breaks ircII + * --Rodder + */ + *current_insert_point = '\0'; + + sendto_one(source_p, "%s", buf); +} + +/* + * m_ison added by Darren Reed 13/8/91 to act as an efficent user indicator + * with respect to cpu/bandwidth used. Implemented for NOTIFY feature in + * clients. Designed to reduce number of whois requests. Can process + * nicknames in batches as long as the maximum buffer length. + * + * format: + * ISON :nicklist + */ +static void +m_ison(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + do_ison(client_p, source_p, parc, parv); +} + +static struct Message ison_msgtab = { + "ISON", 0, 0, 1, 1, MFLG_SLOW, 0, + {m_unregistered, m_ison, m_ignore, m_ignore, m_ison, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&ison_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&ison_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_kline.c b/modules/m_kline.c new file mode 100644 index 0000000..8833fe5 --- /dev/null +++ b/modules/m_kline.c @@ -0,0 +1,563 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_kline.c: Bans a user. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "client.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "hostmask.h" +#include "numeric.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "conf.h" +#include "log.h" +#include "s_misc.h" +#include "send.h" +#include "hash.h" +#include "s_serv.h" +#include "s_gline.h" +#include "parse.h" +#include "modules.h" + + +static int already_placed_kline(struct Client *, const char *, const char *, int); +static void apply_kline(struct Client *, struct ConfItem *, const char *, time_t); +static void apply_tkline(struct Client *, struct ConfItem *, int); + +static char buffer[IRCD_BUFSIZE]; +static int remove_tkline_match(const char *, const char *); + + +/* mo_kline() + * + * inputs - pointer to server + * - pointer to client + * - parameter count + * - parameter list + * output - + * side effects - k line is added + */ +static void +mo_kline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *reason = NULL; + char *oper_reason; + char *user = NULL; + char *host = NULL; + const char *current_date; + char *target_server = NULL; + struct ConfItem *conf; + struct AccessItem *aconf; + time_t tkline_time = 0; + time_t cur_time; + + if (!HasOFlag(source_p, OPER_FLAG_K)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "kline"); + return; + } + + if (parse_aline("KLINE", source_p, parc, parv, + AWILD, &user, &host, &tkline_time, &target_server, &reason) < 0) + return; + + if (target_server != NULL) + { + if (HasID(source_p)) + { + sendto_server(NULL, CAP_KLN|CAP_TS6, NOCAPS, + ":%s KLINE %s %lu %s %s :%s", + source_p->id, target_server, (unsigned long)tkline_time, + user, host, reason); + sendto_server(NULL, CAP_KLN, CAP_TS6, + ":%s KLINE %s %lu %s %s :%s", + source_p->name, target_server, (unsigned long)tkline_time, + user, host, reason); + } + else + sendto_server(NULL, CAP_KLN, NOCAPS, + ":%s KLINE %s %lu %s %s :%s", + source_p->name, target_server, (unsigned long)tkline_time, + user, host, reason); + + /* Allow ON to apply local kline as well if it matches */ + if (!match(target_server, me.name)) + return; + } + else + cluster_a_line(source_p, "KLINE", CAP_KLN, SHARED_KLINE, + "%d %s %s :%s", tkline_time, user, host, reason); + + if (already_placed_kline(source_p, user, host, 1)) + return; + + /* Look for an oper reason */ + if ((oper_reason = strchr(reason, '|')) != NULL) + *oper_reason++ = '\0'; + + cur_time = CurrentTime; + current_date = smalldate(cur_time); + conf = make_conf_item(KLINE_TYPE); + aconf = map_to_conf(conf); + + DupString(aconf->host, host); + DupString(aconf->user, user); + + if (tkline_time != 0) + { + snprintf(buffer, sizeof(buffer), "Temporary K-line %d min. - %s (%s)", + (int)(tkline_time/60), reason, current_date); + DupString(aconf->reason, buffer); + + if (oper_reason != NULL) + DupString(aconf->oper_reason, oper_reason); + apply_tkline(source_p, conf, tkline_time); + } + else + { + snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date); + DupString(aconf->reason, buffer); + + if (oper_reason != NULL) + DupString(aconf->oper_reason, oper_reason); + apply_kline(source_p, conf, current_date, cur_time); + } +} + +/* me_kline - handle remote kline. no propagation */ +static void +me_kline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct ConfItem *conf=NULL; + struct AccessItem *aconf=NULL; + int tkline_time; + const char* current_date; + time_t cur_time; + char *kuser, *khost, *kreason, *oper_reason; + + if (parc != 6 || EmptyString(parv[5])) + return; + + if (!match(parv[1], me.name)) + return; + + tkline_time = valid_tkline(parv[2], TK_SECONDS); + kuser = parv[3]; + khost = parv[4]; + kreason = parv[5]; + + if ((oper_reason = strchr(kreason, '|')) != NULL) + *oper_reason++ = '\0'; + + cur_time = CurrentTime; + current_date = smalldate(cur_time); + + if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(ULINE_TYPE, source_p->servptr->name, + source_p->username, source_p->host, + SHARED_KLINE)) + { + if (!IsClient(source_p) || + already_placed_kline(source_p, kuser, khost, 1)) + return; + + conf = make_conf_item(KLINE_TYPE); + aconf = map_to_conf(conf); + DupString(aconf->host, khost); + DupString(aconf->user, kuser); + + if (tkline_time != 0) + { + snprintf(buffer, sizeof(buffer), "Temporary K-line %d min. - %s (%s)", + (int)(tkline_time/60), kreason, current_date); + DupString(aconf->reason, buffer); + + if (oper_reason != NULL) + DupString(aconf->oper_reason, oper_reason); + apply_tkline(source_p, conf, tkline_time); + } + else + { + snprintf(buffer, sizeof(buffer), "%s (%s)", kreason, current_date); + DupString(aconf->reason, buffer); + + if (oper_reason != NULL) + DupString(aconf->oper_reason, oper_reason); + apply_kline(source_p, conf, current_date, cur_time); + } + } +} + +static void +ms_kline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc != 6 || EmptyString(parv[5])) + return; + + /* parv[0] parv[1] parv[2] parv[3] parv[4] parv[5] */ + /* oper target_server tkline_time user host reason */ + sendto_match_servs(source_p, parv[1], CAP_KLN, + "KLINE %s %s %s %s :%s", + parv[1], parv[2], parv[3], parv[4], parv[5]); + + me_kline(client_p, source_p, parc, parv); +} + +/* apply_kline() + * + * inputs - + * output - NONE + * side effects - kline as given, is added to the hashtable + * and conf file + */ +static void +apply_kline(struct Client *source_p, struct ConfItem *conf, + const char *current_date, time_t cur_time) +{ + struct AccessItem *aconf = map_to_conf(conf); + + add_conf_by_address(CONF_KLINE, aconf); + write_conf_line(source_p, conf, current_date, cur_time); + /* Now, activate kline against current online clients */ + rehashed_klines = 1; +} + +/* apply_tkline() + * + * inputs - + * output - NONE + * side effects - tkline as given is placed + */ +static void +apply_tkline(struct Client *source_p, struct ConfItem *conf, + int tkline_time) +{ + struct AccessItem *aconf; + + aconf = (struct AccessItem *)map_to_conf(conf); + aconf->hold = CurrentTime + tkline_time; + SetConfTemporary(aconf); + add_conf_by_address(CONF_KLINE, aconf); + + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s added temporary %d min. K-Line for [%s@%s] [%s]", + get_oper_name(source_p), tkline_time/60, + aconf->user, aconf->host, + aconf->reason); + sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. K-Line [%s@%s]", + MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from), + source_p->name, tkline_time/60, aconf->user, aconf->host); + ilog(LOG_TYPE_KLINE, "%s added temporary %d min. K-Line for [%s@%s] [%s]", + source_p->name, tkline_time/60, + aconf->user, aconf->host, aconf->reason); + + rehashed_klines = 1; +} + +/* already_placed_kline() + * inputs - user to complain to, username & host to check for + * outputs - returns 1 on existing K-line, 0 if doesn't exist + * side effects - notifies source_p if the K-line already exists + */ +/* + * Note: This currently works if the new K-line is a special case of an + * existing K-line, but not the other way round. To do that we would + * have to walk the hash and check every existing K-line. -A1kmm. + */ +static int +already_placed_kline(struct Client *source_p, const char *luser, const char *lhost, int warn) +{ + const char *reason; + struct irc_ssaddr iphost, *piphost; + struct AccessItem *aconf; + int t; + + if ((t = parse_netmask(lhost, &iphost, &t)) != HM_HOST) + { +#ifdef IPV6 + if (t == HM_IPV6) + t = AF_INET6; + else +#endif + t = AF_INET; + piphost = &iphost; + } + else + { + t = 0; + piphost = NULL; + } + + if ((aconf = find_conf_by_address(lhost, piphost, CONF_KLINE, t, luser, NULL, 0))) + { + if (warn) + { + reason = aconf->reason ? aconf->reason : "No reason"; + sendto_one(source_p, + ":%s NOTICE %s :[%s@%s] already K-Lined by [%s@%s] - %s", + me.name, source_p->name, luser, lhost, aconf->user, + aconf->host, reason); + } + + return 1; + } + + return 0; +} + +/* +** mo_unkline +** Added Aug 31, 1997 +** common (Keith Fralick) fralick@gate.net +** +** parv[0] = sender +** parv[1] = address to remove +* +* +*/ +static void +mo_unkline(struct Client *client_p,struct Client *source_p, + int parc, char *parv[]) +{ + char *target_server = NULL; + char *user, *host; + + if (!HasOFlag(source_p, OPER_FLAG_UNKLINE)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "unkline"); + return; + } + + if (parc < 2 || EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "UNKLINE"); + return; + } + + if (parse_aline("UNKLINE", source_p, parc, parv, 0, &user, + &host, NULL, &target_server, NULL) < 0) + return; + + if (target_server != NULL) + { + sendto_match_servs(source_p, target_server, CAP_UNKLN, + "UNKLINE %s %s %s", + target_server, user, host); + + /* Allow ON to apply local unkline as well if it matches */ + if (!match(target_server, me.name)) + return; + } + else + cluster_a_line(source_p, "UNKLINE", CAP_UNKLN, SHARED_UNKLINE, + "%s %s", user, host); + + if (remove_tkline_match(host, user)) + { + sendto_one(source_p, + ":%s NOTICE %s :Un-klined [%s@%s] from temporary K-Lines", + me.name, source_p->name, user, host); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has removed the temporary K-Line for: [%s@%s]", + get_oper_name(source_p), user, host); + ilog(LOG_TYPE_KLINE, "%s removed temporary K-Line for [%s@%s]", + source_p->name, user, host); + return; + } + + if (remove_conf_line(KLINE_TYPE, source_p, user, host) > 0) + { + sendto_one(source_p, ":%s NOTICE %s :K-Line for [%s@%s] is removed", + me.name, source_p->name, user,host); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has removed the K-Line for: [%s@%s]", + get_oper_name(source_p), user, host); + ilog(LOG_TYPE_KLINE, "%s removed K-Line for [%s@%s]", + source_p->name, user, host); + } + else + sendto_one(source_p, ":%s NOTICE %s :No K-Line for [%s@%s] found", + me.name, source_p->name, user, host); +} + +/* me_unkline() + * + * inputs - server + * - client + * - parc + * - parv + * outputs - none + * side effects - if server is authorized, kline is removed + * does not propagate message + */ +static void +me_unkline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *kuser, *khost; + + if (parc != 4) + return; + + kuser = parv[2]; + khost = parv[3]; + + if (!IsClient(source_p) || !match(parv[1], me.name)) + return; + + if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(ULINE_TYPE, + source_p->servptr->name, + source_p->username, source_p->host, + SHARED_UNKLINE)) + { + if (remove_tkline_match(khost, kuser)) + { + sendto_one(source_p, + ":%s NOTICE %s :Un-klined [%s@%s] from temporary K-Lines", + me.name, source_p->name, kuser, khost); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has removed the temporary K-Line for: [%s@%s]", + get_oper_name(source_p), kuser, khost); + ilog(LOG_TYPE_KLINE, "%s removed temporary K-Line for [%s@%s]", + source_p->name, kuser, khost); + return; + } + + if (remove_conf_line(KLINE_TYPE, source_p, kuser, khost) > 0) + { + sendto_one(source_p, ":%s NOTICE %s :K-Line for [%s@%s] is removed", + me.name, source_p->name, kuser, khost); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has removed the K-Line for: [%s@%s]", + get_oper_name(source_p), kuser, khost); + + ilog(LOG_TYPE_KLINE, "%s removed K-Line for [%s@%s]", + source_p->name, kuser, khost); + } + else + sendto_one(source_p, ":%s NOTICE %s :No K-Line for [%s@%s] found", + me.name, source_p->name, kuser, khost); + } +} + +/* ms_unkline - propagates and handles a remote unkline message */ +static void +ms_unkline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc != 4) + return; + + sendto_match_servs(source_p, parv[1], CAP_UNKLN, + "UNKLINE %s %s %s", + parv[1], parv[2], parv[3]); + + me_unkline(client_p, source_p, parc, parv); +} + +/* static int remove_tkline_match(const char *host, const char *user) + * Input: A hostname, a username to unkline. + * Output: returns YES on success, NO if no tkline removed. + * Side effects: Any matching tklines are removed. + */ +static int +remove_tkline_match(const char *host, const char *user) +{ + struct irc_ssaddr iphost, *piphost; + struct AccessItem *aconf; + int t; + + if ((t = parse_netmask(host, &iphost, NULL)) != HM_HOST) + { +#ifdef IPV6 + if (t == HM_IPV6) + t = AF_INET6; + else +#endif + t = AF_INET; + piphost = &iphost; + } + else + { + t = 0; + piphost = NULL; + } + + if ((aconf = find_conf_by_address(host, piphost, CONF_KLINE, t, user, NULL, 0))) + { + if (IsConfTemporary(aconf)) + { + delete_one_address_conf(host, aconf); + return 1; + } + } + + return 0; +} + +static struct Message kline_msgtab = { + "KLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, ms_kline, me_kline, mo_kline, m_ignore} +}; + +static struct Message unkline_msgtab = { + "UNKLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, ms_unkline, me_unkline, mo_unkline, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&kline_msgtab); + mod_add_cmd(&unkline_msgtab); + add_capability("KLN", CAP_KLN, 1); + add_capability("UNKLN", CAP_UNKLN, 1); +} + +static void +module_exit(void) +{ + mod_del_cmd(&kline_msgtab); + mod_del_cmd(&unkline_msgtab); + delete_capability("UNKLN"); + delete_capability("KLN"); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_knock.c b/modules/m_knock.c new file mode 100644 index 0000000..4ce31d0 --- /dev/null +++ b/modules/m_knock.c @@ -0,0 +1,178 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_knock.c: Requests to be invited to a channel. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "conf.h" +#include "parse.h" +#include "modules.h" +#include "s_serv.h" +#include "s_user.h" + + +/* m_knock + * parv[0] = sender prefix + * parv[1] = channel + * + * The KNOCK command has the following syntax: + * :<sender> KNOCK <channel> + * + * If a user is not banned from the channel they can use the KNOCK + * command to have the server NOTICE the channel operators notifying + * they would like to join. Helpful if the channel is invite-only, the + * key is forgotten, or the channel is full (INVITE can bypass each one + * of these conditions. Concept by Dianora <db@db.net> and written by + * <anonymous> + */ +static void +m_knock(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Channel *chptr = NULL; + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "KNOCK"); + return; + } + + if ((chptr = hash_find_channel(parv[1])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, parv[1]); + return; + } + + /* Normal channel, just be sure they aren't on it */ + if (IsMember(source_p, chptr)) + { + sendto_one(source_p, form_str(ERR_KNOCKONCHAN), me.name, + source_p->name, chptr->chname); + return; + } + + if (!((chptr->mode.mode & MODE_INVITEONLY) || (*chptr->mode.key) || + (chptr->mode.limit && dlink_list_length(&chptr->members) >= + chptr->mode.limit))) + { + sendto_one(source_p, form_str(ERR_CHANOPEN), me.name, + source_p->name, chptr->chname); + return; + } + + if (MyClient(source_p)) + { + /* + * Don't allow a knock if the user is banned, or the channel is private + */ + if (PrivateChannel(chptr) || is_banned(chptr, source_p)) + { + sendto_one(source_p, form_str(ERR_CANNOTSENDTOCHAN), + me.name, source_p->name, chptr->chname); + return; + } + + /* + * flood protection: + * allow one knock per user per knock_delay + * allow one knock per channel per knock_delay_channel + * + * we only limit local requests.. + */ + if ((source_p->localClient->last_knock + ConfigChannel.knock_delay) > + CurrentTime) + { + sendto_one(source_p, form_str(ERR_TOOMANYKNOCK), me.name, + source_p->name, chptr->chname, "user"); + return; + } + + if ((chptr->last_knock + ConfigChannel.knock_delay_channel) > CurrentTime) + { + sendto_one(source_p, form_str(ERR_TOOMANYKNOCK), me.name, + source_p->name, chptr->chname, "channel"); + return; + } + + source_p->localClient->last_knock = CurrentTime; + + sendto_one(source_p, form_str(RPL_KNOCKDLVR), me.name, + source_p->name, chptr->chname); + } + + chptr->last_knock = CurrentTime; + + sendto_channel_local(CHFL_CHANOP, 0, chptr, + ":%s NOTICE @%s :KNOCK: %s (%s [%s@%s] has asked for an invite)", + me.name, chptr->chname, chptr->chname, + source_p->name, + source_p->username, + source_p->host); + + sendto_server(client_p, CAP_KNOCK|CAP_TS6, NOCAPS, + ":%s KNOCK %s", ID(source_p), chptr->chname); + sendto_server(client_p, CAP_KNOCK, CAP_TS6, + ":%s KNOCK %s", source_p->name, chptr->chname); +} + +static struct Message knock_msgtab = { + "KNOCK", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_knock, m_knock, m_ignore, m_knock, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&knock_msgtab); + add_capability("KNOCK", CAP_KNOCK, 1); + add_isupport("KNOCK", NULL, -1); +} + +static void +module_exit(void) +{ + mod_del_cmd(&knock_msgtab); + delete_capability("KNOCK"); + delete_isupport("KNOCK"); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_links.c b/modules/m_links.c new file mode 100644 index 0000000..04192d4 --- /dev/null +++ b/modules/m_links.c @@ -0,0 +1,191 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_links.c: Shows what servers are currently connected. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "s_serv.h" +#include "send.h" +#include "conf.h" +#include "motd.h" +#include "parse.h" +#include "modules.h" + + +static void +do_links(struct Client *source_p, int parc, char *parv[]) +{ + sendto_realops_flags(UMODE_SPY, L_ALL, + "LINKS requested by %s (%s@%s) [%s]", + source_p->name, + source_p->username, source_p->host, + source_p->servptr->name); + + if (HasUMode(source_p, UMODE_OPER) || !ConfigServerHide.flatten_links) + { + const char *mask = (parc > 2 ? parv[2] : parv[1]); + const char *me_name, *nick; + dlink_node *ptr; + + me_name = ID_or_name(&me, source_p->from); + nick = ID_or_name(source_p, source_p->from); + + DLINK_FOREACH(ptr, global_serv_list.head) + { + struct Client *target_p = ptr->data; + + /* skip hidden servers */ + if (IsHidden(target_p)) + if (!HasUMode(source_p, UMODE_OPER)) + continue; + + if (!EmptyString(mask) && !match(mask, target_p->name)) + continue; + + /* + * We just send the reply, as if they are here there's either no SHIDE, + * or they're an oper.. + */ + sendto_one(source_p, form_str(RPL_LINKS), + me_name, nick, + target_p->name, target_p->servptr->name, + target_p->hopcount, target_p->info); + } + + sendto_one(source_p, form_str(RPL_ENDOFLINKS), + me_name, nick, + EmptyString(mask) ? "*" : mask); + } + else + { + /* + * Print our own info so at least it looks like a normal links + * then print out the file (which may or may not be empty) + */ + sendto_one(source_p, form_str(RPL_LINKS), + ID_or_name(&me, source_p->from), + ID_or_name(source_p, source_p->from), + me.name, me.name, 0, me.info); + send_message_file(source_p, &ConfigFileEntry.linksfile); + sendto_one(source_p, form_str(RPL_ENDOFLINKS), + ID_or_name(&me, source_p->from), + ID_or_name(source_p, source_p->from), "*"); + } +} + +static void +mo_links(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc > 2) + if (!ConfigFileEntry.disable_remote || HasUMode(source_p, UMODE_OPER)) + if (hunt_server(client_p, source_p, ":%s LINKS %s :%s", 1, + parc, parv) != HUNTED_ISME) + return; + + do_links(source_p, parc, parv); +} + +/* + * m_links - LINKS message handler + * parv[0] = sender prefix + * parv[1] = servername mask + * or + * parv[0] = sender prefix + * parv[1] = server to query + * parv[2] = servername mask + */ +static void +m_links(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + static time_t last_used = 0; + + if ((last_used + ConfigFileEntry.pace_wait) > CurrentTime) + { + sendto_one(source_p, form_str(RPL_LOAD2HI), + me.name, source_p->name); + return; + } + + last_used = CurrentTime; + + if (!ConfigServerHide.flatten_links) + { + mo_links(client_p, source_p, parc, parv); + return; + } + + do_links(source_p, parc, parv); +} + +/* + * ms_links - LINKS message handler + * parv[0] = sender prefix + * parv[1] = servername mask + * or + * parv[0] = sender prefix + * parv[1] = server to query + * parv[2] = servername mask + */ +static void +ms_links(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (hunt_server(client_p, source_p, ":%s LINKS %s :%s", 1, + parc, parv) != HUNTED_ISME) + return; + + if (IsClient(source_p)) + m_links(client_p, source_p, parc, parv); +} + +static struct Message links_msgtab = { + "LINKS", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_links, ms_links, m_ignore, mo_links, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&links_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&links_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_list.c b/modules/m_list.c new file mode 100644 index 0000000..c35fd3b --- /dev/null +++ b/modules/m_list.c @@ -0,0 +1,200 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_list.c: List channel given or all channels. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "conf.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "s_user.h" + + +static void +do_list(struct Client *source_p, int parc, char *parv[]) +{ + struct ListTask *lt; + int no_masked_channels; + + if (source_p->localClient->list_task != NULL) + { + free_list_task(source_p->localClient->list_task, source_p); + sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name); + return; + } + + lt = MyMalloc(sizeof(struct ListTask)); + lt->users_max = UINT_MAX; + lt->created_max = UINT_MAX; + lt->topicts_max = UINT_MAX; + source_p->localClient->list_task = lt; + + no_masked_channels = 1; + + if (parc > 1) + { + char *opt, *save = NULL; + dlink_list *list; + int i, errors = 0; + + for (opt = strtoken(&save, parv[1], ","); opt != NULL; + opt = strtoken(&save, NULL, ",")) + switch (*opt) + { + case '<': if ((i = atoi(opt + 1)) > 0) + lt->users_max = (unsigned int) i - 1; + else + errors = 1; + break; + case '>': if ((i = atoi(opt + 1)) >= 0) + lt->users_min = (unsigned int) i + 1; + else + errors = 1; + break; + case '-': break; + case 'C': + case 'c': switch (*++opt) + { + case '<': if ((i = atoi(opt + 1)) >= 0) + lt->created_max = (unsigned int) (CurrentTime + - 60 * i); + else + errors = 1; + break; + case '>': if ((i = atoi(opt + 1)) >= 0) + lt->created_min = (unsigned int) (CurrentTime + - 60 * i); + else + errors = 1; + break; + default: errors = 1; + } + break; + case 'T': + case 't': switch (*++opt) + { + case '<': if ((i = atoi(opt + 1)) >= 0) + lt->topicts_min = (unsigned int) (CurrentTime + - 60 * i); + else + errors = 1; + break; + case '>': if ((i = atoi(opt + 1)) >= 0) + lt->topicts_max = (unsigned int) (CurrentTime + - 60 * i); + else + errors = 1; + break; + default: errors = 1; + } + break; + default: if (*opt == '!') + { + list = <->hide_mask; + opt++; + } + else list = <->show_mask; + + if (has_wildcards(opt + !!IsChanPrefix(*opt))) + { + if (list == <->show_mask) + no_masked_channels = 0; + } + else if (!IsChanPrefix(*opt)) + errors = 1; + if (!errors) + { + char *s; + DupString(s, opt); + dlinkAdd(s, make_dlink_node(), list); + } + } + if (errors) + { + free_list_task(lt, source_p); + sendto_one(source_p, form_str(ERR_LISTSYNTAX), + me.name, source_p->name); + return; + } + } + + + dlinkAdd(source_p, make_dlink_node(), &listing_client_list); + + sendto_one(source_p, form_str(RPL_LISTSTART), + me.name, source_p->name); + safe_list_channels(source_p, lt, no_masked_channels && + lt->show_mask.head != NULL); +} + +/* +** mo_list +** parv[0] = sender prefix +** parv[1] = channel +*/ +static void +m_list(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + do_list(source_p, parc, parv); +} + +static struct Message list_msgtab = { + "LIST", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_list, m_ignore, m_ignore, m_list, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&list_msgtab); + add_isupport("ELIST", "CMNTU", -1); + add_isupport("SAFELIST", NULL, -1); +} + +static void +module_exit(void) +{ + mod_del_cmd(&list_msgtab); + delete_isupport("ELIST"); + delete_isupport("SAFELIST"); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_locops.c b/modules/m_locops.c new file mode 100644 index 0000000..534758f --- /dev/null +++ b/modules/m_locops.c @@ -0,0 +1,107 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_locops.c: Sends a message to all operators on the local server. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "irc_string.h" +#include "numeric.h" +#include "send.h" +#include "conf.h" +#include "s_user.h" +#include "s_serv.h" +#include "hash.h" +#include "parse.h" +#include "modules.h" + + +/* + * mo_locops - LOCOPS message handler + * (write to *all* local opers currently online) + * parv[0] = sender prefix + * parv[1] = message text + */ +static void +mo_locops(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *message = parv[1]; + + if (EmptyString(message)) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "LOCOPS"); + return; + } + + sendto_wallops_flags(UMODE_LOCOPS, source_p, "LOCOPS - %s", + message); + + cluster_a_line(source_p, "LOCOPS", 0, SHARED_LOCOPS, message); +} + +static void +ms_locops(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc != 3 || EmptyString(parv[2])) + return; + + sendto_server(client_p, CAP_CLUSTER, 0, "LOCOPS %s :%s", + parv[1], parv[2]); + + if (!IsClient(source_p) || !match(parv[1], me.name)) + return; + + if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name, + "*", "*", SHARED_LOCOPS)) + sendto_wallops_flags(UMODE_LOCOPS, source_p, "SLOCOPS - %s", parv[2]); +} + +static struct Message locops_msgtab = { + "LOCOPS", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, ms_locops, m_ignore, mo_locops, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&locops_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&locops_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_lusers.c b/modules/m_lusers.c new file mode 100644 index 0000000..c7c41c5 --- /dev/null +++ b/modules/m_lusers.c @@ -0,0 +1,113 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_lusers.c: Sends user statistics. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "s_serv.h" /* hunt_server */ +#include "s_user.h" /* show_lusers */ +#include "send.h" +#include "conf.h" +#include "parse.h" +#include "modules.h" + + +/* m_lusers - LUSERS message handler + * parv[0] = sender + * parv[1] = host/server mask. + * parv[2] = server to query + * + * 199970918 JRL hacked to ignore parv[1] completely and require parc > 3 + * to cause a force + * + * 2003 hacked parv[1] back in, by request of efnet admins/opers -Dianora + */ +static void +m_lusers(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + static time_t last_used = 0; + + if ((last_used + ConfigFileEntry.pace_wait_simple) > CurrentTime) + { + /* safe enough to give this on a local connect only */ + sendto_one(source_p, form_str(RPL_LOAD2HI), me.name, source_p->name); + return; + } + + last_used = CurrentTime; + + if (parc > 2 && !ConfigFileEntry.disable_remote) + if (hunt_server(client_p, source_p, ":%s LUSERS %s :%s", 2, + parc, parv) != HUNTED_ISME) + return; + + show_lusers(source_p); +} + +/* ms_lusers - LUSERS message handler for servers and opers + * parv[0] = sender + * parv[1] = host/server mask. + * parv[2] = server to query + */ +static void +ms_lusers(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc > 2) + if (hunt_server(client_p, source_p, ":%s LUSERS %s :%s", 2, + parc, parv) != HUNTED_ISME) + return; + + if (IsClient(source_p)) + show_lusers(source_p); +} + +static struct Message lusers_msgtab = { + "LUSERS", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_lusers, ms_lusers, m_ignore, ms_lusers, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&lusers_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&lusers_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_map.c b/modules/m_map.c new file mode 100644 index 0000000..c1969c6 --- /dev/null +++ b/modules/m_map.c @@ -0,0 +1,184 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_map.c: Sends an Undernet compatible map to a user. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "modules.h" +#include "numeric.h" +#include "send.h" +#include "conf.h" +#include "ircd.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "parse.h" + + +static char buf[IRCD_BUFSIZE]; + +/* dump_map() + * dumps server map, called recursively. + */ +static void +dump_map(struct Client *client_p, const struct Client *root_p, + int start_len, char *pbuf) +{ + int cnt = 0, i = 0, l = 0, len = start_len; + int users, dashes; + const dlink_node *ptr = NULL; + char *pb; + + *pbuf= '\0'; + pb = pbuf; + + l = ircsprintf(pb, "%s", root_p->name); + pb += l; + len += l; + + if (root_p->id[0] != '\0') + { + l = ircsprintf(pb, "[%s]", root_p->id); + pb += l; + len += l; + } + + *pb++ = ' '; + len++; + dashes = 50 - len; + + for (i = 0; i < dashes; i++) + *pb++ = '-'; + + *pb++ = ' '; + *pb++ = '|'; + + users = dlink_list_length(&root_p->serv->client_list); + + sprintf(pb, " Users: %5d (%1.1f%%)", users, + 100 * (float)users / (float)Count.total); + + sendto_one(client_p, form_str(RPL_MAP), me.name, client_p->name, buf); + + if (root_p->serv->server_list.head) + { + cnt += dlink_list_length(&root_p->serv->server_list); + + if (cnt) + { + if (pbuf > buf + 3) + { + pbuf[-2] = ' '; + + if (pbuf[-3] == '`') + pbuf[-3] = ' '; + } + } + } + + i = 1; + + DLINK_FOREACH(ptr, root_p->serv->server_list.head) + { + const struct Client *server_p = ptr->data; + + *pbuf = ' '; + + if (i < cnt) + *(pbuf + 1) = '|'; + else + *(pbuf + 1) = '`'; + + *(pbuf + 2) = '-'; + *(pbuf + 3) = ' '; + dump_map(client_p, server_p, start_len + 4, pbuf + 4); + + ++i; + } +} + +/* m_map() + * parv[0] = sender prefix + */ +static void +m_map(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + static time_t last_used = 0; + + if (ConfigServerHide.flatten_links) + { + m_not_oper(client_p, source_p, parc, parv); + return; + } + + if ((last_used + ConfigFileEntry.pace_wait) > CurrentTime) + { + /* safe enough to give this on a local connect only */ + sendto_one(source_p, form_str(RPL_LOAD2HI), + me.name, source_p->name); + return; + } + + last_used = CurrentTime; + + dump_map(source_p, &me, 0, buf); + sendto_one(source_p, form_str(RPL_MAPEND), me.name, source_p->name); +} + +/* mo_map() + * parv[0] = sender prefix + */ +static void +mo_map(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + dump_map(source_p, &me, 0, buf); + sendto_one(source_p, form_str(RPL_MAPEND), me.name, source_p->name); +} + +static struct Message map_msgtab = { + "MAP", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_map, m_ignore, m_ignore, mo_map, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&map_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&map_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_module.c b/modules/m_module.c new file mode 100644 index 0000000..a3a2d34 --- /dev/null +++ b/modules/m_module.c @@ -0,0 +1,263 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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 + */ + +/*! \file m_module.c + * \brief Includes required functions for processing the MODULE command. + * \version $Id$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "conf.h" +#include "log.h" +#include "s_user.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "packet.h" + + + +/*! \brief MODULE command handler (called by operators) + * + * \param client_p Pointer to allocated Client struct with physical connection + * to this server, i.e. with an open socket connected. + * \param source_p Pointer to allocated Client struct from which the message + * originally comes from. This can be a local or remote client. + * \param parc Integer holding the number of supplied arguments. + * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL + * pointers. + * \note Valid arguments for this command are: + * - parv[0] = sender prefix + * - parv[1] = action [LOAD, UNLOAD, RELOAD, LIST] + * - parv[2] = module name + */ +static void +mo_module(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *m_bn = NULL; + struct module *modp = NULL; + int check_core; + + if (!HasOFlag(source_p, OPER_FLAG_MODULE)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "MODULE"); + return; + } + + if (!irccmp(parv[1], "LOAD")) + { + if (EmptyString(parv[2])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "MODULE"); + return; + } + + if (findmodule_byname((m_bn = libio_basename(parv[2]))) != NULL) + { + sendto_one(source_p, ":%s NOTICE %s :Module %s is already loaded", + me.name, source_p->name, m_bn); + return; + } + + load_one_module(parv[2]); + return; + } + + if (!irccmp(parv[1], "UNLOAD")) + { + if (EmptyString(parv[2])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "MODULE"); + return; + } + + if ((modp = findmodule_byname((m_bn = libio_basename(parv[2])))) == NULL) + { + sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded", + me.name, source_p->name, m_bn); + return; + } + + if (modp->flags & MODULE_FLAG_CORE) + { + sendto_one(source_p, + ":%s NOTICE %s :Module %s is a core module and may not be unloaded", + me.name, source_p->name, m_bn); + return; + } + + if (modp->flags & MODULE_FLAG_NOUNLOAD) + { + sendto_one(source_p, + ":%s NOTICE %s :Module %s is a resident module and may not be unloaded", + me.name, source_p->name, m_bn); + return; + } + + if (unload_one_module(m_bn, 1) == -1) + sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded", + me.name, source_p->name, m_bn); + return; + } + + if (!irccmp(parv[1], "RELOAD")) + { + if (EmptyString(parv[2])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "MODULE"); + return; + } + + if (!strcmp(parv[2], "*")) + { + unsigned int modnum = 0; + dlink_node *ptr = NULL, *ptr_next = NULL; + + sendto_one(source_p, ":%s NOTICE %s :Reloading all modules", + me.name, source_p->name); + + modnum = dlink_list_length(&modules_list); + + DLINK_FOREACH_SAFE(ptr, ptr_next, modules_list.head) + { + modp = ptr->data; + + if (!(modp->flags & MODULE_FLAG_NOUNLOAD)) + unload_one_module(modp->name, 0); + } + + load_all_modules(0); + load_conf_modules(); + load_core_modules(0); + + sendto_realops_flags(UMODE_ALL, L_ALL, + "Module Restart: %u modules unloaded, %u modules loaded", + modnum, dlink_list_length(&modules_list)); + ilog(LOG_TYPE_IRCD, "Module Restart: %u modules unloaded, %u modules loaded", + modnum, dlink_list_length(&modules_list)); + return; + } + + if ((modp = findmodule_byname((m_bn = libio_basename(parv[2])))) == NULL) + { + sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded", + me.name, source_p->name, m_bn); + return; + } + + if (modp->flags & MODULE_FLAG_NOUNLOAD) + { + sendto_one(source_p, + ":%s NOTICE %s :Module %s is a resident module and may not be unloaded", + me.name, source_p->name, m_bn); + return; + } + + check_core = (modp->flags & MODULE_FLAG_CORE) != 0; + + if (unload_one_module(m_bn, 1) == -1) + { + sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded", + me.name, source_p->name, m_bn); + return; + } + + if ((load_one_module(parv[2]) == -1) && check_core) + { + sendto_realops_flags(UMODE_ALL, L_ALL, "Error reloading core " + "module: %s: terminating ircd", parv[2]); + ilog(LOG_TYPE_IRCD, "Error loading core module %s: terminating ircd", parv[2]); + exit(0); + } + + return; + } + + if (!irccmp(parv[1], "LIST")) + { + const dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, modules_list.head) + { + modp = ptr->data; + + if (parc > 2 && !match(parv[2], modp->name)) + continue; + + sendto_one(source_p, form_str(RPL_MODLIST), me.name, source_p->name, + modp->name, modp->handle, + modp->version, (modp->flags & MODULE_FLAG_CORE) ?"(core)":""); + } + + sendto_one(source_p, form_str(RPL_ENDOFMODLIST), + me.name, source_p->name); + return; + } + + sendto_one(source_p, ":%s NOTICE %s :%s is not a valid option. " + "Choose from LOAD, UNLOAD, RELOAD, LIST", + me.name, source_p->name, parv[1]); +} + + +static struct Message module_msgtab = { + "MODULE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_module, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&module_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&module_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = MODULE_FLAG_NOUNLOAD +}; diff --git a/modules/m_motd.c b/modules/m_motd.c new file mode 100644 index 0000000..4e0bd1c --- /dev/null +++ b/modules/m_motd.c @@ -0,0 +1,130 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_motd.c: Shows the current message of the day. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "motd.h" +#include "ircd.h" +#include "send.h" +#include "numeric.h" +#include "s_serv.h" /* hunt_server */ +#include "parse.h" +#include "modules.h" +#include "conf.h" + + +static void +do_motd(struct Client *source_p) +{ + sendto_realops_flags(UMODE_SPY, L_ALL, + "MOTD requested by %s (%s@%s) [%s]", + source_p->name, source_p->username, + source_p->host, source_p->servptr->name); + send_message_file(source_p, &ConfigFileEntry.motd); +} + +/* +** m_motd +** parv[0] = sender prefix +** parv[1] = servername +*/ +static void +m_motd(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + static time_t last_used = 0; + + if ((last_used + ConfigFileEntry.pace_wait) > CurrentTime) + { + /* safe enough to give this on a local connect only */ + sendto_one(source_p, form_str(RPL_LOAD2HI), + me.name, source_p->name); + return; + } + + last_used = CurrentTime; + + /* This is safe enough to use during non hidden server mode */ + if (!ConfigFileEntry.disable_remote && !ConfigServerHide.hide_servers) + if (hunt_server(client_p, source_p, ":%s MOTD :%s", 1, + parc, parv) != HUNTED_ISME) + return; + + do_motd(source_p); +} + +/* + * note regarding mo_motd being used twice: + * this is not a kludge. any rate limiting, shide, or whatever + * other access restrictions should be done by the source's server. + * for security's sake, still check that the source is an oper + * for 'oper only' information in the mo_ function(s). + */ + +/* +** mo_motd +** parv[0] = sender prefix +** parv[1] = servername +*/ +static void +mo_motd(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (!IsClient(source_p)) + return; + + if (hunt_server(client_p, source_p, ":%s MOTD :%s", 1, + parc, parv) != HUNTED_ISME) + return; + + do_motd(source_p); +} + +static struct Message motd_msgtab = { + "MOTD", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_motd, mo_motd, m_ignore, mo_motd, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&motd_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&motd_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_names.c b/modules/m_names.c new file mode 100644 index 0000000..ce56eb2 --- /dev/null +++ b/modules/m_names.c @@ -0,0 +1,196 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_names.c: Shows the users who are online. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "s_serv.h" +#include "parse.h" +#include "modules.h" + + +/* names_all_visible_channels() + * + * inputs - pointer to client struct requesting names + * output - none + * side effects - lists all visible channels whee! + */ +static void +names_all_visible_channels(struct Client *source_p) +{ + dlink_node *ptr = NULL; + + /* + * First, do all visible channels (public and the one user self is) + */ + DLINK_FOREACH(ptr, global_channel_list.head) + /* Find users on same channel (defined by chptr) */ + channel_member_names(source_p, ptr->data, 0); +} + +/* names_non_public_non_secret() + * + * inputs - pointer to client struct requesting names + * output - none + * side effects - lists all non public non secret channels + */ +static void +names_non_public_non_secret(struct Client *source_p) +{ + int mlen, tlen, cur_len; + int reply_to_send = 0; + int shown_already; + dlink_node *gc2ptr, *lp; + struct Client *c2ptr; + struct Channel *ch3ptr = NULL; + char buf[IRCD_BUFSIZE]; + char *t; + + mlen = snprintf(buf, sizeof(buf), form_str(RPL_NAMREPLY), + me.name, source_p->name, "*", "*"); + cur_len = mlen; + t = buf + mlen; + + /* Second, do all non-public, non-secret channels in one big sweep */ + DLINK_FOREACH(gc2ptr, global_client_list.head) + { + c2ptr = gc2ptr->data; + + if (!IsClient(c2ptr) || HasUMode(c2ptr, UMODE_INVISIBLE)) + continue; + + shown_already = 0; + + /* We already know the user is not +i. If they are on no common + * channels with source_p, they have not been shown yet. */ + DLINK_FOREACH(lp, c2ptr->channel.head) + { + ch3ptr = ((struct Membership *) lp->data)->chptr; + + if (IsMember(source_p, ch3ptr)) + { + shown_already = 1; + break; + } + } + + if (shown_already) + continue; + + tlen = strlen(c2ptr->name); + if (cur_len + tlen + 1 > IRCD_BUFSIZE - 2) + { + sendto_one(source_p, "%s", buf); + cur_len = mlen; + t = buf + mlen; + } + + strcpy(t, c2ptr->name); + t += tlen; + + *t++ = ' '; + *t = 0; + + cur_len += tlen + 1; + + reply_to_send = 1; + } + + if (reply_to_send) + sendto_one(source_p, "%s", buf); +} + +/* +** m_names +** parv[0] = sender prefix +** parv[1] = channel +*/ +static void +m_names(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Channel *chptr = NULL; + char *s; + char *para = parc > 1 ? parv[1] : NULL; + + if (!EmptyString(para)) + { + while (*para == ',') + ++para; + + if ((s = strchr(para, ',')) != NULL) + *s = '\0'; + + if (*para == '\0') + return; + + if ((chptr = hash_find_channel(para)) != NULL) + channel_member_names(source_p, chptr, 1); + else + sendto_one(source_p, form_str(RPL_ENDOFNAMES), + me.name, source_p->name, para); + } + else + { + names_all_visible_channels(source_p); + names_non_public_non_secret(source_p); + sendto_one(source_p, form_str(RPL_ENDOFNAMES), + me.name, source_p->name, "*"); + } +} + +static struct Message names_msgtab = { + "NAMES", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_names, m_ignore, m_ignore, m_names, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&names_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&names_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_oper.c b/modules/m_oper.c new file mode 100644 index 0000000..c325755 --- /dev/null +++ b/modules/m_oper.c @@ -0,0 +1,161 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_oper.c: Makes a user an IRC Operator. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "conf.h" +#include "log.h" +#include "s_user.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "packet.h" + + + +/* failed_oper_notice() + * + * inputs - pointer to client doing /oper ... + * - pointer to nick they tried to oper as + * - pointer to reason they have failed + * output - nothing + * side effects - notices all opers of the failed oper attempt if enabled + */ +static void +failed_oper_notice(struct Client *source_p, const char *name, + const char *reason) +{ + if (ConfigFileEntry.failed_oper_notice) + sendto_realops_flags(UMODE_ALL, L_ALL, "Failed OPER attempt as %s " + "by %s (%s@%s) - %s", name, source_p->name, + source_p->username, source_p->host, reason); + + ilog(LOG_TYPE_OPER, "Failed OPER attempt as %s " + "by %s (%s@%s) - %s", name, source_p->name, + source_p->username, source_p->host, reason); +} + +/* +** m_oper +** parv[0] = sender prefix +** parv[1] = oper name +** parv[2] = oper password +*/ +static void +m_oper(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct ConfItem *conf; + struct AccessItem *aconf=NULL; + const char *name = parv[1]; + const char *password = parv[2]; + + if (EmptyString(password)) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "OPER"); + return; + } + + /* end the grace period */ + if (!IsFloodDone(source_p)) + flood_endgrace(source_p); + + if ((conf = find_exact_name_conf(OPER_TYPE, source_p, name, NULL, NULL)) == NULL) + { + sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name); + conf = find_exact_name_conf(OPER_TYPE, NULL, name, NULL, NULL); + failed_oper_notice(source_p, name, (conf != NULL) ? + "host mismatch" : "no oper {} block"); + return; + } + + aconf = map_to_conf(conf); + + if (match_conf_password(password, aconf)) + { + if (attach_conf(source_p, conf) != 0) + { + sendto_one(source_p, ":%s NOTICE %s :Can't attach conf!", + me.name, source_p->name); + failed_oper_notice(source_p, name, "can't attach conf!"); + return; + } + + oper_up(source_p); + + ilog(LOG_TYPE_OPER, "OPER %s by %s!%s@%s", + name, source_p->name, source_p->username, source_p->host); + } + else + { + sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name); + failed_oper_notice(source_p, name, "password mismatch"); + } +} + +/* +** mo_oper +** parv[0] = sender prefix +** parv[1] = oper name +** parv[2] = oper password +*/ +static void +mo_oper(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + sendto_one(source_p, form_str(RPL_YOUREOPER), + me.name, source_p->name); +} + +static struct Message oper_msgtab = { + "OPER", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_oper, m_ignore, m_ignore, mo_oper, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&oper_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&oper_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_operwall.c b/modules/m_operwall.c new file mode 100644 index 0000000..4d81f1c --- /dev/null +++ b/modules/m_operwall.c @@ -0,0 +1,137 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_operwall.c: Sends a message to all IRCOps. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "irc_string.h" +#include "numeric.h" +#include "send.h" +#include "s_user.h" +#include "parse.h" +#include "modules.h" +#include "s_serv.h" + + +/* + * mo_operwall - OPERWALL message handler + * (write to *all* local opers currently online) + * parv[0] = sender prefix + * parv[1] = message text + */ +static void +mo_operwall(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *message = parv[1]; + + if (!HasOFlag(source_p, OPER_FLAG_OPERWALL)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "operwall"); + return; + } + + if (EmptyString(message)) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "OPERWALL"); + return; + } + + sendto_server(NULL, CAP_TS6, NOCAPS, + ":%s OPERWALL :%s", ID(source_p), message); + sendto_server(NULL, NOCAPS, CAP_TS6, + ":%s OPERWALL :%s", source_p->name, message); + sendto_wallops_flags(UMODE_OPERWALL, source_p, "OPERWALL - %s", message); +} + +/* + * ms_operwall - OPERWALL message handler + * (write to *all* local opers currently online) + * parv[0] = sender prefix + * parv[1] = message text + */ +static void +ms_operwall(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *message = parv[1]; + + if (EmptyString(message)) + return; + + sendto_server(client_p, CAP_TS6, NOCAPS, ":%s OPERWALL :%s", + ID(source_p), message); + sendto_server(client_p, NOCAPS, CAP_TS6, ":%s OPERWALL :%s", + source_p->name, message); + sendto_wallops_flags(UMODE_OPERWALL, source_p, "OPERWALL - %s", message); +} + +/* + * me_operwall - OPERWALL message handler + * (write to *all* local opers currently online) + * parv[0] = sender prefix + * parv[1] = message text + * + * Lets ms_encap handle propagation. + */ +static void +me_operwall(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *message = parv[1]; + + if (EmptyString(message)) + return; + + sendto_wallops_flags(UMODE_OPERWALL, source_p, "OPERWALL - %s", message); +} + +static struct Message operwall_msgtab = { + "OPERWALL", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, ms_operwall, me_operwall, mo_operwall, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&operwall_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&operwall_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_pass.c b/modules/m_pass.c new file mode 100644 index 0000000..be78c7c --- /dev/null +++ b/modules/m_pass.c @@ -0,0 +1,115 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_pass.c: Used to send a password for a server or client{} block. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" /* client struct */ +#include "irc_string.h" +#include "send.h" /* sendto_one */ +#include "numeric.h" /* ERR_xxx */ +#include "ircd.h" /* me */ +#include "parse.h" +#include "modules.h" +#include "s_serv.h" +#include "s_user.h" + + +/* + * m_pass() - Added Sat, 4 March 1989 + * + * + * mr_pass - PASS message handler + * parv[0] = sender prefix + * parv[1] = password + * parv[2] = optional extra version information + */ +static void +mr_pass(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *password = parv[1]; + + assert(client_p == source_p); + + if (EmptyString(password)) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, + source_p->name[0] ? source_p->name : "*", "PASS"); + return; + } + + MyFree(source_p->localClient->passwd); + if (strlen(password) > PASSWDLEN) + password[PASSWDLEN] = '\0'; + DupString(source_p->localClient->passwd, password); + + if (parc > 2) + { + /* It looks to me as if orabidoo wanted to have more + * than one set of option strings possible here... + * i.e. ":AABBTS" as long as TS was the last two chars + * however, as we are now using CAPAB, I think we can + * safely assume if there is a ":TS" then its a TS server + * -Dianora + */ + if (!irccmp(parv[2], "TS") && source_p->tsinfo == 0) + source_p->tsinfo = TS_DOESTS; + } + + /* only do this stuff if we are doing ts6 */ + if (parc > 4) + { + if (atoi(parv[3]) >= 6 && valid_sid(parv[4])) + { + strlcpy(source_p->id, parv[4], sizeof(source_p->id)); + SetCapable(source_p, CAP_TS6); + } + } +} + +static struct Message pass_msgtab = { + "PASS", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { mr_pass, m_registered, m_ignore, m_ignore, m_registered, mr_pass } +}; + +static void +module_init(void) +{ + mod_add_cmd(&pass_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&pass_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_ping.c b/modules/m_ping.c new file mode 100644 index 0000000..520b00a --- /dev/null +++ b/modules/m_ping.c @@ -0,0 +1,149 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_ping.c: Requests that a PONG message be sent back. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "irc_string.h" +#include "parse.h" +#include "modules.h" +#include "hash.h" +#include "conf.h" +#include "s_serv.h" + + +/* +** m_ping +** parv[0] = sender prefix +** parv[1] = origin +** parv[2] = destination +*/ +static void +m_ping(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p; + char *origin, *destination; + + if (parc < 2 || EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NOORIGIN), + me.name, source_p->name); + return; + } + + origin = parv[1]; + destination = parv[2]; /* Will get NULL or pointer (parc >= 2!!) */ + + if (ConfigFileEntry.disable_remote && !HasUMode(source_p, UMODE_OPER)) + { + sendto_one(source_p, ":%s PONG %s :%s", me.name, + (destination) ? destination : me.name, origin); + return; + } + + if (!EmptyString(destination) && irccmp(destination, me.name) != 0) + { + /* We're sending it across servers.. origin == client_p->name --fl_ */ + origin = client_p->name; + + if ((target_p = hash_find_server(destination)) != NULL) + { + sendto_one(target_p, ":%s PING %s :%s", source_p->name, + origin, destination); + } + else + { + sendto_one(source_p, form_str(ERR_NOSUCHSERVER), + me.name, source_p->name, destination); + return; + } + } + else + sendto_one(source_p, ":%s PONG %s :%s", me.name, + (destination) ? destination : me.name, origin); +} + +static void +ms_ping(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p; + const char *origin, *destination; + + if (parc < 2 || EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NOORIGIN), + me.name, source_p->name); + return; + } + + origin = source_p->name; + destination = parv[2]; /* Will get NULL or pointer (parc >= 2!!) */ + + if (!EmptyString(destination) && irccmp(destination, me.name) != 0 && irccmp(destination, me.id) != 0) + { + if ((target_p = hash_find_server(destination))) + sendto_one(target_p, ":%s PING %s :%s", source_p->name, + origin, destination); + else + { + sendto_one(source_p, form_str(ERR_NOSUCHSERVER), + ID_or_name(&me, client_p), source_p->name, destination); + return; + } + } + else + sendto_one(source_p, ":%s PONG %s :%s", + ID_or_name(&me, client_p), (destination) ? destination : me.name, origin); +} + +static struct Message ping_msgtab = { + "PING", 0, 0, 1, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_ping, ms_ping, m_ignore, m_ping, m_ping} +}; + +static void +module_init(void) +{ + mod_add_cmd(&ping_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&ping_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_pong.c b/modules/m_pong.c new file mode 100644 index 0000000..c12a0a6 --- /dev/null +++ b/modules/m_pong.c @@ -0,0 +1,135 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_pong.c: The reply to a ping message. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "ircd.h" +#include "s_user.h" +#include "client.h" +#include "hash.h" /* for find_client() */ +#include "numeric.h" +#include "conf.h" +#include "send.h" +#include "irc_string.h" +#include "parse.h" +#include "modules.h" + + +static void +ms_pong(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p; + const char *origin, *destination; + + if (parc < 2 || EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NOORIGIN), + me.name, source_p->name); + return; + } + + origin = parv[1]; + destination = parv[2]; + + /* Now attempt to route the PONG, comstud pointed out routable PING + * is used for SPING. routable PING should also probably be left in + * -Dianora + * That being the case, we will route, but only for registered clients (a + * case can be made to allow them only from servers). -Shadowfax + */ + if (!EmptyString(destination) && !match(destination, me.name) && + irccmp(destination, me.id)) + { + if ((target_p = hash_find_client(destination)) || + (target_p = hash_find_server(destination))) + sendto_one(target_p, ":%s PONG %s %s", + source_p->name, origin, destination); + else + { + sendto_one(source_p, form_str(ERR_NOSUCHSERVER), + me.name, source_p->name, destination); + return; + } + } +} + +static void +mr_pong(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + assert(source_p == client_p); + + if (parc == 2 && *parv[1] != '\0') + { + if (ConfigFileEntry.ping_cookie && !source_p->localClient->registration) + { + unsigned int incoming_ping = strtoul(parv[1], NULL, 10); + + if (incoming_ping) + { + if (source_p->localClient->random_ping == incoming_ping) + { + SetPingCookie(source_p); + register_local_user(source_p); + } + else + { + sendto_one(source_p, form_str(ERR_WRONGPONG), me.name, + source_p->name, source_p->localClient->random_ping); + return; + } + } + } + } + else + sendto_one(source_p, form_str(ERR_NOORIGIN), + me.name, source_p->name); +} + +static struct Message pong_msgtab = { + "PONG", 0, 0, 1, MAXPARA, MFLG_SLOW, 0, + {mr_pong, m_ignore, ms_pong, m_ignore, m_ignore, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&pong_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&pong_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_post.c b/modules/m_post.c new file mode 100644 index 0000000..f8e6ff6 --- /dev/null +++ b/modules/m_post.c @@ -0,0 +1,87 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_post.c: Exits the user if unregistered, it is a web form. + * + * Copyright (C) 2001-2002 Hybrid 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 + * + * $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "send.h" +#include "parse.h" +#include "modules.h" + + +/* +** mr_dumb_proxy +** parv[0] = sender prefix +** parv[1] = comment +*/ +static void +mr_dumb_proxy(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + sendto_realops_flags(UMODE_REJ, L_ALL, + "HTTP Proxy disconnected: [%s@%s]", + client_p->username, client_p->host); + exit_client(source_p, source_p, "Client Exit"); +} + +static struct Message post_msgtab = { + "POST", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {mr_dumb_proxy, m_ignore, m_ignore, m_ignore, m_ignore, m_ignore} +}; + +static struct Message get_msgtab = { + "GET", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {mr_dumb_proxy, m_ignore, m_ignore, m_ignore, m_ignore, m_ignore} +}; + +static struct Message put_msgtab = { + "PUT", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {mr_dumb_proxy, m_ignore, m_ignore, m_ignore, m_ignore, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&post_msgtab); + mod_add_cmd(&get_msgtab); + mod_add_cmd(&put_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&post_msgtab); + mod_del_cmd(&get_msgtab); + mod_del_cmd(&put_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_rehash.c b/modules/m_rehash.c new file mode 100644 index 0000000..f73c867 --- /dev/null +++ b/modules/m_rehash.c @@ -0,0 +1,136 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_rehash.c: Re-reads the configuration file. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "irc_string.h" +#include "ircd.h" +#include "list.h" +#include "numeric.h" +#include "irc_res.h" +#include "conf.h" +#include "log.h" +#include "send.h" +#include "parse.h" +#include "modules.h" + + +/* + * mo_rehash - REHASH message handler + * + */ +static void +mo_rehash(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + int found = 0; + + if (!HasOFlag(source_p, OPER_FLAG_REHASH)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "rehash"); + return; + } + + if (parc > 1) + { + if (irccmp(parv[1], "DNS") == 0) + { + sendto_one(source_p, form_str(RPL_REHASHING), me.name, source_p->name, "DNS"); + sendto_realops_flags(UMODE_ALL, L_ALL, "%s is rehashing DNS", + get_oper_name(source_p)); + restart_resolver(); /* re-read /etc/resolv.conf AGAIN? + and close/re-open res socket */ + found = 1; + } + else if (irccmp(parv[1], "FDLIMIT") == 0) + { + sendto_one(source_p, form_str(RPL_REHASHING), me.name, + source_p->name, "FDLIMIT"); + sendto_realops_flags(UMODE_ALL, L_ALL, "%s is updating FDLIMIT", + get_oper_name(source_p)); + recalc_fdlimit(NULL); + found = 1; + } + else if (irccmp(parv[1], "MOTD") == 0) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s is forcing re-reading of MOTD file", + get_oper_name(source_p)); + read_message_file(&ConfigFileEntry.motd); + found = 1; + } + + if (found) + { + ilog(LOG_TYPE_IRCD, "REHASH %s From %s", + parv[1], get_client_name(source_p, HIDE_IP)); + return; + } + else + { + sendto_one(source_p, ":%s NOTICE %s :rehash one of :DNS FDLIMIT " + "MOTD", me.name, source_p->name); + return; + } + } + else + { + sendto_one(source_p, form_str(RPL_REHASHING), + me.name, source_p->name, ConfigFileEntry.configfile); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s is rehashing server config file", + get_oper_name(source_p)); + ilog(LOG_TYPE_IRCD, "REHASH From %s[%s]", + get_oper_name(source_p), source_p->sockhost); + rehash(0); + } +} + +static struct Message rehash_msgtab = { + "REHASH", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_rehash, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&rehash_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&rehash_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_restart.c b/modules/m_restart.c new file mode 100644 index 0000000..50e91ea --- /dev/null +++ b/modules/m_restart.c @@ -0,0 +1,98 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_restart.c: Exits and re-runs ircd. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "restart.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "conf.h" + + +/* + * mo_restart + * + */ +static void +mo_restart(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char buf[IRCD_BUFSIZE]; + + if (!HasOFlag(source_p, OPER_FLAG_RESTART)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "restart"); + return; + } + + if (EmptyString(parv[1])) + { + sendto_one(source_p, ":%s NOTICE %s :Need server name /restart %s", + me.name, source_p->name, me.name); + return; + } + + if (irccmp(parv[1], me.name)) + { + sendto_one(source_p, ":%s NOTICE %s :Mismatch on /restart %s", + me.name, source_p->name, me.name); + return; + } + + snprintf(buf, sizeof(buf), "received RESTART command from %s", + get_oper_name(source_p)); + server_die(buf, 1); +} + +static struct Message restart_msgtab = { + "RESTART", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_restart, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&restart_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&restart_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_resv.c b/modules/m_resv.c new file mode 100644 index 0000000..e733ddc --- /dev/null +++ b/modules/m_resv.c @@ -0,0 +1,434 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_resv.c: Reserves(jupes) a nickname or channel. + * + * Copyright (C) 2001-2002 Hybrid 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 + * + * $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "channel.h" +#include "ircd.h" +#include "irc_string.h" +#include "numeric.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "conf.h" +#include "log.h" +#include "resv.h" +#include "hash.h" + + +static void parse_resv(struct Client *, char *, int, char *); +static void remove_resv(struct Client *, const char *); + + +/* mo_resv() + * parv[0] = sender prefix + * parv[1] = channel/nick to forbid + */ +static void +mo_resv(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *resv = NULL; + char *reason = NULL; + char *target_server = NULL; + time_t tkline_time = 0; + + /* RESV #channel ON irc.server.com :abuse + * RESV kiddie ON irc.server.com :abuse + */ + if (parse_aline("RESV", source_p, parc, parv, + AWILD, &resv, NULL, &tkline_time, &target_server, &reason) < 0) + return; + + if (target_server != NULL) + { + /* if a given expire time is given, ENCAP it */ + if (tkline_time != 0) + sendto_match_servs(source_p, target_server, CAP_ENCAP, + "ENCAP %s RESV %d %s 0 :%s", + target_server, (int)tkline_time, resv, reason); + else + sendto_match_servs(source_p, target_server, CAP_CLUSTER, + "RESV %s %s :%s", + target_server, resv, reason); + /* Allow ON to apply local resv as well if it matches */ + if (!match(target_server, me.name)) + return; + } + else + { + /* RESV #channel :abuse + * RESV kiddie :abuse + */ + if (tkline_time != 0) + cluster_a_line(source_p, "ENCAP", CAP_ENCAP, SHARED_RESV, + "RESV %d %s 0 : %s", (int)tkline_time, resv, reason); + else + cluster_a_line(source_p, "RESV", CAP_KLN, SHARED_RESV, + "%s : %s", resv, reason); + } + + parse_resv(source_p, resv, (int)tkline_time, reason); +} + +/* me_resv() + * + * inputs - server + * - client (oper) + * - parc number of arguments + * - parv list of arguments + * via parv[] + * parv[0] = client name applying resv + * parv[1] = tkline_time + * parv[2] = name + * parv[3] = 0 + * parv[4] = reason + * parc should be 5 + * + * outputs - NONE + * side effects - + */ +static void +me_resv(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc != 5 || !IsClient(source_p)) + return; + + parse_resv(source_p, parv[2], atoi(parv[1]), parv[4]); +} + +/* ms_resv() + * parv[0] = sender prefix + * parv[1] = target server + * parv[2] = channel/nick to resv + * parv[3] = reason + */ +static void +ms_resv(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if ((parc != 4) || EmptyString(parv[3])) + return; + + sendto_match_servs(source_p, parv[1], CAP_CLUSTER, + "RESV %s %s :%s", + parv[1], parv[2], parv[3]); + + if (!IsClient(source_p) || !match(parv[1], me.name)) + return; + + if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(ULINE_TYPE, source_p->servptr->name, + source_p->username, source_p->host, + SHARED_RESV)) + parse_resv(source_p, parv[2], 0, parv[3]); +} + +/* mo_unresv() + * parv[0] = sender prefix + * parv[1] = channel/nick to unforbid + */ +static void +mo_unresv(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *resv = NULL; + char *reason = NULL; + char *target_server = NULL; + + /* UNRESV #channel ON irc.server.com */ + /* UNRESV kiddie ON irc.server.com */ + if (parse_aline("UNRESV", source_p, parc, parv, + 0, &resv, NULL, NULL, &target_server, &reason) < 0) + return; + + if (target_server != NULL) + { + sendto_match_servs(source_p, target_server, CAP_CLUSTER, + "UNRESV %s %s", + target_server, resv); + + /* Allow ON to apply local unresv as well if it matches */ + if (!match(target_server, me.name)) + return; + } + else + cluster_a_line(source_p, "UNRESV", CAP_KLN, SHARED_UNRESV, resv); + + remove_resv(source_p, resv); +} + +/* ms_unresv() + * parv[0] = sender prefix + * parv[1] = target server + * parv[2] = resv to remove + */ +static void +ms_unresv(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if ((parc != 3) || EmptyString(parv[2])) + return; + + sendto_match_servs(source_p, parv[1], CAP_CLUSTER, + "UNRESV %s %s", + parv[1], parv[2]); + + if (!IsClient(source_p) || !match(parv[1], me.name)) + return; + + if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(ULINE_TYPE, source_p->servptr->name, + source_p->username, source_p->host, + SHARED_UNRESV)) + remove_resv(source_p, parv[2]); +} + +/* parse_resv() + * + * inputs - source_p, NULL supported + * - thing to resv + * - time_t if tkline + * - reason + * outputs - none + * side effects - parse resv, create if valid + */ +static void +parse_resv(struct Client *source_p, char *name, int tkline_time, char *reason) +{ + struct ConfItem *conf = NULL; + + if (IsChanPrefix(*name)) + { + struct ResvChannel *resv_p; + + if ((conf = create_channel_resv(name, reason, 0)) == NULL) + { + sendto_one(source_p, + ":%s NOTICE %s :A RESV has already been placed on channel: %s", + me.name, source_p->name, name); + return; + } + + resv_p = map_to_conf(conf); + + if (tkline_time != 0) + { + sendto_one(source_p, + ":%s NOTICE %s :A %d minute %s RESV has been placed on channel: %s", + me.name, source_p->name, + tkline_time/60, + (MyClient(source_p) ? "local" : "remote"), name); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has placed a %d minute %s RESV on channel: %s [%s]", + get_oper_name(source_p), + tkline_time/60, + (MyClient(source_p) ? "local" : "remote"), + resv_p->name, resv_p->reason); + ilog(LOG_TYPE_IRCD, "%s added temporary %d min. RESV for [%s] [%s]", + source_p->name, (int)tkline_time/60, + conf->name, resv_p->reason); + resv_p->hold = CurrentTime + tkline_time; + add_temp_line(conf); + } + else + { + sendto_one(source_p, + ":%s NOTICE %s :A %s RESV has been placed on channel %s", + me.name, source_p->name, + (MyClient(source_p) ? "local" : "remote"), name); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has placed a %s RESV on channel %s : [%s]", + get_oper_name(source_p), + (MyClient(source_p) ? "local" : "remote"), + resv_p->name, resv_p->reason); + write_conf_line(source_p, conf, NULL /* not used */, 0 /* not used */); + } + } + else + { + struct MatchItem *resv_p = NULL; + + if (!valid_wild_card_simple(name)) + { + sendto_one(source_p, ":%s NOTICE %s :Please include at least %d non-wildcard characters with the resv", + me.name, source_p->name, ConfigFileEntry.min_nonwildcard_simple); + return; + } + + if (!HasUMode(source_p, UMODE_ADMIN) && strpbrk(name, "*?#")) + { + sendto_one(source_p, ":%s NOTICE %s :You must be an admin to perform a " + "wildcard RESV", me.name, source_p->name); + return; + } + + if ((conf = create_nick_resv(name, reason, 0)) == NULL) + { + sendto_one(source_p, + ":%s NOTICE %s :A RESV has already been placed on nick %s", + me.name, source_p->name, name); + return; + } + + resv_p = map_to_conf(conf); + + if (tkline_time != 0) + { + sendto_one(source_p, + ":%s NOTICE %s :A %d minute %s RESV has been placed on nick %s : [%s]", + me.name, source_p->name, + tkline_time/60, + (MyClient(source_p) ? "local" : "remote"), + conf->name, resv_p->reason); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has placed a %d minute %s RESV on nick %s : [%s]", + get_oper_name(source_p), + tkline_time/60, + (MyClient(source_p) ? "local" : "remote"), + conf->name, resv_p->reason); + ilog(LOG_TYPE_IRCD, "%s added temporary %d min. RESV for [%s] [%s]", + source_p->name, (int)tkline_time/60, + conf->name, resv_p->reason); + resv_p->hold = CurrentTime + tkline_time; + add_temp_line(conf); + } + else + { + sendto_one(source_p, + ":%s NOTICE %s :A %s RESV has been placed on nick %s : [%s]", + me.name, source_p->name, + (MyClient(source_p) ? "local" : "remote"), + conf->name, resv_p->reason); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has placed a %s RESV on nick %s : [%s]", + get_oper_name(source_p), + (MyClient(source_p) ? "local" : "remote"), + conf->name, resv_p->reason); + write_conf_line(source_p, conf, NULL /* not used */, 0 /* not used */); + } + } +} + +static void +remove_resv(struct Client *source_p, const char *name) +{ + struct ConfItem *conf = NULL; + + if (IsChanPrefix(*name)) + { + struct ResvChannel *resv_p; + + if (resv_channel_list.head == NULL || + !(resv_p = hash_find_resv(name))) + { + sendto_one(source_p, + ":%s NOTICE %s :A RESV does not exist for channel: %s", + me.name, source_p->name, name); + return; + } + + if (resv_p->conf) + { + sendto_one(source_p, + ":%s NOTICE %s :The RESV for channel: %s is in ircd.conf and must be removed by hand.", + me.name, source_p->name, name); + return; + } + + delete_channel_resv(resv_p); + remove_conf_line(CRESV_TYPE, source_p, name, NULL); + + sendto_one(source_p, + ":%s NOTICE %s :The RESV has been removed on channel: %s", + me.name, source_p->name, name); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has removed the RESV for channel: %s", + get_oper_name(source_p), name); + } + else + { + struct MatchItem *resv_p = NULL; + + if ((conf = find_exact_name_conf(NRESV_TYPE, NULL, name, NULL, NULL)) == NULL) + { + sendto_one(source_p, ":%s NOTICE %s :A RESV does not exist for nick: %s", + me.name, source_p->name, name); + return; + } + + resv_p = map_to_conf(conf); + + if (resv_p->action) + { + sendto_one(source_p, + ":%s NOTICE %s :The RESV for nick: %s is in ircd.conf and must be removed by hand.", + me.name, source_p->name, name); + return; + } + + delete_conf_item(conf); + remove_conf_line(NRESV_TYPE, source_p, name, NULL); + + sendto_one(source_p, ":%s NOTICE %s :The RESV has been removed on nick: %s", + me.name, source_p->name, name); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has removed the RESV for nick: %s", + get_oper_name(source_p), name); + } +} + +static struct Message resv_msgtab = { + "RESV", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + { m_ignore, m_not_oper, ms_resv, me_resv, mo_resv, m_ignore } +}; + +static struct Message unresv_msgtab = { + "UNRESV", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_ignore, m_not_oper, ms_unresv, m_ignore, mo_unresv, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&resv_msgtab); + mod_add_cmd(&unresv_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&resv_msgtab); + mod_del_cmd(&unresv_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_services.c b/modules/m_services.c new file mode 100644 index 0000000..d8881f4 --- /dev/null +++ b/modules/m_services.c @@ -0,0 +1,355 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 1999 by the Bahamut Development Team. + * Copyright (C) 2011 by the Hybrid 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 + */ + +/*! \file m_services.c + * \brief Provides service aliases + * \version $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "channel_mode.h" +#include "numeric.h" +#include "conf.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "irc_string.h" +#include "s_user.h" +#include "hash.h" + + +/* + * XXX: Each services alias handler is currently ugly copy&paste. + * Configureable aliases will get implemented. + */ + +static void +m_nickserv(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + + assert(client_p && source_p); + assert(client_p == source_p); + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), + me.name, source_p->name); + return; + } + + if ((target_p = hash_find_server(ConfigFileEntry.service_name))) + { + sendto_one(target_p, ":%s PRIVMSG NickServ@%s :%s", + source_p->name, ConfigFileEntry.service_name, parv[1]); + return; + } + + sendto_one(source_p, form_str(ERR_SERVICESDOWN), + me.name, source_p->name, "NickServ"); +} + +static void +m_chanserv(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + + assert(client_p && source_p); + assert(client_p == source_p); + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), + me.name, source_p->name); + return; + } + + if ((target_p = hash_find_server(ConfigFileEntry.service_name))) + { + sendto_one(target_p, ":%s PRIVMSG ChanServ@%s :%s", + source_p->name, ConfigFileEntry.service_name, parv[1]); + return; + } + + sendto_one(source_p, form_str(ERR_SERVICESDOWN), + me.name, source_p->name, "ChanServ"); +} + +static void +m_memoserv(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + + assert(client_p && source_p); + assert(client_p == source_p); + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), + me.name, source_p->name); + return; + } + + if ((target_p = hash_find_server(ConfigFileEntry.service_name))) + { + sendto_one(target_p, ":%s PRIVMSG MemoServ@%s :%s", + source_p->name, ConfigFileEntry.service_name, parv[1]); + return; + } + + sendto_one(source_p, form_str(ERR_SERVICESDOWN), + me.name, source_p->name, "MemoServ"); +} + +static void +m_operserv(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + + assert(client_p && source_p); + assert(client_p == source_p); + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), + me.name, source_p->name); + return; + } + + if ((target_p = hash_find_server(ConfigFileEntry.service_name))) + { + sendto_one(target_p, ":%s PRIVMSG OperServ@%s :%s", + source_p->name, ConfigFileEntry.service_name, parv[1]); + return; + } + + sendto_one(source_p, form_str(ERR_SERVICESDOWN), + me.name, source_p->name, "OperServ"); +} + +static void +m_statserv(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + + assert(client_p && source_p); + assert(client_p == source_p); + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), + me.name, source_p->name); + return; + } + + if ((target_p = hash_find_server(ConfigFileEntry.service_name))) + { + sendto_one(target_p, ":%s PRIVMSG StatServ@%s :%s", + source_p->name, ConfigFileEntry.service_name, parv[1]); + return; + } + + sendto_one(source_p, form_str(ERR_SERVICESDOWN), + me.name, source_p->name, "StatServ"); +} + +static void +m_helpserv(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + + assert(client_p && source_p); + assert(client_p == source_p); + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), + me.name, source_p->name); + return; + } + + if ((target_p = hash_find_server(ConfigFileEntry.service_name))) + { + sendto_one(target_p, ":%s PRIVMSG HelpServ@%s :%s", + source_p->name, ConfigFileEntry.service_name, parv[1]); + return; + } + + sendto_one(source_p, form_str(ERR_SERVICESDOWN), + me.name, source_p->name, "HelpServ"); +} + +static void +m_botserv(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + + assert(client_p && source_p); + assert(client_p == source_p); + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), + me.name, source_p->name); + return; + } + + if ((target_p = hash_find_server(ConfigFileEntry.service_name))) + { + sendto_one(target_p, ":%s PRIVMSG BotServ@%s :%s", + source_p->name, ConfigFileEntry.service_name, parv[1]); + return; + } + + sendto_one(source_p, form_str(ERR_SERVICESDOWN), + me.name, source_p->name, "BotServ"); +} + + +static struct Message ms_msgtab = { + "MS", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_memoserv, m_ignore, m_ignore, m_memoserv, m_ignore} +}; + +static struct Message ns_msgtab = { + "NS", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_nickserv, m_ignore, m_ignore, m_nickserv, m_ignore} +}; + +static struct Message os_msgtab = { + "OS", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_operserv, m_ignore, m_ignore, m_operserv, m_ignore} +}; + +static struct Message bs_msgtab = { + "BS", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_botserv, m_ignore, m_ignore, m_botserv, m_ignore} +}; + +static struct Message cs_msgtab = { + "CS", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_chanserv, m_ignore, m_ignore, m_chanserv, m_ignore} +}; + +static struct Message ss_msgtab = { + "SS", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_statserv, m_ignore, m_ignore, m_statserv, m_ignore} +}; + +static struct Message hs_msgtab = { + "HS", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_helpserv, m_ignore, m_ignore, m_helpserv, m_ignore} +}; + +static struct Message botserv_msgtab = { + "BOTSERV", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_botserv, m_ignore, m_ignore, m_botserv, m_ignore} +}; + +static struct Message chanserv_msgtab = { + "CHANSERV", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_chanserv, m_ignore, m_ignore, m_chanserv, m_ignore} +}; + +static struct Message memoserv_msgtab = { + "MEMOSERV", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_memoserv, m_ignore, m_ignore, m_memoserv, m_ignore} +}; + +static struct Message nickserv_msgtab = { + "NICKSERV", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_nickserv, m_ignore, m_ignore, m_nickserv, m_ignore} +}; + +static struct Message operserv_msgtab = { + "OPERSERV", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_operserv, m_ignore, m_ignore, m_operserv, m_ignore} +}; + +static struct Message statserv_msgtab = { + "STATSERV", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_statserv, m_ignore, m_ignore, m_statserv, m_ignore} +}; + +static struct Message helpserv_msgtab = { + "HELPSERV", 0, 0, 0, 1, MFLG_SLOW, 0, + {m_unregistered, m_helpserv, m_ignore, m_ignore, m_helpserv, m_ignore} +}; + + +static void +module_init(void) +{ + mod_add_cmd(&botserv_msgtab); + mod_add_cmd(&chanserv_msgtab); + mod_add_cmd(&memoserv_msgtab); + mod_add_cmd(&nickserv_msgtab); + mod_add_cmd(&operserv_msgtab); + mod_add_cmd(&statserv_msgtab); + mod_add_cmd(&helpserv_msgtab); + mod_add_cmd(&bs_msgtab); + mod_add_cmd(&ns_msgtab); + mod_add_cmd(&cs_msgtab); + mod_add_cmd(&ms_msgtab); + mod_add_cmd(&os_msgtab); + mod_add_cmd(&ss_msgtab); + mod_add_cmd(&hs_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&botserv_msgtab); + mod_del_cmd(&chanserv_msgtab); + mod_del_cmd(&memoserv_msgtab); + mod_del_cmd(&nickserv_msgtab); + mod_del_cmd(&operserv_msgtab); + mod_del_cmd(&statserv_msgtab); + mod_del_cmd(&helpserv_msgtab); + mod_del_cmd(&bs_msgtab); + mod_del_cmd(&ns_msgtab); + mod_del_cmd(&cs_msgtab); + mod_del_cmd(&ms_msgtab); + mod_del_cmd(&os_msgtab); + mod_del_cmd(&ss_msgtab); + mod_del_cmd(&hs_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_set.c b/modules/m_set.c new file mode 100644 index 0000000..f17b4a6 --- /dev/null +++ b/modules/m_set.c @@ -0,0 +1,616 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_set.c: Sets a server parameter. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +/* rewritten by jdc */ + +#include "stdinc.h" +#include "client.h" +#include "event.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "s_serv.h" +#include "send.h" +#include "channel.h" +#include "conf.h" +#include "parse.h" +#include "modules.h" +#include "s_user.h" +#include "s_misc.h" + + +/* Structure used for the SET table itself */ +struct SetStruct +{ + const char *name; + void (*handler)(); + const int wants_char; /* 1 if it expects (char *, [int]) */ + const int wants_int; /* 1 if it expects ([char *], int) */ + /* eg: 0, 1 == only an int arg + * eg: 1, 1 == char and int args */ +}; + +static void quote_autoconn(struct Client *, const char *, int); +static void quote_autoconnall(struct Client *, int); +static void quote_floodcount(struct Client *, int); +static void quote_identtimeout(struct Client *, int); +static void quote_max(struct Client *, int); +static void quote_msglocale(struct Client *, char *); +static void quote_spamnum(struct Client *, int); +static void quote_spamtime(struct Client *, int); +static void quote_splitmode(struct Client *, char *); +static void quote_splitnum(struct Client *, int); +static void quote_splitusers(struct Client *, int); +static void list_quote_commands(struct Client *); +static void quote_jfloodtime(struct Client *, int); +static void quote_jfloodcount(struct Client *, int); + +/* + * If this ever needs to be expanded to more than one arg of each + * type, want_char/want_int could be the count of the arguments, + * instead of just a boolean flag... + * + * -davidt + */ + +static const struct SetStruct set_cmd_table[] = +{ + /* name function string arg int arg */ + /* -------------------------------------------------------- */ + { "AUTOCONN", quote_autoconn, 1, 1 }, + { "AUTOCONNALL", quote_autoconnall, 0, 1 }, + { "FLOODCOUNT", quote_floodcount, 0, 1 }, + { "IDENTTIMEOUT", quote_identtimeout, 0, 1 }, + { "MAX", quote_max, 0, 1 }, + { "MSGLOCALE", quote_msglocale, 1, 0 }, + { "SPAMNUM", quote_spamnum, 0, 1 }, + { "SPAMTIME", quote_spamtime, 0, 1 }, + { "SPLITMODE", quote_splitmode, 1, 0 }, + { "SPLITNUM", quote_splitnum, 0, 1 }, + { "SPLITUSERS", quote_splitusers, 0, 1 }, + { "JFLOODTIME", quote_jfloodtime, 0, 1 }, + { "JFLOODCOUNT", quote_jfloodcount, 0, 1 }, + /* -------------------------------------------------------- */ + { NULL, NULL, 0, 0 } +}; + +/* + * list_quote_commands() sends the client all the available commands. + * Four to a line for now. + */ +static void +list_quote_commands(struct Client *source_p) +{ + int j = 0; + const struct SetStruct *tab = set_cmd_table; + const char *names[4] = { "", "", "", "" }; + + sendto_one(source_p, ":%s NOTICE %s :Available QUOTE SET commands:", + me.name, source_p->name); + + for (; tab->handler; ++tab) + { + names[j++] = tab->name; + + if (j > 3) + { + sendto_one(source_p, ":%s NOTICE %s :%s %s %s %s", + me.name, source_p->name, + names[0], names[1], + names[2], names[3]); + j = 0; + names[0] = names[1] = names[2] = names[3] = ""; + } + + } + + if (j) + sendto_one(source_p, ":%s NOTICE %s :%s %s %s %s", + me.name, source_p->name, + names[0], names[1], + names[2], names[3]); +} + +/* SET AUTOCONN */ +static void +quote_autoconn(struct Client *source_p, const char *arg, int newval) +{ + struct AccessItem *aconf; + + if (arg != NULL) + { + struct ConfItem *conf = find_exact_name_conf(SERVER_TYPE, NULL, arg, NULL, NULL); + + if (conf != NULL) + { + aconf = map_to_conf(conf); + if (newval) + SetConfAllowAutoConn(aconf); + else + ClearConfAllowAutoConn(aconf); + + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has changed AUTOCONN for %s to %i", + get_oper_name(source_p), arg, newval); + sendto_one(source_p, + ":%s NOTICE %s :AUTOCONN for %s is now set to %i", + me.name, source_p->name, arg, newval); + } + else + { + sendto_one(source_p, ":%s NOTICE %s :Can't find %s", + me.name, source_p->name, arg); + } + } + else + { + sendto_one(source_p, ":%s NOTICE %s :Please specify a server name!", + me.name, source_p->name); + } +} + +/* SET AUTOCONNALL */ +static void +quote_autoconnall(struct Client *source_p, int newval) +{ + if (newval >= 0) + { + sendto_realops_flags(UMODE_ALL, L_ALL, "%s has changed AUTOCONNALL to %i", + get_oper_name(source_p), newval); + + GlobalSetOptions.autoconn = newval; + } + else + sendto_one(source_p, ":%s NOTICE %s :AUTOCONNALL is currently %i", + me.name, source_p->name, GlobalSetOptions.autoconn); +} + +/* SET FLOODCOUNT */ +static void +quote_floodcount(struct Client *source_p, int newval) +{ + if (newval >= 0) + { + GlobalSetOptions.floodcount = newval; + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has changed FLOODCOUNT to %i", + get_oper_name(source_p), GlobalSetOptions.floodcount); + } + else + sendto_one(source_p, ":%s NOTICE %s :FLOODCOUNT is currently %i", + me.name, source_p->name, GlobalSetOptions.floodcount); +} + +/* SET IDENTTIMEOUT */ +static void +quote_identtimeout(struct Client *source_p, int newval) +{ + if (!HasUMode(source_p, UMODE_ADMIN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "set"); + return; + } + + if (newval > 0) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has changed IDENTTIMEOUT to %d", + get_oper_name(source_p), newval); + GlobalSetOptions.ident_timeout = newval; + } + else + sendto_one(source_p, ":%s NOTICE %s :IDENTTIMEOUT is currently %d", + me.name, source_p->name, GlobalSetOptions.ident_timeout); +} + +/* SET MAX */ +static void +quote_max(struct Client *source_p, int newval) +{ + if (newval > 0) + { + recalc_fdlimit(NULL); + + if (newval > MAXCLIENTS_MAX) + { + sendto_one(source_p, + ":%s NOTICE %s :You cannot set MAXCLIENTS to > %d, restoring to %d", + me.name, source_p->name, MAXCLIENTS_MAX, ServerInfo.max_clients); + return; + } + + if (newval < MAXCLIENTS_MIN) + { + sendto_one(source_p, + ":%s NOTICE %s :You cannot set MAXCLIENTS to < %d, restoring to %d", + me.name, source_p->name, MAXCLIENTS_MIN, ServerInfo.max_clients); + return; + } + + ServerInfo.max_clients = newval; + + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s set new MAXCLIENTS to %d (%d current)", + get_oper_name(source_p), ServerInfo.max_clients, Count.local); + } + else + sendto_one(source_p, ":%s NOTICE %s :Current MAXCLIENTS = %d (%d)", + me.name, source_p->name, ServerInfo.max_clients, Count.local); +} + +/* SET MSGLOCALE */ +static void +quote_msglocale(struct Client *source_p, char *locale) +{ + if (locale != NULL) + { + set_locale(locale); + rebuild_isupport_message_line(); + sendto_one(source_p, ":%s NOTICE %s :Set MSGLOCALE to '%s'", + me.name, source_p->name, get_locale()); + } + else + sendto_one(source_p, ":%s NOTICE %s :MSGLOCALE is currently '%s'", + me.name, source_p->name, get_locale()); +} + +/* SET SPAMNUM */ +static void +quote_spamnum(struct Client *source_p, int newval) +{ + if (newval >= 0) + { + if (newval == 0) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has disabled ANTI_SPAMBOT", source_p->name); + GlobalSetOptions.spam_num = newval; + return; + } + + GlobalSetOptions.spam_num = IRCD_MAX(newval, MIN_SPAM_NUM); + sendto_realops_flags(UMODE_ALL, L_ALL, "%s has changed SPAMNUM to %i", + get_oper_name(source_p), GlobalSetOptions.spam_num); + } + else + sendto_one(source_p, ":%s NOTICE %s :SPAMNUM is currently %i", + me.name, source_p->name, GlobalSetOptions.spam_num); +} + +/* SET SPAMTIME */ +static void +quote_spamtime(struct Client *source_p, int newval) +{ + if (newval > 0) + { + GlobalSetOptions.spam_time = IRCD_MAX(newval, MIN_SPAM_TIME); + sendto_realops_flags(UMODE_ALL, L_ALL, "%s has changed SPAMTIME to %i", + get_oper_name(source_p), GlobalSetOptions.spam_time); + } + else + sendto_one(source_p, ":%s NOTICE %s :SPAMTIME is currently %i", + me.name, source_p->name, GlobalSetOptions.spam_time); +} + +/* this table is what splitmode may be set to */ +static const char *splitmode_values[] = +{ + "OFF", + "ON", + "AUTO", + NULL +}; + +/* this table is what splitmode may be */ +static const char *splitmode_status[] = +{ + "OFF", + "AUTO (OFF)", + "ON", + "AUTO (ON)", + NULL +}; + +/* SET SPLITMODE */ +static void +quote_splitmode(struct Client *source_p, char *charval) +{ + if (charval) + { + int newval; + + for (newval = 0; splitmode_values[newval]; ++newval) + if (irccmp(splitmode_values[newval], charval) == 0) + break; + + /* OFF */ + if (newval == 0) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s is disabling splitmode", + get_oper_name(source_p)); + + splitmode = 0; + splitchecking = 0; + + eventDelete(check_splitmode, NULL); + } + /* ON */ + else if (newval == 1) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s is enabling and activating splitmode", + get_oper_name(source_p)); + + splitmode = 1; + splitchecking = 0; + + /* we might be deactivating an automatic splitmode, so pull the event */ + eventDelete(check_splitmode, NULL); + } + /* AUTO */ + else if (newval == 2) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s is enabling automatic splitmode", + get_oper_name(source_p)); + + splitchecking = 1; + check_splitmode(NULL); + } + } + else + /* if we add splitchecking to splitmode*2 we get a unique table to + * pull values back out of, splitmode can be four states - but you can + * only set to three, which means we cant use the same table --fl_ + */ + sendto_one(source_p, ":%s NOTICE %s :SPLITMODE is currently %s", + me.name, source_p->name, + splitmode_status[(splitchecking + (splitmode * 2))]); +} + +/* SET SPLITNUM */ +static void +quote_splitnum(struct Client *source_p, int newval) +{ + if (newval >= 0) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has changed SPLITNUM to %i", + get_oper_name(source_p), newval); + split_servers = newval; + + if (splitchecking) + check_splitmode(NULL); + } + else + sendto_one(source_p, ":%s NOTICE %s :SPLITNUM is currently %i", + me.name, source_p->name, split_servers); +} + +/* SET SPLITUSERS */ +static void +quote_splitusers(struct Client *source_p, int newval) +{ + if (newval >= 0) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has changed SPLITUSERS to %i", + get_oper_name(source_p), newval); + split_users = newval; + + if (splitchecking) + check_splitmode(NULL); + } + else + sendto_one(source_p, ":%s NOTICE %s :SPLITUSERS is currently %i", + me.name, source_p->name, split_users); +} + +/* SET JFLOODTIME */ +static void +quote_jfloodtime(struct Client *source_p, int newval) +{ + if (newval >= 0) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has changed JFLOODTIME to %i", + get_oper_name(source_p), newval); + GlobalSetOptions.joinfloodtime = newval; + } + else + sendto_one(source_p, ":%s NOTICE %s :JFLOODTIME is currently %i", + me.name, source_p->name, GlobalSetOptions.joinfloodtime); +} + +/* SET JFLOODCOUNT */ +static void +quote_jfloodcount(struct Client *source_p, int newval) +{ + if (newval >= 0) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has changed JFLOODCOUNT to %i", + get_oper_name(source_p), newval); + GlobalSetOptions.joinfloodcount = newval; + } + else + sendto_one(source_p, ":%s NOTICE %s :JFLOODCOUNT is currently %i", + me.name, source_p->name, GlobalSetOptions.joinfloodcount); +} + +/* + * mo_set - SET command handler + * set options while running + */ +static void +mo_set(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + int n; + int newval; + const char *arg = NULL; + const char *intarg = NULL; + const struct SetStruct *tab = set_cmd_table; + + if (!HasOFlag(source_p, OPER_FLAG_SET)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "set"); + return; + } + + if (parc > 1) + { + /* + * Go through all the commands in set_cmd_table, until one is + * matched. + */ + for (; tab->handler; ++tab) + { + if (!irccmp(tab->name, parv[1])) + { + /* + * Command found; now execute the code + */ + n = 2; + + if (tab->wants_char) + arg = parv[n++]; + + if (tab->wants_int) + intarg = parv[n++]; + + if ((n - 1) > parc) + { + if (parc > 2) + sendto_one(source_p, + ":%s NOTICE %s :SET %s expects (\"%s%s\") args", + me.name, source_p->name, tab->name, + (tab->wants_char ? "string, " : ""), + (tab->wants_char ? "int" : "")); + } + + if (parc <= 2) + { + arg = NULL; + intarg = NULL; + } + + if (!strcmp(tab->name, "AUTOCONN") && (parc < 4)) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "SET"); + return; + } + + if (tab->wants_int && (parc > 2)) + { + if (intarg) + { + if (irccmp(intarg, "yes") == 0 || irccmp(intarg, "on") == 0) + newval = 1; + else if (irccmp(intarg, "no") == 0|| irccmp(intarg, "off") == 0) + newval = 0; + else + newval = atoi(intarg); + } + else + newval = -1; + + if (newval < 0) + { + sendto_one(source_p, + ":%s NOTICE %s :Value less than 0 illegal for %s", + me.name, source_p->name, + tab->name); + + return; + } + } + else + newval = -1; + + if (tab->wants_char) + { + if (tab->wants_int) + tab->handler(source_p, arg, newval); + else + tab->handler(source_p, arg); + return; + } + else + { + if (tab->wants_int) + tab->handler(source_p, newval); + else + /* Just in case someone actually wants a + * set function that takes no args.. *shrug* */ + tab->handler(source_p); + return; + } + } + } + + /* + * Code here will be executed when a /QUOTE SET command is not + * found within set_cmd_table. + */ + sendto_one(source_p, ":%s NOTICE %s :Variable not found.", + me.name, source_p->name); + return; + } + + list_quote_commands(source_p); +} + +static struct Message set_msgtab = { + "SET", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, rfc1459_command_send_error, m_ignore, mo_set, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&set_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&set_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_stats.c b/modules/m_stats.c new file mode 100644 index 0000000..2361688 --- /dev/null +++ b/modules/m_stats.c @@ -0,0 +1,1533 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_stats.c: Sends the user statistics or config information. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" /* dlink_node/dlink_list */ +#include "balloc.h" +#include "client.h" /* Client */ +#include "irc_string.h" +#include "ircd.h" /* me */ +#include "listener.h" /* show_ports */ +#include "s_gline.h" +#include "hostmask.h" +#include "numeric.h" /* ERR_xxx */ +#include "send.h" /* sendto_one */ +#include "fdlist.h" /* PF and friends */ +#include "s_bsd.h" /* highest_fd */ +#include "conf.h" /* AccessItem, report_configured_links */ +#include "s_misc.h" /* serv_info */ +#include "s_serv.h" /* hunt_server */ +#include "s_user.h" /* show_opers */ +#include "event.h" /* events */ +#include "dbuf.h" +#include "hook.h" +#include "parse.h" +#include "modules.h" +#include "resv.h" /* report_resv */ +#include "whowas.h" +#include "watch.h" +#include "irc_res.h" + + +const char *from, *to; + +/* + * This is part of the STATS replies. There is no offical numeric for this + * since this isnt an official command, in much the same way as HASH isnt. + * It is also possible that some systems wont support this call or have + * different field names for "struct rusage". + * -avalon + */ +static void +stats_usage(struct Client *source_p, int parc, char *parv[]) +{ + struct rusage rus; + time_t secs; + time_t rup; +#ifdef hz +# define hzz hz +#else +# ifdef HZ +# define hzz HZ +# else + int hzz = 1; +# endif +#endif + + if (getrusage(RUSAGE_SELF, &rus) == -1) + { + sendto_one(source_p, ":%s NOTICE %s :Getruseage error: %s", + me.name, source_p->name, strerror(errno)); + return; + } + + secs = rus.ru_utime.tv_sec + rus.ru_stime.tv_sec; + + if (secs == 0) + secs = 1; + + rup = (CurrentTime - me.localClient->since) * hzz; + + if (rup == 0) + rup = 1; + + sendto_one(source_p, + ":%s %d %s R :CPU Secs %d:%d User %d:%d System %d:%d", + me.name, RPL_STATSDEBUG, source_p->name, (int)(secs/60), (int)(secs%60), + (int)(rus.ru_utime.tv_sec/60), (int)(rus.ru_utime.tv_sec%60), + (int)(rus.ru_stime.tv_sec/60), (int)(rus.ru_stime.tv_sec%60)); + sendto_one(source_p, ":%s %d %s R :RSS %ld ShMem %ld Data %ld Stack %ld", + me.name, RPL_STATSDEBUG, source_p->name, rus.ru_maxrss, + (rus.ru_ixrss / rup), (rus.ru_idrss / rup), + (rus.ru_isrss / rup)); + sendto_one(source_p, ":%s %d %s R :Swaps %d Reclaims %d Faults %d", + me.name, RPL_STATSDEBUG, source_p->name, (int)rus.ru_nswap, + (int)rus.ru_minflt, (int)rus.ru_majflt); + sendto_one(source_p, ":%s %d %s R :Block in %d out %d", + me.name, RPL_STATSDEBUG, source_p->name, (int)rus.ru_inblock, + (int)rus.ru_oublock); + sendto_one(source_p, ":%s %d %s R :Msg Rcv %d Send %d", + me.name, RPL_STATSDEBUG, source_p->name, (int)rus.ru_msgrcv, + (int)rus.ru_msgsnd); + sendto_one(source_p, ":%s %d %s R :Signals %d Context Vol. %d Invol %d", + me.name, RPL_STATSDEBUG, source_p->name, (int)rus.ru_nsignals, + (int)rus.ru_nvcsw, (int)rus.ru_nivcsw); +} + +static void +stats_memory(struct Client *source_p, int parc, char *parv[]) +{ + const dlink_node *gptr = NULL; + const dlink_node *dlink = NULL; + + unsigned int local_client_conf_count = 0; /* local client conf links */ + unsigned int users_counted = 0; /* user structs */ + + unsigned int channel_members = 0; + unsigned int channel_invites = 0; + unsigned int channel_bans = 0; + unsigned int channel_except = 0; + unsigned int channel_invex = 0; + + unsigned int wwu = 0; /* whowas users */ + unsigned int class_count = 0; /* classes */ + unsigned int aways_counted = 0; + unsigned int number_ips_stored; /* number of ip addresses hashed */ + + uint64_t channel_memory = 0; + uint64_t channel_ban_memory = 0; + uint64_t channel_except_memory = 0; + uint64_t channel_invex_memory = 0; + + unsigned int safelist_count = 0; + uint64_t safelist_memory = 0; + + uint64_t wwm = 0; /* whowas array memory used */ + uint64_t conf_memory = 0; /* memory used by conf lines */ + uint64_t mem_ips_stored; /* memory used by ip address hash */ + + uint64_t total_channel_memory = 0; + uint64_t totww = 0; + + unsigned int local_client_count = 0; + unsigned int remote_client_count = 0; + + uint64_t local_client_memory_used = 0; + uint64_t remote_client_memory_used = 0; + + uint64_t total_memory = 0; + unsigned int topic_count = 0; + + unsigned int watch_list_headers = 0; /* watchlist headers */ + unsigned int watch_list_entries = 0; /* watchlist entries */ + uint64_t watch_list_memory = 0; /* watchlist memory used */ + + + DLINK_FOREACH(gptr, global_client_list.head) + { + struct Client *target_p = gptr->data; + + if (MyConnect(target_p)) + { + ++local_client_count; + local_client_conf_count += dlink_list_length(&target_p->localClient->confs); + watch_list_entries += dlink_list_length(&target_p->localClient->watches); + } + else + ++remote_client_count; + + if (IsClient(target_p)) + { + ++users_counted; + + if (target_p->away[0]) + ++aways_counted; + } + } + + /* Count up all channels, ban lists, except lists, Invex lists */ + channel_memory = dlink_list_length(&global_channel_list) * + sizeof(struct Channel); + DLINK_FOREACH(gptr, global_channel_list.head) + { + const struct Ban *actualBan; + const struct Channel *chptr = gptr->data; + + channel_members += dlink_list_length(&chptr->members); + channel_invites += dlink_list_length(&chptr->invites); + + if (chptr->topic[0]) + ++topic_count; + + channel_bans += dlink_list_length(&chptr->banlist); + channel_ban_memory += dlink_list_length(&chptr->banlist) * sizeof(struct Ban); + + DLINK_FOREACH(dlink, chptr->banlist.head) + { + actualBan = dlink->data; + assert(actualBan->who); + + channel_ban_memory += actualBan->len + 1; + channel_ban_memory += strlen(actualBan->who) + 1; + } + + channel_except += dlink_list_length(&chptr->exceptlist); + channel_except_memory += dlink_list_length(&chptr->exceptlist) * sizeof(struct Ban); + + DLINK_FOREACH(dlink, chptr->exceptlist.head) + { + actualBan = dlink->data; + assert(actualBan->who); + + channel_except_memory += actualBan->len + 1; + channel_except_memory += strlen(actualBan->who) + 1; + } + + channel_invex += dlink_list_length(&chptr->invexlist); + channel_invex_memory += dlink_list_length(&chptr->invexlist) * sizeof(struct Ban); + + DLINK_FOREACH(dlink, chptr->invexlist.head) + { + actualBan = dlink->data; + assert(actualBan->who); + + channel_invex_memory += actualBan->len + 1; + channel_invex_memory += strlen(actualBan->who) + 1; + } + } + + if ((safelist_count = dlink_list_length(&listing_client_list))) + { + safelist_memory = safelist_count * sizeof(struct ListTask); + DLINK_FOREACH(gptr, listing_client_list.head) + { + const struct Client *acptr = gptr->data; + + DLINK_FOREACH(dlink, acptr->localClient->list_task->show_mask.head) + safelist_memory += strlen(dlink->data); + + DLINK_FOREACH(dlink, acptr->localClient->list_task->hide_mask.head) + safelist_memory += strlen(dlink->data); + } + } + +#if 0 + /* XXX THIS has to be fixed !!!! -db */ + /* count up all config items */ + DLINK_FOREACH(dlink, ConfigItemList.head) + { + aconf = dlink->data; + conf_memory += aconf->host ? strlen(aconf->host)+1 : 0; + conf_memory += aconf->passwd ? strlen(aconf->passwd)+1 : 0; + conf_memory += aconf->name ? strlen(aconf->name)+1 : 0; + conf_memory += sizeof(struct AccessItem); + } +#endif + /* count up all classes */ + class_count = dlink_list_length(&class_items); + + count_whowas_memory(&wwu, &wwm); + watch_count_memory(&watch_list_headers, &watch_list_memory); + + sendto_one(source_p, ":%s %d %s z :WATCH headers %u(%u) entries %d(%u)", + me.name, RPL_STATSDEBUG, source_p->name, watch_list_headers, + watch_list_memory, watch_list_entries, + watch_list_entries * sizeof(dlink_node) * 2); + + sendto_one(source_p, ":%s %d %s z :Clients %u(%u)", + me.name, RPL_STATSDEBUG, source_p->name, users_counted, + (users_counted * sizeof(struct Client))); + + sendto_one(source_p, ":%s %d %s z :User aways %u", + me.name, RPL_STATSDEBUG, source_p->name, + aways_counted); + + sendto_one(source_p, ":%s %d %s z :Attached confs %u(%llu)", + me.name, RPL_STATSDEBUG, source_p->name, + local_client_conf_count, + (unsigned long long)(local_client_conf_count * sizeof(dlink_node))); + + sendto_one(source_p, ":%s %d %s z :Resv channels %u(%lu) nicks %u(%lu)", + me.name, RPL_STATSDEBUG, source_p->name, + dlink_list_length(&resv_channel_list), + dlink_list_length(&resv_channel_list) * sizeof(struct ResvChannel), + dlink_list_length(&nresv_items), + dlink_list_length(&nresv_items) * sizeof(struct MatchItem)); + + sendto_one(source_p, ":%s %d %s z :Classes %u(%llu)", + me.name, RPL_STATSDEBUG, source_p->name, + class_count, (unsigned long long)(class_count * sizeof(struct ClassItem))); + + sendto_one(source_p, ":%s %d %s z :Channels %uu(%llu) Topics %u(%u)", + me.name, RPL_STATSDEBUG, source_p->name, + dlink_list_length(&global_channel_list), + channel_memory, topic_count, topic_count * + (TOPICLEN + 1 + USERHOST_REPLYLEN)); + + sendto_one(source_p, ":%s %d %s z :Bans %u(%llu)", + me.name, RPL_STATSDEBUG, source_p->name, + channel_bans, channel_ban_memory); + + sendto_one(source_p, ":%s %d %s z :Exceptions %u(%llu)", + me.name, RPL_STATSDEBUG, source_p->name, + channel_except, channel_except_memory); + + sendto_one(source_p, ":%s %d %s z :Invex %u(%llu)", + me.name, RPL_STATSDEBUG, source_p->name, + channel_invex, channel_invex_memory); + + sendto_one(source_p, ":%s %d %s z :Channel members %u(%llu) invites %u(%llu)", + me.name, RPL_STATSDEBUG, source_p->name, channel_members, + (unsigned long long)(channel_members * sizeof(struct Membership)), + channel_invites, (unsigned long long)channel_invites * + sizeof(dlink_node) * 2); + + total_channel_memory = channel_memory + channel_ban_memory + + channel_members * sizeof(struct Membership) + + (channel_invites * sizeof(dlink_node)*2); + + sendto_one(source_p, ":%s %d %s z :Safelist %u(%llu)", + me.name, RPL_STATSDEBUG, source_p->name, + safelist_count, safelist_memory); + + sendto_one(source_p, ":%s %d %s z :Whowas users %u(%llu)", + me.name, RPL_STATSDEBUG, source_p->name, + wwu, (unsigned long long)(wwu * sizeof(struct Client))); + + sendto_one(source_p, ":%s %d %s z :Whowas array %u(%llu)", + me.name, RPL_STATSDEBUG, source_p->name, + NICKNAMEHISTORYLENGTH, wwm); + + totww = wwu * sizeof(struct Client) + wwm; + + count_ip_hash(&number_ips_stored,&mem_ips_stored); + sendto_one(source_p, ":%s %d %s z :iphash %u(%llu)", + me.name, RPL_STATSDEBUG, source_p->name, + number_ips_stored, mem_ips_stored); + + total_memory = totww + total_channel_memory + conf_memory + class_count * + sizeof(struct ClassItem); + sendto_one(source_p, ":%s %d %s z :Total: whowas %llu channel %llu conf %llu", + me.name, RPL_STATSDEBUG, source_p->name, totww, + total_channel_memory, conf_memory); + + local_client_memory_used = local_client_count*(sizeof(struct Client) + sizeof(struct LocalUser)); + total_memory += local_client_memory_used; + sendto_one(source_p, ":%s %d %s z :Local client Memory in use: %u(%llu)", + me.name, RPL_STATSDEBUG, source_p->name, local_client_count, + local_client_memory_used); + + remote_client_memory_used = remote_client_count * sizeof(struct Client); + total_memory += remote_client_memory_used; + sendto_one(source_p, ":%s %d %s z :Remote client Memory in use: %u(%llu)", + me.name, RPL_STATSDEBUG, source_p->name, remote_client_count, + remote_client_memory_used); + + block_heap_report_stats(source_p); + + sendto_one(source_p, + ":%s %d %s z :TOTAL: %llu", + me.name, RPL_STATSDEBUG, source_p->name, + total_memory); +} + +static void +stats_dns_servers(struct Client *source_p) +{ + report_dns_servers(source_p); +} + +static void +stats_connect(struct Client *source_p, int parc, char *parv[]) +{ + report_confitem_types(source_p, SERVER_TYPE); +} + +/* stats_deny() + * + * input - client to report to + * output - none + * side effects - client is given dline list. + */ +static void +stats_deny(struct Client *source_p, int parc, char *parv[]) +{ + struct ConfItem *conf; + struct AccessItem *aconf; + dlink_node *ptr = NULL; + unsigned int i = 0; + + + for (i = 0; i < ATABLE_SIZE; ++i) + { + DLINK_FOREACH(ptr, atable[i].head) + { + struct AddressRec *arec = ptr->data; + + if (arec->type == CONF_DLINE) + { + aconf = arec->aconf; + + /* dont report a tdline as a dline */ + if (aconf->flags & CONF_FLAGS_TEMPORARY) + continue; + + conf = unmap_conf_item(aconf); + + sendto_one(source_p, form_str(RPL_STATSDLINE), + from, to, 'D', aconf->host, aconf->reason, + aconf->oper_reason ? aconf->oper_reason : ""); + } + } + } +} + +/* stats_tdeny() + * + * input - client to report to + * output - none + * side effects - client is given dline list. + */ +static void +stats_tdeny(struct Client *source_p, int parc, char *parv[]) +{ + struct ConfItem *conf; + struct AccessItem *aconf; + dlink_node *ptr = NULL; + unsigned int i = 0; + + + for (i = 0; i < ATABLE_SIZE; ++i) + { + DLINK_FOREACH(ptr, atable[i].head) + { + struct AddressRec *arec = ptr->data; + + if (arec->type == CONF_DLINE) + { + aconf = arec->aconf; + + /* dont report a permanent dline as a tdline */ + if (!(aconf->flags & CONF_FLAGS_TEMPORARY)) + continue; + + conf = unmap_conf_item(aconf); + + sendto_one(source_p, form_str(RPL_STATSDLINE), + from, to, 'd', aconf->host, aconf->reason, + aconf->oper_reason ? aconf->oper_reason : ""); + } + } + } +} + +/* stats_exempt() + * + * input - client to report to + * output - none + * side effects - client is given list of exempt blocks + */ +static void +stats_exempt(struct Client *source_p, int parc, char *parv[]) +{ + struct ConfItem *conf; + struct AccessItem *aconf; + dlink_node *ptr = NULL; + unsigned int i = 0; + + if (ConfigFileEntry.stats_e_disabled) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + from, to); + return; + } + + + for (i = 0; i < ATABLE_SIZE; ++i) + { + DLINK_FOREACH(ptr, atable[i].head) + { + struct AddressRec *arec = ptr->data; + + if (arec->type == CONF_EXEMPTDLINE) + { + aconf = arec->aconf; + + conf = unmap_conf_item(aconf); + + sendto_one(source_p, form_str(RPL_STATSDLINE), + from, to, 'e', aconf->host, + aconf->reason, aconf->oper_reason ? aconf->oper_reason : ""); + } + } + } +} + +static void +stats_events(struct Client *source_p, int parc, char *parv[]) +{ + show_events(source_p); +} + +/* stats_pending_glines() + * + * input - client pointer + * output - none + * side effects - client is shown list of pending glines + */ +static void +stats_pending_glines(struct Client *source_p, int parc, char *parv[]) +{ + const dlink_node *dn_ptr = NULL; + const struct gline_pending *glp_ptr = NULL; + char timebuffer[MAX_DATE_STRING] = { '\0' }; + struct tm *tmptr = NULL; + + if (!ConfigFileEntry.glines) + { + sendto_one(source_p, ":%s NOTICE %s :This server does not support G-Lines", + from, to); + return; + } + + if (dlink_list_length(&pending_glines[GLINE_PENDING_ADD_TYPE]) > 0) + sendto_one(source_p, ":%s NOTICE %s :Pending G-lines", + from, to); + + DLINK_FOREACH(dn_ptr, pending_glines[GLINE_PENDING_ADD_TYPE].head) + { + glp_ptr = dn_ptr->data; + tmptr = localtime(&glp_ptr->vote_1.time_request); + strftime(timebuffer, MAX_DATE_STRING, "%Y/%m/%d %H:%M:%S", tmptr); + + sendto_one(source_p, + ":%s NOTICE %s :1) %s!%s@%s on %s requested gline at %s for %s@%s [%s]", + from, to, glp_ptr->vote_1.oper_nick, + glp_ptr->vote_1.oper_user, glp_ptr->vote_1.oper_host, + glp_ptr->vote_1.oper_server, timebuffer, + glp_ptr->user, glp_ptr->host, glp_ptr->vote_1.reason); + + if (glp_ptr->vote_2.oper_nick[0] != '\0') + { + tmptr = localtime(&glp_ptr->vote_2.time_request); + strftime(timebuffer, MAX_DATE_STRING, "%Y/%m/%d %H:%M:%S", tmptr); + sendto_one(source_p, + ":%s NOTICE %s :2) %s!%s@%s on %s requested gline at %s for %s@%s [%s]", + from, to, glp_ptr->vote_2.oper_nick, + glp_ptr->vote_2.oper_user, glp_ptr->vote_2.oper_host, + glp_ptr->vote_2.oper_server, timebuffer, + glp_ptr->user, glp_ptr->host, glp_ptr->vote_2.reason); + } + } + + sendto_one(source_p, ":%s NOTICE %s :End of Pending G-lines", + from, to); + + if (dlink_list_length(&pending_glines[GLINE_PENDING_DEL_TYPE]) > 0) + sendto_one(source_p, ":%s NOTICE %s :Pending UNG-lines", + from, to); + + DLINK_FOREACH(dn_ptr, pending_glines[GLINE_PENDING_DEL_TYPE].head) + { + glp_ptr = dn_ptr->data; + tmptr = localtime(&glp_ptr->vote_1.time_request); + strftime(timebuffer, MAX_DATE_STRING, "%Y/%m/%d %H:%M:%S", tmptr); + + sendto_one(source_p, + ":%s NOTICE %s :1) %s!%s@%s on %s requested ungline at %s for %s@%s [%s]", + from, to, glp_ptr->vote_1.oper_nick, + glp_ptr->vote_1.oper_user, glp_ptr->vote_1.oper_host, + glp_ptr->vote_1.oper_server, timebuffer, + glp_ptr->user, glp_ptr->host, glp_ptr->vote_1.reason); + + if (glp_ptr->vote_2.oper_nick[0] != '\0') + { + tmptr = localtime(&glp_ptr->vote_2.time_request); + strftime(timebuffer, MAX_DATE_STRING, "%Y/%m/%d %H:%M:%S", tmptr); + sendto_one(source_p, + ":%s NOTICE %s :2) %s!%s@%s on %s requested ungline at %s for %s@%s [%s]", + from, to, glp_ptr->vote_2.oper_nick, + glp_ptr->vote_2.oper_user, glp_ptr->vote_2.oper_host, + glp_ptr->vote_2.oper_server, timebuffer, + glp_ptr->user, glp_ptr->host, glp_ptr->vote_2.reason); + + } + } + + sendto_one(source_p, ":%s NOTICE %s :End of Pending UNG-lines", + from, to); +} + +/* stats_glines() + * + * input - client pointer + * output - none + * side effects - client is shown list of glines + */ +static void +stats_glines(struct Client *source_p, int parc, char *parv[]) +{ + dlink_node *ptr = NULL; + unsigned int i = 0; + + if (!ConfigFileEntry.glines) + { + sendto_one(source_p, ":%s NOTICE %s :This server does not support G-Lines", + from, to); + return; + } + + for (i = 0; i < ATABLE_SIZE; ++i) + { + DLINK_FOREACH(ptr, atable[i].head) + { + const struct AddressRec *arec = ptr->data; + + if (arec->type == CONF_GLINE) + { + const struct AccessItem *aconf = arec->aconf; + + sendto_one(source_p, form_str(RPL_STATSKLINE), + from, to, "G", + aconf->host ? aconf->host : "*", + aconf->user ? aconf->user : "*", + aconf->reason ? aconf->reason : "No reason", "" ); + } + } + } +} + +static void +stats_hubleaf(struct Client *source_p, int parc, char *parv[]) +{ + report_confitem_types(source_p, HUB_TYPE); + report_confitem_types(source_p, LEAF_TYPE); +} + +/* + * show_iline_prefix() + * + * inputs - pointer to struct Client requesting output + * - pointer to struct AccessItem + * - name to which iline prefix will be prefixed to + * output - pointer to static string with prefixes listed in ascii form + * side effects - NONE + */ +static const char * +show_iline_prefix(struct Client *sptr, struct AccessItem *aconf, const char *name) +{ + static char prefix_of_host[USERLEN + 14]; + char *prefix_ptr = prefix_of_host; + + if (IsNoTilde(aconf)) + *prefix_ptr++ = '-'; + if (IsLimitIp(aconf)) + *prefix_ptr++ = '!'; + if (IsNeedIdentd(aconf)) + *prefix_ptr++ = '+'; + if (!IsNeedPassword(aconf)) + *prefix_ptr++ = '&'; + if (IsConfExemptResv(aconf)) + *prefix_ptr++ = '$'; + if (IsNoMatchIp(aconf)) + *prefix_ptr++ = '%'; + if (IsConfDoSpoofIp(aconf)) + *prefix_ptr++ = '='; + if (MyOper(sptr) && IsConfExemptKline(aconf)) + *prefix_ptr++ = '^'; + if (MyOper(sptr) && IsConfExemptGline(aconf)) + *prefix_ptr++ = '_'; + if (MyOper(sptr) && IsConfExemptLimits(aconf)) + *prefix_ptr++ = '>'; + if (IsConfCanFlood(aconf)) + *prefix_ptr++ = '|'; + + strlcpy(prefix_ptr, name, USERLEN+1); + + return prefix_of_host; +} + +static void +report_auth(struct Client *client_p, int parc, char *parv[]) +{ + struct ConfItem *conf; + struct AccessItem *aconf; + dlink_node *ptr = NULL; + unsigned int i; + + + for (i = 0; i < ATABLE_SIZE; ++i) + { + DLINK_FOREACH(ptr, atable[i].head) + { + struct AddressRec *arec = ptr->data; + + if (arec->type == CONF_CLIENT) + { + aconf = arec->aconf; + + if (!MyOper(client_p) && IsConfDoSpoofIp(aconf)) + continue; + + conf = unmap_conf_item(aconf); + + /* We are doing a partial list, based on what matches the u@h of the + * sender, so prepare the strings for comparing --fl_ + */ + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(client_p, form_str(RPL_STATSILINE), me.name, + client_p->name, 'I', + conf->name == NULL ? "*" : conf->name, + show_iline_prefix(client_p, aconf, aconf->user), + IsConfDoSpoofIp(aconf) ? "255.255.255.255" : + aconf->host, aconf->port, + aconf->class_ptr ? aconf->class_ptr->name : "<default>"); + + else + sendto_one(client_p, form_str(RPL_STATSILINE), me.name, + client_p->name, 'I', + conf->name == NULL ? "*" : conf->name, + show_iline_prefix(client_p, aconf, aconf->user), + aconf->host, aconf->port, + aconf->class_ptr ? aconf->class_ptr->name : "<default>"); + } + } + } +} + +static void +stats_auth(struct Client *source_p, int parc, char *parv[]) +{ + /* Oper only, if unopered, return ERR_NOPRIVILEGES */ + if ((ConfigFileEntry.stats_i_oper_only == 2) && !HasUMode(source_p, UMODE_OPER)) + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + from, to); + + /* If unopered, Only return matching auth blocks */ + else if ((ConfigFileEntry.stats_i_oper_only == 1) && !HasUMode(source_p, UMODE_OPER)) + { + struct ConfItem *conf; + struct AccessItem *aconf; + + if (MyConnect(source_p)) + aconf = find_conf_by_address(source_p->host, + &source_p->localClient->ip, + CONF_CLIENT, + source_p->localClient->aftype, + source_p->username, + source_p->localClient->passwd, 1); + else + aconf = find_conf_by_address(source_p->host, NULL, CONF_CLIENT, + 0, source_p->username, NULL, 1); + + if (aconf == NULL) + return; + + conf = unmap_conf_item(aconf); + + sendto_one(source_p, form_str(RPL_STATSILINE), from, + to, 'I', + "*", show_iline_prefix(source_p, aconf, aconf->user), + aconf->host, aconf->port, + aconf->class_ptr ? aconf->class_ptr->name : "<default>"); + } + /* They are opered, or allowed to see all auth blocks */ + else + report_auth(source_p, 0, NULL); +} + +/* report_Klines() + * Inputs: Client to report to, + * type(==0 for perm, !=0 for temporary) + * mask + * Output: None + * Side effects: Reports configured K(or k)-lines to client_p. + */ +static void +report_Klines(struct Client *client_p, int tkline) +{ + struct AccessItem *aconf = NULL; + unsigned int i = 0; + const char *p = NULL; + dlink_node *ptr = NULL; + + if (tkline) + p = "k"; + else + p = "K"; + + for (i = 0; i < ATABLE_SIZE; ++i) + { + DLINK_FOREACH(ptr, atable[i].head) + { + struct AddressRec *arec = ptr->data; + + if (arec->type == CONF_KLINE) + { + if ((tkline && !((aconf = arec->aconf)->flags & CONF_FLAGS_TEMPORARY)) || + (!tkline && ((aconf = arec->aconf)->flags & CONF_FLAGS_TEMPORARY))) + continue; + + if (HasUMode(client_p, UMODE_OPER)) + sendto_one(client_p, form_str(RPL_STATSKLINE), me.name, + client_p->name, p, aconf->host, aconf->user, + aconf->reason, aconf->oper_reason ? aconf->oper_reason : ""); + else + sendto_one(client_p, form_str(RPL_STATSKLINE), me.name, + client_p->name, p, aconf->host, aconf->user, + aconf->reason, ""); + } + } + } +} + +static void +stats_tklines(struct Client *source_p, int parc, char *parv[]) +{ + /* Oper only, if unopered, return ERR_NOPRIVILEGES */ + if ((ConfigFileEntry.stats_k_oper_only == 2) && !HasUMode(source_p, UMODE_OPER)) + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + from, to); + + /* If unopered, Only return matching klines */ + else if ((ConfigFileEntry.stats_k_oper_only == 1) && !HasUMode(source_p, UMODE_OPER)) + { + struct AccessItem *aconf = NULL; + + if (MyConnect(source_p)) + aconf = find_conf_by_address(source_p->host, + &source_p->localClient->ip, + CONF_KLINE, + source_p->localClient->aftype, + source_p->username, NULL, 1); + else + aconf = find_conf_by_address(source_p->host, NULL, CONF_KLINE, + 0, source_p->username, NULL, 1); + + if (aconf == NULL) + return; + + /* dont report a permanent kline as a tkline */ + if (!(aconf->flags & CONF_FLAGS_TEMPORARY)) + return; + + sendto_one(source_p, form_str(RPL_STATSKLINE), from, + to, "k", aconf->host, aconf->user, aconf->reason, ""); + } + /* Theyre opered, or allowed to see all klines */ + else { + report_Klines(source_p, 1); + } +} + +static void +stats_klines(struct Client *source_p, int parc, char *parv[]) +{ + /* Oper only, if unopered, return ERR_NOPRIVILEGES */ + if ((ConfigFileEntry.stats_k_oper_only == 2) && !HasUMode(source_p, UMODE_OPER)) + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + from, to); + + /* If unopered, Only return matching klines */ + else if ((ConfigFileEntry.stats_k_oper_only == 1) && !HasUMode(source_p, UMODE_OPER)) + { + struct AccessItem *aconf = NULL; + + /* search for a kline */ + if (MyConnect(source_p)) + aconf = find_conf_by_address(source_p->host, + &source_p->localClient->ip, + CONF_KLINE, + source_p->localClient->aftype, + source_p->username, NULL, 0); + else + aconf = find_conf_by_address(source_p->host, NULL, CONF_KLINE, + 0, source_p->username, NULL, 0); + + if (aconf == NULL) + return; + + /* dont report a tkline as a kline */ + if (aconf->flags & CONF_FLAGS_TEMPORARY) + return; + + sendto_one(source_p, form_str(RPL_STATSKLINE), from, + to, "K", aconf->host, aconf->user, aconf->reason, ""); + } + /* Theyre opered, or allowed to see all klines */ + else { + report_Klines(source_p, 0); + report_confitem_types(source_p, RKLINE_TYPE); + } +} + +static void +stats_messages(struct Client *source_p, int parc, char *parv[]) +{ + report_messages(source_p); +} + +static void +stats_oper(struct Client *source_p, int parc, char *parv[]) +{ + if (!HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.stats_o_oper_only) + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + from, to); + else + report_confitem_types(source_p, OPER_TYPE); +} + +/* stats_operedup() + * + * input - client pointer + * output - none + * side effects - client is shown a list of active opers + */ +static void +stats_operedup(struct Client *source_p, int parc, char *parv[]) +{ + dlink_node *ptr; + + DLINK_FOREACH(ptr, oper_list.head) + { + const struct Client *target_p = ptr->data; + + if (HasUMode(target_p, UMODE_HIDDEN) && !HasUMode(source_p, UMODE_OPER)) + continue; + + if (MyClient(source_p) && HasUMode(source_p, UMODE_OPER)) + sendto_one(source_p, ":%s %d %s p :[%c][%s] %s (%s@%s) Idle: %d", + from, RPL_STATSDEBUG, to, + HasUMode(target_p, UMODE_ADMIN) ? 'A' : 'O', + oper_privs_as_string(target_p->localClient->operflags), + target_p->name, target_p->username, target_p->host, + (int)(CurrentTime - target_p->localClient->last_privmsg)); + else + sendto_one(source_p, ":%s %d %s p :[%c] %s (%s@%s) Idle: %d", + from, RPL_STATSDEBUG, to, + HasUMode(target_p, UMODE_ADMIN) ? 'A' : 'O', + target_p->name, target_p->username, target_p->host, + (int)(CurrentTime - target_p->localClient->last_privmsg)); + } + + sendto_one(source_p, ":%s %d %s p :%lu OPER(s)", + from, RPL_STATSDEBUG, to, dlink_list_length(&oper_list)); +} + +static void +stats_ports(struct Client *source_p, int parc, char *parv[]) +{ + if (!HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.stats_P_oper_only) + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + from, to); + else + show_ports(source_p); +} + +static void +stats_resv(struct Client *source_p, int parc, char *parv[]) +{ + report_resv(source_p); +} + +static void +stats_service(struct Client *source_p, int parc, char *parv[]) +{ + report_confitem_types(source_p, SERVICE_TYPE); +} + +static void +stats_tstats(struct Client *source_p, int parc, char *parv[]) +{ + const struct Client *target_p = NULL; + const dlink_node *ptr = NULL; + struct ServerStatistics *sp; + struct ServerStatistics tmp; + + sp = &tmp; + memcpy(sp, &ServerStats, sizeof(struct ServerStatistics)); + + /* + * must use the += operator. is_sv is not the number of currently + * active server connections. Note the incrementation in + * s_bsd.c:close_connection. + */ + sp->is_sv += dlink_list_length(&serv_list); + + DLINK_FOREACH(ptr, serv_list.head) + { + target_p = ptr->data; + + sp->is_sbs += target_p->localClient->send.bytes; + sp->is_sbr += target_p->localClient->recv.bytes; + sp->is_sti += CurrentTime - target_p->localClient->firsttime; + } + + sp->is_cl += dlink_list_length(&local_client_list); + + DLINK_FOREACH(ptr, local_client_list.head) + { + target_p = ptr->data; + + sp->is_cbs += target_p->localClient->send.bytes; + sp->is_cbr += target_p->localClient->recv.bytes; + sp->is_cti += CurrentTime - target_p->localClient->firsttime; + } + + sp->is_ni += dlink_list_length(&unknown_list); + + sendto_one(source_p, ":%s %d %s T :accepts %u refused %u", + me.name, RPL_STATSDEBUG, source_p->name, sp->is_ac, sp->is_ref); + sendto_one(source_p, ":%s %d %s T :unknown commands %u prefixes %u", + me.name, RPL_STATSDEBUG, source_p->name, sp->is_unco, sp->is_unpf); + sendto_one(source_p, ":%s %d %s T :nick collisions %u unknown closes %u", + me.name, RPL_STATSDEBUG, source_p->name, sp->is_kill, sp->is_ni); + sendto_one(source_p, ":%s %d %s T :wrong direction %u empty %u", + me.name, RPL_STATSDEBUG, source_p->name, sp->is_wrdi, sp->is_empt); + sendto_one(source_p, ":%s %d %s T :numerics seen %u", + me.name, RPL_STATSDEBUG, source_p->name, sp->is_num); + sendto_one(source_p, ":%s %d %s T :auth successes %u fails %u", + me.name, RPL_STATSDEBUG, source_p->name, sp->is_asuc, sp->is_abad); + sendto_one(source_p, ":%s %d %s T :Client Server", + me.name, RPL_STATSDEBUG, source_p->name); + + sendto_one(source_p, ":%s %d %s T :connected %u %u", + me.name, RPL_STATSDEBUG, source_p->name, + (unsigned int)sp->is_cl, + (unsigned int)sp->is_sv); + sendto_one(source_p, ":%s %d %s T :bytes sent %llu %llu", + me.name, RPL_STATSDEBUG, source_p->name, + sp->is_cbs, sp->is_sbs); + sendto_one(source_p, ":%s %d %s T :bytes recv %llu %llu", + me.name, RPL_STATSDEBUG, source_p->name, + sp->is_cbr, sp->is_sbr); + sendto_one(source_p, ":%s %d %s T :time connected %u %u", + me.name, RPL_STATSDEBUG, source_p->name, + (unsigned int)sp->is_cti, + (unsigned int)sp->is_sti); +} + +static void +stats_uptime(struct Client *source_p, int parc, char *parv[]) +{ + time_t now = CurrentTime - me.localClient->since; + + sendto_one(source_p, form_str(RPL_STATSUPTIME), from, to, + now / 86400, (now / 3600) % 24, (now / 60) % 60, now % 60); + + if (!ConfigFileEntry.disable_remote || HasUMode(source_p, UMODE_OPER)) + sendto_one(source_p, form_str(RPL_STATSCONN), from, to, + Count.max_loc_con, Count.max_loc_cli, Count.totalrestartcount); +} + +static void +stats_shared(struct Client *source_p, int parc, char *parv[]) +{ + report_confitem_types(source_p, ULINE_TYPE); +} + +/* stats_servers() + * + * input - client pointer + * output - none + * side effects - client is shown lists of who connected servers + */ +static void +stats_servers(struct Client *source_p, int parc, char *parv[]) +{ + dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, serv_list.head) + { + const struct Client *target_p = ptr->data; + + sendto_one(source_p, ":%s %d %s v :%s (%s!%s@%s) Idle: %d", + from, RPL_STATSDEBUG, to, target_p->name, + (target_p->serv->by[0] ? target_p->serv->by : "Remote."), + "*", "*", (int)(CurrentTime - target_p->localClient->lasttime)); + } + + sendto_one(source_p, ":%s %d %s v :%u Server(s)", + from, RPL_STATSDEBUG, to, dlink_list_length(&serv_list)); +} + +static void +stats_gecos(struct Client *source_p, int parc, char *parv[]) +{ + report_confitem_types(source_p, XLINE_TYPE); + report_confitem_types(source_p, RXLINE_TYPE); +} + +static void +stats_class(struct Client *source_p, int parc, char *parv[]) +{ + report_confitem_types(source_p, CLASS_TYPE); +} + +static void +stats_servlinks(struct Client *source_p, int parc, char *parv[]) +{ + uint64_t sendB = 0, recvB = 0; + time_t uptime = 0; + dlink_node *ptr = NULL; + + if (ConfigServerHide.flatten_links && !HasUMode(source_p, UMODE_OPER)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + from, to); + return; + } + + DLINK_FOREACH(ptr, serv_list.head) + { + struct Client *target_p = ptr->data; + + sendB += target_p->localClient->send.bytes; + recvB += target_p->localClient->recv.bytes; + + /* ":%s 211 %s %s %u %u %llu %u %llu :%u %u %s" */ + sendto_one(source_p, form_str(RPL_STATSLINKINFO), + from, to, + get_client_name(target_p, HasUMode(source_p, UMODE_ADMIN) ? SHOW_IP : MASK_IP), + dbuf_length(&target_p->localClient->buf_sendq), + target_p->localClient->send.messages, + target_p->localClient->send.bytes >> 10, + target_p->localClient->recv.messages, + target_p->localClient->recv.bytes >> 10, + (unsigned)(CurrentTime - target_p->localClient->firsttime), + (CurrentTime > target_p->localClient->since) ? (unsigned)(CurrentTime - target_p->localClient->since): 0, + HasUMode(source_p, UMODE_OPER) ? show_capabilities(target_p) : "TS"); + } + + sendB >>= 10; + recvB >>= 10; + + sendto_one(source_p, ":%s %d %s ? :%u total server(s)", + from, RPL_STATSDEBUG, to, dlink_list_length(&serv_list)); + sendto_one(source_p, ":%s %d %s ? :Sent total : %7.2f %s", + from, RPL_STATSDEBUG, to, + _GMKv(sendB), _GMKs(sendB)); + sendto_one(source_p, ":%s %d %s ? :Recv total : %7.2f %s", + from, RPL_STATSDEBUG, to, + _GMKv(recvB), _GMKs(recvB)); + + uptime = (CurrentTime - me.localClient->since); + + sendto_one(source_p, ":%s %d %s ? :Server send: %7.2f %s (%4.1f K/s)", + from, RPL_STATSDEBUG, to, + _GMKv((me.localClient->send.bytes>>10)), + _GMKs((me.localClient->send.bytes>>10)), + (float)((float)((me.localClient->send.bytes) >> 10) / + (float)uptime)); + sendto_one(source_p, ":%s %d %s ? :Server recv: %7.2f %s (%4.1f K/s)", + from, RPL_STATSDEBUG, to, + _GMKv((me.localClient->recv.bytes>>10)), + _GMKs((me.localClient->recv.bytes>>10)), + (float)((float)((me.localClient->recv.bytes) >> 10) / + (float)uptime)); +} + +/* parse_stats_args() + * + * inputs - arg count + * - args + * - doall flag + * - wild card or not + * output - pointer to name to use + * side effects - + * common parse routine for m_stats args + * + */ +static char * +parse_stats_args(int parc, char *parv[], int *doall, int *wilds) +{ + char *name; + + if (parc > 2) + { + name = parv[2]; + + if (!irccmp(name, from)) + *doall = 2; + else if (match(name, from)) + *doall = 1; + + *wilds = has_wildcards(name); + + return name; + } + + return NULL; +} + +static void +stats_L_list(struct Client *source_p,char *name, int doall, int wilds, + dlink_list *list,char statchar) +{ + dlink_node *ptr; + struct Client *target_p; + + /* + * send info about connections which match, or all if the + * mask matches from. Only restrictions are on those who + * are invisible not being visible to 'foreigners' who use + * a wild card based search to list it. + */ + DLINK_FOREACH(ptr, list->head) + { + target_p = ptr->data; + + if (HasUMode(target_p, UMODE_INVISIBLE) && (doall || wilds) && + !(MyConnect(source_p) && HasUMode(source_p, UMODE_OPER)) && + !HasUMode(target_p, UMODE_OPER) && (target_p != source_p)) + continue; + if (!doall && wilds && !match(name, target_p->name)) + continue; + if (!(doall || wilds) && irccmp(name, target_p->name)) + continue; + + /* This basically shows ips for our opers if its not a server/admin, or + * its one of our admins. */ + if(MyClient(source_p) && HasUMode(source_p, UMODE_OPER) && + (HasUMode(source_p, UMODE_ADMIN) || + (!IsServer(target_p) && !HasUMode(target_p, UMODE_ADMIN) && + !IsHandshake(target_p) && !IsConnecting(target_p)))) + { + sendto_one(source_p, form_str(RPL_STATSLINKINFO), + from, to, + (IsUpper(statchar)) ? + get_client_name(target_p, SHOW_IP) : + get_client_name(target_p, HIDE_IP), + dbuf_length(&target_p->localClient->buf_sendq), + target_p->localClient->send.messages, + target_p->localClient->send.bytes>>10, + target_p->localClient->recv.messages, + target_p->localClient->recv.bytes>>10, + (unsigned)(CurrentTime - target_p->localClient->firsttime), + (CurrentTime > target_p->localClient->since) ? (unsigned)(CurrentTime - target_p->localClient->since):0, + IsServer(target_p) ? show_capabilities(target_p) : "-"); + } + else + { + /* If its a hidden ip, an admin, or a server, mask the real IP */ + if(IsIPSpoof(target_p) || IsServer(target_p) || HasUMode(target_p, UMODE_ADMIN) + || IsHandshake(target_p) || IsConnecting(target_p)) + sendto_one(source_p, form_str(RPL_STATSLINKINFO), + from, to, + get_client_name(target_p, MASK_IP), + dbuf_length(&target_p->localClient->buf_sendq), + target_p->localClient->send.messages, + target_p->localClient->send.bytes>>10, + target_p->localClient->recv.messages, + target_p->localClient->recv.bytes>>10, + (unsigned)(CurrentTime - target_p->localClient->firsttime), + (CurrentTime > target_p->localClient->since) ? (unsigned)(CurrentTime - target_p->localClient->since):0, + IsServer(target_p) ? show_capabilities(target_p) : "-"); + else /* show the real IP */ + sendto_one(source_p, form_str(RPL_STATSLINKINFO), + from, to, + (IsUpper(statchar)) ? + get_client_name(target_p, SHOW_IP) : + get_client_name(target_p, HIDE_IP), + dbuf_length(&target_p->localClient->buf_sendq), + target_p->localClient->send.messages, + target_p->localClient->send.bytes>>10, + target_p->localClient->recv.messages, + target_p->localClient->recv.bytes>>10, + (unsigned)(CurrentTime - target_p->localClient->firsttime), + (CurrentTime > target_p->localClient->since) ? (unsigned)(CurrentTime - target_p->localClient->since):0, + IsServer(target_p) ? show_capabilities(target_p) : "-"); + } + } +} + +/* + * stats_L + * + * inputs - pointer to client to report to + * - doall flag + * - wild card or not + * output - NONE + * side effects - + */ +static void +stats_L(struct Client *source_p,char *name,int doall, + int wilds,char statchar) +{ + stats_L_list(source_p, name, doall, wilds, &unknown_list, statchar); + stats_L_list(source_p, name, doall, wilds, &local_client_list, statchar); + stats_L_list(source_p, name, doall, wilds, &serv_list, statchar); +} + +static void +stats_ltrace(struct Client *source_p, int parc, char *parv[]) +{ + int doall = 0; + int wilds = 0; + char *name = NULL; + char statchar; + + if ((name = parse_stats_args(parc, parv, &doall, &wilds)) != NULL) + { + statchar = parv[1][0]; + + stats_L(source_p, name, doall, wilds, statchar); + } + else + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + from, to, "STATS"); +} + +static const struct StatsStruct +{ + const unsigned char letter; + void (*handler)(); + const unsigned int need_oper; + const unsigned int need_admin; +} stats_cmd_table[] = { + /* letter function need_oper need_admin */ + { 'a', stats_dns_servers, 1, 1 }, + { 'A', stats_dns_servers, 1, 1 }, + { 'c', stats_connect, 1, 0 }, + { 'C', stats_connect, 1, 0 }, + { 'd', stats_tdeny, 1, 0 }, + { 'D', stats_deny, 1, 0 }, + { 'e', stats_exempt, 1, 0 }, + { 'E', stats_events, 1, 1 }, + { 'f', fd_dump, 1, 1 }, + { 'F', fd_dump, 1, 1 }, + { 'g', stats_pending_glines, 1, 0 }, + { 'G', stats_glines, 1, 0 }, + { 'h', stats_hooks, 1, 1 }, + { 'H', stats_hubleaf, 1, 0 }, + { 'i', stats_auth, 0, 0 }, + { 'I', stats_auth, 0, 0 }, + { 'k', stats_tklines, 0, 0 }, + { 'K', stats_klines, 0, 0 }, + { 'l', stats_ltrace, 1, 0 }, + { 'L', stats_ltrace, 1, 0 }, + { 'm', stats_messages, 0, 0 }, + { 'M', stats_messages, 0, 0 }, + { 'o', stats_oper, 0, 0 }, + { 'O', stats_oper, 0, 0 }, + { 'p', stats_operedup, 0, 0 }, + { 'P', stats_ports, 0, 0 }, + { 'q', stats_resv, 1, 0 }, + { 'Q', stats_resv, 1, 0 }, + { 'r', stats_usage, 1, 0 }, + { 'R', stats_usage, 1, 0 }, + { 'S', stats_service, 1, 0 }, + { 't', stats_tstats, 1, 0 }, + { 'T', stats_tstats, 1, 0 }, + { 'u', stats_uptime, 0, 0 }, + { 'U', stats_shared, 1, 0 }, + { 'v', stats_servers, 1, 0 }, + { 'x', stats_gecos, 1, 0 }, + { 'X', stats_gecos, 1, 0 }, + { 'y', stats_class, 1, 0 }, + { 'Y', stats_class, 1, 0 }, + { 'z', stats_memory, 1, 0 }, + { '?', stats_servlinks, 0, 0 }, + { '\0', NULL, 0, 0 } +}; + +static void +do_stats(struct Client *source_p, int parc, char *parv[]) +{ + const struct StatsStruct *tab = stats_cmd_table; + const char statchar = *parv[1]; + + if (statchar == '\0') + { + sendto_one(source_p, form_str(RPL_ENDOFSTATS), + from, to, '*'); + return; + } + + for (; tab->handler; ++tab) + { + if (tab->letter == statchar) + { + /* The stats table says what privs are needed, so check --fl_ */ + if ((tab->need_admin && !HasUMode(source_p, UMODE_ADMIN)) || + (tab->need_oper && !HasUMode(source_p, UMODE_OPER))) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + from, to); + break; + } + + sendto_realops_flags(UMODE_SPY, L_ALL, + "STATS %c requested by %s (%s@%s) [%s]", + statchar, source_p->name, source_p->username, + source_p->host, source_p->servptr->name); + tab->handler(source_p, parc, parv); + break; + } + } + + sendto_one(source_p, form_str(RPL_ENDOFSTATS), + from, to, statchar); +} + +/* + * m_stats() + * parv[0] = sender prefix + * parv[1] = stat letter/command + * parv[2] = (if present) server/mask in stats L + * + * This will search the tables for the appropriate stats letter/command, + * if found execute it. + */ +static void +m_stats(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + static time_t last_used = 0; + + /* Is the stats meant for us? */ + if (!ConfigFileEntry.disable_remote) + if (hunt_server(client_p, source_p, ":%s STATS %s :%s", 2, + parc, parv) != HUNTED_ISME) + return; + + if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p)) + { + from = me.id; + to = source_p->id; + } + else + { + from = me.name; + to = source_p->name; + } + + /* Check the user is actually allowed to do /stats, and isnt flooding */ + if ((last_used + ConfigFileEntry.pace_wait) > CurrentTime) + { + sendto_one(source_p,form_str(RPL_LOAD2HI), + from, to); + return; + } + + last_used = CurrentTime; + + do_stats(source_p, parc, parv); +} + +/* + * mo_stats() + * parv[0] = sender prefix + * parv[1] = stat letter/command + * parv[2] = (if present) server/mask in stats L, or target + * + * This will search the tables for the appropriate stats letter, + * if found execute it. + */ +static void +mo_stats(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (hunt_server(client_p, source_p, ":%s STATS %s :%s", 2, + parc, parv) != HUNTED_ISME) + return; + + if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p)) + { + from = me.id; + to = source_p->id; + } + else + { + from = me.name; + to = source_p->name; + } + + do_stats(source_p, parc, parv); +} + +/* + * ms_stats - STATS message handler + * parv[0] = sender prefix + * parv[1] = statistics selector (defaults to Message frequency) + * parv[2] = server name (current server defaulted, if omitted) + */ +static void +ms_stats(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (hunt_server(client_p, source_p, ":%s STATS %s :%s", 2, + parc, parv) != HUNTED_ISME) + return; + + if (IsClient(source_p)) + mo_stats(client_p, source_p, parc, parv); +} + +static struct Message stats_msgtab = { + "STATS", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_stats, ms_stats, m_ignore, mo_stats, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&stats_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&stats_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_svinfo.c b/modules/m_svinfo.c new file mode 100644 index 0000000..bb36887 --- /dev/null +++ b/modules/m_svinfo.c @@ -0,0 +1,143 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_svinfo.c: Sends TS information for clock & compatibility checks. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "conf.h" +#include "log.h" +#include "parse.h" +#include "modules.h" + + +/* + * ms_svinfo - SVINFO message handler + * parv[0] = sender prefix + * parv[1] = TS_CURRENT for the server + * parv[2] = TS_MIN for the server + * parv[3] = server is standalone or connected to non-TS only + * parv[4] = server's idea of UTC time + */ +static void +ms_svinfo(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + time_t deltat; + time_t theirtime; + + if (MyConnect(source_p) && IsUnknown(source_p)) + { + exit_client(source_p, source_p, "Need SERVER before SVINFO"); + return; + } + + if (!IsServer(source_p) || !MyConnect(source_p) || parc < 5) + return; + + if (TS_CURRENT < atoi(parv[2]) || atoi(parv[1]) < TS_MIN) + { + /* + * a server with the wrong TS version connected; since we're + * TS_ONLY we can't fall back to the non-TS protocol so + * we drop the link -orabidoo + */ + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Link %s dropped, wrong TS protocol version (%s,%s)", + get_client_name(source_p, SHOW_IP), parv[1], parv[2]); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Link %s dropped, wrong TS protocol version (%s,%s)", + get_client_name(source_p, MASK_IP), parv[1], parv[2]); + exit_client(source_p, source_p, "Incompatible TS version"); + return; + } + + /* + * since we're here, might as well set CurrentTime while we're at it + */ + set_time(); + theirtime = atol(parv[4]); + deltat = abs(theirtime - CurrentTime); + + if (deltat > ConfigFileEntry.ts_max_delta) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Link %s dropped, excessive TS delta (my TS=%lu, their TS=%lu, delta=%d)", + get_client_name(source_p, SHOW_IP), + (unsigned long) CurrentTime, + (unsigned long) theirtime, + (int) deltat); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Link %s dropped, excessive TS delta (my TS=%lu, their TS=%lu, delta=%d)", + get_client_name(source_p, MASK_IP), + (unsigned long) CurrentTime, + (unsigned long) theirtime, + (int) deltat); + ilog(LOG_TYPE_IRCD, + "Link %s dropped, excessive TS delta (my TS=%lu, their TS=%lu, delta=%d)", + get_client_name(source_p, SHOW_IP), + (unsigned long) CurrentTime, + (unsigned long) theirtime, + (int) deltat); + exit_client(source_p, source_p, "Excessive TS delta"); + return; + } + + if (deltat > ConfigFileEntry.ts_warn_delta) + sendto_realops_flags(UMODE_ALL, L_ALL, + "Link %s notable TS delta (my TS=%lu, their TS=%lu, delta=%d)", + source_p->name, + (unsigned long) CurrentTime, + (unsigned long) theirtime, + (int) deltat); +} + +static struct Message svinfo_msgtab = { + "SVINFO", 0, 0, 4, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_ignore, ms_svinfo, m_ignore, m_ignore, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&svinfo_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&svinfo_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_svsmode.c b/modules/m_svsmode.c new file mode 100644 index 0000000..34c4c71 --- /dev/null +++ b/modules/m_svsmode.c @@ -0,0 +1,208 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 1999 by the Bahamut Development Team. + * Copyright (C) 2011 by the Hybrid 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 + */ + +/*! \file m_svsmode.c + * \brief Includes required functions for processing the SVSMODE command. + * \version $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "s_serv.h" +#include "send.h" +#include "channel_mode.h" +#include "parse.h" +#include "modules.h" +#include "irc_string.h" +#include "s_user.h" +#include "conf.h" +#include "hook.h" + + +/*! \brief SVSMODE command handler (called by services) + * + * \param client_p Pointer to allocated Client struct with physical connection + * to this server, i.e. with an open socket connected. + * \param source_p Pointer to allocated Client struct from which the message + * originally comes from. This can be a local or remote client. + * \param parc Integer holding the number of supplied arguments. + * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL + * pointers. + * \note Valid arguments for this command are: + * - parv[0] = sender prefix + * - parv[1] = nickname + * - parv[2] = TS (or mode, depending on svs version) + * - parv[3] = mode (or services id if old svs version) + * - parv[4] = optional argument (services id) + */ +static void +ms_svsmode(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL; + int what = MODE_ADD; + unsigned int flag = 0, setflags = 0; + char *m = NULL, *modes = NULL, *extarg = NULL; + time_t ts = 0; + + if (!HasFlag(source_p, FLAGS_SERVICE)) + return; + + if ((parc >= 4) && ((*parv[3] == '+') || (*parv[3] == '-'))) + { + ts = atol(parv[2]); + modes = parv[3]; + extarg = (parc > 4) ? parv[4] : NULL; + } + else + { + modes = parv[2]; + extarg = (parc > 3) ? parv[3] : NULL; + } + + if ((target_p = find_person(client_p, parv[1])) == NULL) + return; + + if (ts && (ts != target_p->tsinfo)) + return; + + setflags = target_p->umodes; + + for (m = modes; *m; ++m) + { + switch (*m) + { + case '+': + what = MODE_ADD; + break; + case '-': + what = MODE_DEL; + break; + + case 'd': + if (!EmptyString(extarg)) + strlcpy(target_p->svid, extarg, sizeof(target_p->svid)); + break; + + case 'o': + if (what == MODE_DEL && HasUMode(target_p, UMODE_OPER)) + { + ClearOper(target_p); + Count.oper--; + + if (MyConnect(target_p)) + { + dlink_node *dm = NULL; + + detach_conf(target_p, OPER_TYPE); + ClrOFlag(target_p); + DelUMode(target_p, ConfigFileEntry.oper_only_umodes); + + if ((dm = dlinkFindDelete(&oper_list, target_p)) != NULL) + free_dlink_node(dm); + } + } + + break; + + case 'i': + if (what == MODE_ADD && !HasUMode(target_p, UMODE_INVISIBLE)) + { + AddUMode(target_p, UMODE_INVISIBLE); + ++Count.invisi; + } + + if (what == MODE_DEL && HasUMode(target_p, UMODE_INVISIBLE)) + { + DelUMode(target_p, UMODE_INVISIBLE); + --Count.invisi; + } + + break; + + case ' ': + case '\n': + case '\r': + case '\t': + break; + default: + if ((flag = user_modes[(unsigned char)*m])) + execute_callback(umode_cb, client_p, target_p, what, flag); + break; + } + } + + if (extarg) + { + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s SVSMODE %s %lu %s %s", ID(source_p), + ID(target_p), (unsigned long)target_p->tsinfo, modes, extarg); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s SVSMODE %s %lu %s %s", source_p->name, + target_p->name, (unsigned long)target_p->tsinfo, modes, extarg); + } + else + { + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s SVSMODE %s %lu %s", ID(source_p), + ID(target_p), (unsigned long)target_p->tsinfo, modes); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s SVSMODE %s %lu %s", source_p->name, + target_p->name, (unsigned long)target_p->tsinfo, modes); + } + + if (MyConnect(target_p) && (setflags != target_p->umodes)) + { + char modebuf[IRCD_BUFSIZE]; + + send_umode(target_p, target_p, setflags, 0xffffffff, modebuf); + } +} + +static struct Message svsmode_msgtab = { + "SVSMODE", 0, 0, 3, MAXPARA, MFLG_SLOW, 0, + {m_ignore, m_ignore, ms_svsmode, m_ignore, m_ignore, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&svsmode_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&svsmode_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_svsnick.c b/modules/m_svsnick.c new file mode 100644 index 0000000..ff638d7 --- /dev/null +++ b/modules/m_svsnick.c @@ -0,0 +1,148 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 1999 by the Bahamut Development Team. + * Copyright (C) 2011 by the Hybrid 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 + */ + +/*! \file m_svsnick.c + * \brief Includes required functions for processing the SVSNICK command. + * \version $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "channel_mode.h" +#include "numeric.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "irc_string.h" +#include "s_user.h" +#include "hash.h" +#include "watch.h" +#include "whowas.h" + + +/*! \brief SVSNICK command handler (called by services) + * + * \param client_p Pointer to allocated Client struct with physical connection + * to this server, i.e. with an open socket connected. + * \param source_p Pointer to allocated Client struct from which the message + * originally comes from. This can be a local or remote client. + * \param parc Integer holding the number of supplied arguments. + * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL + * pointers. + * \note Valid arguments for this command are: + * - parv[0] = sender prefix + * - parv[1] = old nickname + * - parv[2] = new nickname + * - parv[3] = timestamp + */ +static void +ms_svsnick(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p = NULL, *exists_p = NULL; + + if (!HasFlag(source_p, FLAGS_SERVICE) || !valid_nickname(parv[2], 1)) + return; + + if (hunt_server(client_p, source_p, ":%s SVSNICK %s %s :%s", + 1, parc, parv) != HUNTED_ISME) + return; + + if ((target_p = find_person(client_p, parv[1])) == NULL) + return; + + assert(MyClient(target_p)); + + if ((exists_p = hash_find_client(parv[2]))) + { + if (IsUnknown(exists_p)) + exit_client(exists_p, &me, "SVSNICK Override"); + else + { + exit_client(target_p, &me, "SVSNICK Collide"); + return; + } + } + + target_p->tsinfo = atoi(parv[3]); + clear_ban_cache_client(target_p); + watch_check_hash(target_p, RPL_LOGOFF); + + if (HasUMode(target_p, UMODE_REGISTERED)) + { + unsigned int oldmodes = target_p->umodes; + char modebuf[IRCD_BUFSIZE] = { '\0' }; + + DelUMode(target_p, UMODE_REGISTERED); + send_umode(target_p, target_p, oldmodes, 0xffffffff, modebuf); + } + + sendto_common_channels_local(target_p, 1, ":%s!%s@%s NICK :%s", + target_p->name, target_p->username, + target_p->host, parv[2]); + + add_history(target_p, 1); + + sendto_server(NULL, CAP_TS6, NOCAPS, + ":%s NICK %s :%lu", + ID(target_p), parv[2], (unsigned long)target_p->tsinfo); + sendto_server(NULL, NOCAPS, CAP_TS6, + ":%s NICK %s :%lu", + target_p->name, parv[2], (unsigned long)source_p->tsinfo); + + hash_del_client(target_p); + strlcpy(target_p->name, parv[2], sizeof(target_p->name)); + hash_add_client(target_p); + + watch_check_hash(target_p, RPL_LOGON); + + fd_note(&target_p->localClient->fd, "Nick: %s", parv[2]); +} + +static struct Message svsnick_msgtab = { + "SVSNICK", 0, 0, 4, MAXPARA, MFLG_SLOW, 0, + {m_ignore, m_ignore, ms_svsnick, m_ignore, m_ignore, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&svsnick_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&svsnick_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_tburst.c b/modules/m_tburst.c new file mode 100644 index 0000000..f927c35 --- /dev/null +++ b/modules/m_tburst.c @@ -0,0 +1,143 @@ +/* modules/m_tburst.c + * Copyright (C) 2002, 2003, 2004, 2005 Hybrid Development Team + * + * 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.The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "send.h" +#include "modules.h" +#include "hash.h" +#include "s_serv.h" +#include "conf.h" +#include "parse.h" + + +/* ms_tburst() + * + * parv[0] = sender prefix + * parv[1] = channel timestamp + * parv[2] = channel + * parv[3] = topic timestamp + * parv[4] = topic setter + * parv[5] = topic + */ +static void +ms_tburst(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Channel *chptr = NULL; + int accept_remote = 0; + time_t remote_channel_ts = atol(parv[1]); + time_t remote_topic_ts = atol(parv[3]); + const char *topic = parv[5]; + const char *setby = parv[4]; + + /* + * Do NOT test parv[5] for an empty string and return if true! + * parv[5] CAN be an empty string, i.e. if the other side wants + * to unset our topic. Don't forget: an empty topic is also a + * valid topic. + */ + + + if ((chptr = hash_find_channel(parv[2])) == NULL) + return; + + /* + * The logic for accepting and rejecting channel topics was + * always a bit hairy, so now we got exactly 2 cases where + * we would accept a bursted topic + * + * Case 1: + * The TS of the remote channel is older than ours + * Case 2: + * The TS of the remote channel is equal to ours AND + * the TS of the remote topic is newer than ours + */ + if (HasFlag(source_p, FLAGS_SERVICE)) + accept_remote = 1; + else if (remote_channel_ts < chptr->channelts) + accept_remote = 1; + else if (remote_channel_ts == chptr->channelts) + if (remote_topic_ts > chptr->topic_time) + accept_remote = 1; + + if (accept_remote) + { + int topic_differs = strncmp(chptr->topic, topic, sizeof(chptr->topic) - 1); + + set_channel_topic(chptr, topic, setby, remote_topic_ts); + + if (topic_differs) + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s TOPIC %s :%s", + ConfigServerHide.hide_servers ? me.name : source_p->name, + chptr->chname, chptr->topic); + } + + /* + * Always propagate what we have received, not only if we accept the topic. + * This will keep other servers in sync. + */ + sendto_server(source_p, CAP_TBURST|CAP_TS6, NOCAPS, + ":%s TBURST %s %s %s %s :%s", + ID(source_p), parv[1], parv[2], parv[3], setby, topic); + sendto_server(source_p, CAP_TBURST, CAP_TS6, + ":%s TBURST %s %s %s %s :%s", + source_p->name, parv[1], parv[2], parv[3], setby, topic); +} + +static struct Message tburst_msgtab = { + "TBURST", 0, 0, 6, MAXPARA, MFLG_SLOW, 0, + { m_ignore, m_ignore, ms_tburst, m_ignore, m_ignore, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&tburst_msgtab); + add_capability("TBURST", CAP_TBURST, 1); +} + +static void +module_exit(void) +{ + mod_del_cmd(&tburst_msgtab); + delete_capability("TBURST"); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_testline.c b/modules/m_testline.c new file mode 100644 index 0000000..f9a8e67 --- /dev/null +++ b/modules/m_testline.c @@ -0,0 +1,258 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_testline.c: Tests a hostmask to see what will happen to it. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "irc_string.h" +#include "ircd_defs.h" +#include "ircd.h" +#include "restart.h" +#include "conf.h" +#include "send.h" +#include "hostmask.h" +#include "numeric.h" +#include "parse.h" +#include "resv.h" +#include "hash.h" +#include "modules.h" + + +/* mo_testline() + * + * inputs - pointer to physical connection request is coming from + * - pointer to source connection request is coming from + * - parc arg count + * - parv actual arguments + * + * output - NONE + * side effects - command to test I/K lines on server + * + * i.e. /quote testline user@host,ip [password] + * + */ +static void +mo_testline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + /* IRCD_BUFSIZE to allow things like *u*s*e*r*n*a*m*e* etc. */ + char given_name[IRCD_BUFSIZE]; + char given_host[IRCD_BUFSIZE]; + char parv1_copy[IRCD_BUFSIZE]; + struct ConfItem *conf; + struct AccessItem *aconf; + struct irc_ssaddr ip; + int host_mask; + int t; + int matches = 0; + char userhost[HOSTLEN + USERLEN + 2]; + struct split_nuh_item nuh; + + if (EmptyString(parv[1])) + { + sendto_one(source_p, ":%s NOTICE %s :usage: user@host|ip [password]", + me.name, source_p->name); + return; + } + + if (IsChanPrefix(*parv[1])) /* Might be channel resv */ + { + const struct ResvChannel *chptr = NULL; + + if ((chptr = match_find_resv(parv[1]))) + { + sendto_one(source_p, form_str(RPL_TESTLINE), + me.name, source_p->name, 'Q', 0, chptr->name, + chptr->reason ? chptr->reason : "No reason", ""); + return; + } + } + + strlcpy(parv1_copy, parv[1], sizeof(parv1_copy)); + + nuh.nuhmask = parv[1]; + nuh.nickptr = NULL; + nuh.userptr = given_name; + nuh.hostptr = given_host; + + nuh.nicksize = 0; + nuh.usersize = sizeof(given_name); + nuh.hostsize = sizeof(given_host); + + split_nuh(&nuh); + + t = parse_netmask(given_host, &ip, &host_mask); + + if (t != HM_HOST) + { + aconf = find_dline_conf(&ip, +#ifdef IPV6 + (t == HM_IPV6) ? AF_INET6 : AF_INET +#else + AF_INET +#endif + ); + if (aconf != NULL) + { + ++matches; + if (aconf->status & CONF_EXEMPTDLINE) + sendto_one(source_p, + ":%s NOTICE %s :Exempt D-line host [%s] reason [%s]", + me.name, source_p->name, aconf->host, aconf->reason); + else + sendto_one(source_p, form_str(RPL_TESTLINE), + me.name, source_p->name, + IsConfTemporary(aconf) ? 'd' : 'D', + IsConfTemporary(aconf) ? ((aconf->hold - CurrentTime) / 60) + : 0L, + aconf->host, aconf->reason, + aconf->oper_reason ? aconf->oper_reason : ""); + } + } + + if (t != HM_HOST) + aconf = find_address_conf(given_host, given_name, &ip, +#ifdef IPV6 + (t == HM_IPV6) ? AF_INET6 : AF_INET, +#else + AF_INET, +#endif + parv[2]); + else + aconf = find_address_conf(given_host, given_name, NULL, 0, parv[2]); + + if (aconf != NULL) + { + snprintf(userhost, sizeof(userhost), "%s@%s", aconf->user, aconf->host); + + if (aconf->status & CONF_CLIENT) + { + sendto_one(source_p, form_str(RPL_TESTLINE), + me.name, source_p->name, 'I', 0L, userhost, + aconf->class_ptr ? aconf->class_ptr->name : "<default>", ""); + ++matches; + } + else if (aconf->status & CONF_KLINE) + { + sendto_one(source_p, form_str(RPL_TESTLINE), + me.name, source_p->name, + IsConfTemporary(aconf) ? 'k' : 'K', + IsConfTemporary(aconf) ? ((aconf->hold - CurrentTime) / 60) + : 0L, + userhost, aconf->reason? aconf->reason : "No reason", + aconf->oper_reason ? aconf->oper_reason : ""); + ++matches; + } + } + + conf = find_matching_name_conf(NRESV_TYPE, given_name, NULL, NULL, 0); + + if (conf != NULL) + { + const struct MatchItem *mconf = map_to_conf(conf); + + sendto_one(source_p, form_str(RPL_TESTLINE), + me.name, source_p->name, 'Q', 0L, + conf->name, + mconf->reason ? mconf->reason : "No reason", + mconf->oper_reason ? mconf->oper_reason : ""); + ++matches; + } + + if (matches == 0) + sendto_one(source_p, form_str(RPL_NOTESTLINE), + me.name, source_p->name, parv1_copy); +} + +/* mo_testgecos() + * + * inputs - pointer to physical connection request is coming from + * - pointer to source connection request is coming from + * - parc arg count + * - parv actual arguments + * + * output - always 0 + * side effects - command to test X lines on server + * + * i.e. /quote testgecos gecos + * + */ +static void +mo_testgecos(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct ConfItem *conf = NULL; + + if (EmptyString(parv[1])) + { + sendto_one(source_p, ":%s NOTICE %s :usage: gecos", + me.name, source_p->name); + return; + } + + if ((conf = find_matching_name_conf(XLINE_TYPE, parv[1], NULL, NULL, 0))) + { + const struct MatchItem *xconf = map_to_conf(conf); + sendto_one(source_p, form_str(RPL_TESTLINE), + me.name, source_p->name, 'X', 0L, + conf->name, xconf->reason ? xconf->reason : "X-lined", + xconf->oper_reason ? xconf->oper_reason : ""); + } + else + sendto_one(source_p, form_str(RPL_NOTESTLINE), + me.name, source_p->name, parv[1]); +} + +static struct Message testline_msgtab = { + "TESTLINE", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_testline, m_ignore } +}; + +struct Message testgecos_msgtab = { + "TESTGECOS", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_testgecos, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&testline_msgtab); + mod_add_cmd(&testgecos_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&testline_msgtab); + mod_del_cmd(&testgecos_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_testmask.c b/modules/m_testmask.c new file mode 100644 index 0000000..20da840 --- /dev/null +++ b/modules/m_testmask.c @@ -0,0 +1,131 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_testmask.c: Counts the birdies err local and remote clients. + * + * Copyright (C) 2005 by Diane Bruce + * Coypright (C) 2005 ircd-hybrid team + * + * 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.The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "irc_string.h" +#include "ircd_defs.h" +#include "ircd.h" +#include "restart.h" +#include "conf.h" +#include "send.h" +#include "hostmask.h" +#include "numeric.h" +#include "parse.h" +#include "modules.h" + + +/* mo_testmask() + * + * inputs - pointer to physical connection request is coming from + * - pointer to source connection request is coming from + * - parc arg count + * - parv actual arguments + * output - NONE + * side effects - count up clients matching mask + * i.e. /quote testmask user@host + */ +static void +mo_testmask(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct split_nuh_item nuh; + char given_nick[IRCD_BUFSIZE]; + char given_user[IRCD_BUFSIZE]; + char given_host[IRCD_BUFSIZE]; + unsigned int count[2] = { 0, 0 }; + const dlink_node *ptr = NULL; + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "TESTMASK"); + return; + } + + nuh.nuhmask = parv[1]; + nuh.nickptr = given_nick; + nuh.userptr = given_user; + nuh.hostptr = given_host; + + nuh.nicksize = sizeof(given_nick); + nuh.usersize = sizeof(given_user); + nuh.hostsize = sizeof(given_host); + + split_nuh(&nuh); + + DLINK_FOREACH(ptr, global_client_list.head) + { + const struct Client *target_p = ptr->data; + + if (!IsClient(target_p) || !match(given_nick, target_p->name)) + continue; + + if (match(given_user, target_p->username)) + if (match(given_host, target_p->host) || match(given_host, target_p->sockhost)) + ++count[!MyConnect(target_p)]; + } + + sendto_one(source_p, form_str(RPL_TESTMASK), me.name, + source_p->name, + given_nick, given_user, + given_host, count[0], count[1]); +} + +static struct Message testmask_msgtab = { + "TESTMASK", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_testmask, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&testmask_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&testmask_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_time.c b/modules/m_time.c new file mode 100644 index 0000000..14705c6 --- /dev/null +++ b/modules/m_time.c @@ -0,0 +1,99 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_time.c: Sends the current time on the server. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "s_misc.h" +#include "conf.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "packet.h" + + +/* + * m_time + * parv[0] = sender prefix + * parv[1] = servername + */ +static void +m_time(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + /* this is not rate limited, so end the grace period */ + if (!IsFloodDone(source_p)) + flood_endgrace(source_p); + + /* This is safe enough to use during non hidden server mode */ + if (!ConfigFileEntry.disable_remote) + if (hunt_server(client_p, source_p, ":%s TIME :%s", 1, parc, parv) != HUNTED_ISME) + return; + + sendto_one(source_p, form_str(RPL_TIME), me.name, + source_p->name, me.name, date(0)); +} + +/* + * mo_time + * parv[0] = sender prefix + * parv[1] = servername + */ +static void +mo_time(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (hunt_server(client_p, source_p, ":%s TIME :%s", 1, parc, parv) == HUNTED_ISME) + sendto_one(source_p, form_str(RPL_TIME), me.name, + source_p->name, me.name, date(0)); +} + +static struct Message time_msgtab = { + "TIME", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_time, mo_time, m_ignore, mo_time, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&time_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&time_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_topic.c b/modules/m_topic.c new file mode 100644 index 0000000..fe4faea --- /dev/null +++ b/modules/m_topic.c @@ -0,0 +1,171 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_topic.c: Sets a channel topic. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "s_serv.h" +#include "parse.h" +#include "modules.h" +#include "packet.h" + + +/* m_topic() + * parv[0] = sender prefix + * parv[1] = channel name + * parv[2] = new topic, if setting topic + */ +static void +m_topic(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Channel *chptr = NULL; + const char *from, *to; + + if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p)) + { + from = me.id; + to = source_p->id; + } + else + { + from = me.name; + to = source_p->name; + } + + if (EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + from, to, "TOPIC"); + return; + } + + if (MyClient(source_p) && !IsFloodDone(source_p)) + flood_endgrace(source_p); + + if ((chptr = hash_find_channel(parv[1])) == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + from, to, parv[1]); + return; + } + + /* setting topic */ + if (parc > 2) + { + struct Membership *ms; + + if ((ms = find_channel_link(source_p, chptr)) == NULL) + { + sendto_one(source_p, form_str(ERR_NOTONCHANNEL), from, + to, parv[1]); + return; + } + + if (!(chptr->mode.mode & MODE_TOPICLIMIT) || + has_member_flags(ms, CHFL_CHANOP|CHFL_HALFOP)) + { + char topic_info[USERHOST_REPLYLEN]; + + snprintf(topic_info, sizeof(topic_info), "%s!%s@%s", source_p->name, + source_p->username, source_p->host); + set_channel_topic(chptr, parv[2], topic_info, CurrentTime); + + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s TOPIC %s :%s", + ID(source_p), chptr->chname, + chptr->topic); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s TOPIC %s :%s", + source_p->name, chptr->chname, + chptr->topic); + sendto_channel_local(ALL_MEMBERS, 0, + chptr, ":%s!%s@%s TOPIC %s :%s", + source_p->name, + source_p->username, + source_p->host, + chptr->chname, chptr->topic); + } + else + sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), + from, to, chptr->chname); + } + else /* only asking for topic */ + { + if (!SecretChannel(chptr) || IsMember(source_p, chptr)) + { + if (chptr->topic[0] == '\0') + sendto_one(source_p, form_str(RPL_NOTOPIC), + from, to, chptr->chname); + else + { + sendto_one(source_p, form_str(RPL_TOPIC), + from, to, + chptr->chname, chptr->topic); + sendto_one(source_p, form_str(RPL_TOPICWHOTIME), + from, to, chptr->chname, + chptr->topic_info, + chptr->topic_time); + } + } + else + sendto_one(source_p, form_str(ERR_NOTONCHANNEL), + from, to, chptr->chname); + } +} + +static struct Message topic_msgtab = { + "TOPIC", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_topic, m_topic, m_ignore, m_topic, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&topic_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&topic_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_trace.c b/modules/m_trace.c new file mode 100644 index 0000000..910b390 --- /dev/null +++ b/modules/m_trace.c @@ -0,0 +1,448 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_trace.c: Traces a path to a client/server. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "s_bsd.h" +#include "s_serv.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "conf.h" + + +static void do_actual_trace(struct Client *, int, char *[]); +static void report_this_status(struct Client *, struct Client *, int); + +static void +trace_get_dependent(int *const server, + int *const client, const struct Client *target_p) +{ + const dlink_node *ptr = NULL; + + (*server)++; + (*client) += dlink_list_length(&target_p->serv->client_list); + + DLINK_FOREACH(ptr, target_p->serv->server_list.head) + trace_get_dependent(server, client, ptr->data); +} + +/* + * m_trace() + * + * parv[0] = sender prefix + * parv[1] = target client/server to trace + */ +static void +m_trace(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *tname; + + if (parc > 1) + tname = parv[1]; + else + tname = me.name; + + sendto_one(source_p, form_str(RPL_ENDOFTRACE), + me.name, source_p->name, tname); +} + + +/* mo_trace() + * parv[0] = sender prefix + * parv[1] = servername + */ +static void +mo_trace(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + dlink_node *ptr; + const char *tname; + const char *from, *to; + + if (parc > 2) + if (hunt_server(client_p, source_p, ":%s TRACE %s :%s", 2, parc, parv)) + return; + + if (parc > 1) + tname = parv[1]; + else + tname = me.name; + + if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p)) + { + from = me.id; + to = source_p->id; + } + else + { + from = me.name; + to = source_p->name; + } + + switch (hunt_server(client_p, source_p, ":%s TRACE :%s", 1, parc, parv)) + { + case HUNTED_PASS: /* note: gets here only if parv[1] exists */ + { + struct Client *ac2ptr = NULL; + + if ((ac2ptr = hash_find_client(tname)) == NULL) + { + DLINK_FOREACH(ptr, global_client_list.head) + { + ac2ptr = ptr->data; + + if (match(tname, ac2ptr->name)) + break; + else + ac2ptr = NULL; + } + } + + if (ac2ptr != NULL) + sendto_one(source_p, form_str(RPL_TRACELINK), from, to, + ircd_version, tname, ac2ptr->from->name); + else + sendto_one(source_p, form_str(RPL_TRACELINK), from, to, + ircd_version, tname, "ac2ptr_is_NULL!!"); + return; + } + + case HUNTED_ISME: + do_actual_trace(source_p, parc, parv); + break; + default: + return; + } +} + +/* +** ms_trace +** parv[0] = sender prefix +** parv[1] = servername +*/ +static void +ms_trace(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (hunt_server(client_p, source_p, ":%s TRACE %s :%s", 2, parc, parv)) + return; + + if (HasUMode(source_p, UMODE_OPER)) + mo_trace(client_p, source_p, parc, parv); +} + +static void +do_actual_trace(struct Client *source_p, int parc, char *parv[]) +{ + struct Client *target_p = NULL; + struct ConfItem *conf; + struct ClassItem *cltmp; + int doall = 0; + int wilds, dow; + dlink_node *ptr; + const char *from, *to, *tname; + + if (parc > 1) + tname = parv[1]; + else + tname = me.name; + + if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p)) + { + from = me.id; + to = source_p->id; + } + else + { + from = me.name; + to = source_p->name; + } + + sendto_realops_flags(UMODE_SPY, L_ALL, + "TRACE requested by %s (%s@%s) [%s]", + source_p->name, source_p->username, + source_p->host, source_p->servptr->name); + + if (match(tname, me.name)) + doall = 1; + else if (!MyClient(source_p) && !strcmp(tname, me.id)) + { + doall = 1; + tname = me.name; + } + + wilds = !parv[1] || has_wildcards(tname); + dow = wilds || doall; + + set_time(); + if (!HasUMode(source_p, UMODE_OPER) || !dow) /* non-oper traces must be full nicks */ + /* lets also do this for opers tracing nicks */ + { + const char *name; + const char *class_name; + + target_p = hash_find_client(tname); + + if (target_p && IsClient(target_p)) + { + name = get_client_name(target_p, HIDE_IP); + class_name = get_client_class(target_p); + + if (HasUMode(target_p, UMODE_OPER)) + { + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + from, to, class_name, name, + IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost, + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + else + { + sendto_one(source_p,form_str(RPL_TRACEUSER), + from, to, class_name, name, + IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost, + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + } + + sendto_one(source_p, form_str(RPL_ENDOFTRACE), + from, to, tname); + return; + } + + /* report all direct connections */ + DLINK_FOREACH(ptr, local_client_list.head) + { + target_p = ptr->data; + + if (HasUMode(target_p, UMODE_INVISIBLE) && dow && + !(MyConnect(source_p) && HasUMode(source_p, UMODE_OPER)) && + !HasUMode(target_p, UMODE_OPER) && (target_p != source_p)) + continue; + if (!doall && wilds && !match(tname, target_p->name)) + continue; + if (!dow && irccmp(tname, target_p->name)) + continue; + + report_this_status(source_p, target_p, dow); + } + + DLINK_FOREACH(ptr, serv_list.head) + { + target_p = ptr->data; + + if (!doall && wilds && !match(tname, target_p->name)) + continue; + if (!dow && irccmp(tname, target_p->name)) + continue; + + report_this_status(source_p, target_p, dow); + } + + /* This section is to report the unknowns */ + DLINK_FOREACH(ptr, unknown_list.head) + { + target_p = ptr->data; + + if (!doall && wilds && !match(tname, target_p->name)) + continue; + if (!dow && irccmp(tname, target_p->name)) + continue; + + report_this_status(source_p, target_p, dow); + } + + DLINK_FOREACH(ptr, class_items.head) + { + conf = ptr->data; + cltmp = map_to_conf(conf); + + if (cltmp->curr_user_count > 0) + sendto_one(source_p, form_str(RPL_TRACECLASS), + from, to, conf->name, cltmp->curr_user_count); + } + + sendto_one(source_p, form_str(RPL_ENDOFTRACE), from, to, tname); +} + +/* report_this_status() + * + * inputs - pointer to client to report to + * - pointer to client to report about + * output - counter of number of hits + * side effects - NONE + */ +static void +report_this_status(struct Client *source_p, struct Client *target_p, int dow) +{ + const char *name; + const char *class_name; + const char *from, *to; + + if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p)) + { + from = me.id; + to = source_p->id; + } + else + { + from = me.name; + to = source_p->name; + } + + name = get_client_name(target_p, HIDE_IP); + class_name = get_client_class(target_p); + + set_time(); + + switch (target_p->status) + { + case STAT_CONNECTING: + sendto_one(source_p, form_str(RPL_TRACECONNECTING), + from, to, class_name, + HasUMode(source_p, UMODE_ADMIN) ? name : target_p->name); + break; + case STAT_HANDSHAKE: + sendto_one(source_p, form_str(RPL_TRACEHANDSHAKE), + from, to, class_name, + HasUMode(source_p, UMODE_ADMIN) ? name : target_p->name); + break; + case STAT_ME: + break; + case STAT_UNKNOWN: + /* added time -Taner */ + sendto_one(source_p, form_str(RPL_TRACEUNKNOWN), + from, to, class_name, name, target_p->sockhost, + target_p->localClient->firsttime ? /* TBD: can't be 0 */ + CurrentTime - target_p->localClient->firsttime : -1); + break; + case STAT_CLIENT: + /* + * Only opers see users if there is a wildcard + * but anyone can see all the opers. + */ + if ((HasUMode(source_p, UMODE_OPER) && + (MyClient(source_p) || !(dow && HasUMode(target_p, UMODE_INVISIBLE)))) + || !dow || HasUMode(target_p, UMODE_OPER)) + { + if (HasUMode(target_p, UMODE_ADMIN) && !ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + from, to, class_name, name, + HasUMode(source_p, UMODE_ADMIN) ? target_p->sockhost : "255.255.255.255", + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + + else if (HasUMode(target_p, UMODE_OPER)) + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + from, to, class_name, name, + IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost, + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else + sendto_one(source_p, form_str(RPL_TRACEOPERATOR), + from, to, class_name, name, + MyOper(source_p) ? target_p->sockhost : + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + else + { + if (ConfigFileEntry.hide_spoof_ips) + sendto_one(source_p, form_str(RPL_TRACEUSER), + from, to, class_name, name, + IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost, + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + else + sendto_one(source_p, form_str(RPL_TRACEUSER), + from, to, class_name, name, + MyOper(source_p) ? target_p->sockhost : + (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost), + CurrentTime - target_p->localClient->lasttime, + CurrentTime - target_p->localClient->last_privmsg); + } + } + break; + case STAT_SERVER: + { + int clients = 0; + int servers = 0; + + trace_get_dependent(&servers, &clients, target_p); + + if (!HasUMode(source_p, UMODE_ADMIN)) + name = get_client_name(target_p, MASK_IP); + + sendto_one(source_p, form_str(RPL_TRACESERVER), + from, to, class_name, servers, + clients, name, *(target_p->serv->by) ? + target_p->serv->by : "*", "*", + me.name, CurrentTime - target_p->localClient->lasttime); + break; + } + + default: /* ...we actually shouldn't come here... --msa */ + sendto_one(source_p, form_str(RPL_TRACENEWTYPE), + from, to, name); + break; + } +} + +static struct Message trace_msgtab = { + "TRACE", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_trace, ms_trace, m_ignore, mo_trace, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&trace_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&trace_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_user.c b/modules/m_user.c new file mode 100644 index 0000000..9db36b4 --- /dev/null +++ b/modules/m_user.c @@ -0,0 +1,134 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_user.c: Sends username information. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "s_user.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "listener.h" + + +/* do_local_user() + * + * inputs - + * output - NONE + * side effects - + */ +static void +do_local_user(struct Client *source_p, + const char *username, const char *host, const char *server, + const char *realname) +{ + assert(source_p != NULL); + assert(source_p->username != username); + assert(IsUnknown(source_p)); + + source_p->localClient->registration &= ~REG_NEED_USER; + + /* + * don't take the clients word for it, ever + */ + source_p->servptr = &me; + + strlcpy(source_p->info, realname, sizeof(source_p->info)); + + /* stash for later */ + strlcpy(source_p->localClient->client_host, host, sizeof(source_p->localClient->client_host)); + strlcpy(source_p->localClient->client_server, server, sizeof(source_p->localClient->client_server)); + + if (!IsGotId(source_p)) + strlcpy(source_p->username, username, sizeof(source_p->username)); + + if (!source_p->localClient->registration) + register_local_user(source_p); +} + +/* +** mr_user +** parv[0] = sender prefix +** parv[1] = username (login name, account) +** parv[2] = client host name (used only from other servers) +** parv[3] = server host name (used only from other servers) +** parv[4] = users real name info +*/ +static void +mr_user(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *p = NULL; + + if (source_p->localClient->listener->flags & LISTENER_SERVER) + { + exit_client(source_p, &me, "Use a different port"); + return; + } + + if ((p = strchr(parv[1], '@')) != NULL) + *p = '\0'; + + if (EmptyString(parv[4])) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, + source_p->name[0] ? source_p->name : "*", "USER"); + return; + } + + do_local_user(source_p, + parv[1], /* username */ + parv[2], /* host */ + parv[3], /* server */ + parv[4] /* users real name */ ); +} + +static struct Message user_msgtab = { + "USER", 0, 0, 5, MAXPARA, MFLG_SLOW, 0, + { mr_user, m_registered, m_ignore, m_ignore, m_registered, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&user_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&user_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_userhost.c b/modules/m_userhost.c new file mode 100644 index 0000000..81cddf6 --- /dev/null +++ b/modules/m_userhost.c @@ -0,0 +1,127 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_userhost.c: Shows a user's host. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "s_serv.h" +#include "send.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "parse.h" +#include "modules.h" + + +/* + * m_userhost added by Darren Reed 13/8/91 to aid clients and reduce + * the need for complicated requests like WHOIS. It returns user/host + * information only (no spurious AWAY labels or channels). + */ +static void +m_userhost(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p; + char buf[IRCD_BUFSIZE]; + char response[NICKLEN*2+USERLEN+HOSTLEN+30]; + char *t = NULL, *p = NULL, *nick = NULL; + int i = 0; /* loop counter */ + int cur_len; + int rl; + + cur_len = snprintf(buf, sizeof(buf), form_str(RPL_USERHOST), me.name, source_p->name, ""); + t = buf + cur_len; + + for (nick = strtoken(&p, parv[1], " "); nick && i++ < 5; + nick = strtoken(&p, NULL, " ")) + { + if ((target_p = find_person(client_p, nick)) != NULL) + { + /* + * Show real IP for USERHOST on yourself. + * This is needed for things like mIRC, which do a server-based + * lookup (USERHOST) to figure out what the clients' local IP + * is. Useful for things like NAT, and dynamic dial-up users. + */ + if (MyClient(target_p) && (target_p == source_p)) + { + rl = ircsprintf(response, "%s%s=%c%s@%s ", + target_p->name, + HasUMode(target_p, UMODE_OPER) ? "*" : "", + (target_p->away[0]) ? '-' : '+', + target_p->username, + target_p->sockhost); + } + else + { + rl = ircsprintf(response, "%s%s=%c%s@%s ", + target_p->name, (HasUMode(target_p, UMODE_OPER) && + (!HasUMode(target_p, UMODE_HIDDEN) || + HasUMode(source_p, UMODE_OPER))) ? "*" : "", + (target_p->away[0]) ? '-' : '+', + target_p->username, + target_p->host); + } + + if ((rl + cur_len) < (IRCD_BUFSIZE - 10)) + { + ircsprintf(t, "%s", response); + t += rl; + cur_len += rl; + } + else + break; + } + } + + sendto_one(source_p, "%s", buf); +} + +static struct Message userhost_msgtab = { + "USERHOST", 0, 0, 1, 1, MFLG_SLOW, 0, + {m_unregistered, m_userhost, m_userhost, m_ignore, m_userhost, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&userhost_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&userhost_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_users.c b/modules/m_users.c new file mode 100644 index 0000000..14ab296 --- /dev/null +++ b/modules/m_users.c @@ -0,0 +1,120 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_users.c: Gives some basic user statistics. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "s_serv.h" +#include "conf.h" +#include "send.h" +#include "parse.h" +#include "modules.h" + + +/* + * m_users + * parv[0] = sender prefix + * parv[1] = servername + */ +static void +m_users(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + static time_t last_used = 0; + + if (last_used + ConfigFileEntry.pace_wait_simple > CurrentTime) + { + sendto_one(source_p, form_str(RPL_LOAD2HI), + me.name, source_p->name); + return; + } + + last_used = CurrentTime; + + if (!ConfigFileEntry.disable_remote) + if (hunt_server(client_p, source_p, ":%s USERS :%s", 1, + parc, parv) != HUNTED_ISME) + return; + + sendto_one(source_p, form_str(RPL_LOCALUSERS), me.name, source_p->name, + ConfigServerHide.hide_servers ? Count.total : Count.local, + ConfigServerHide.hide_servers ? Count.max_tot : Count.max_loc, + ConfigServerHide.hide_servers ? Count.total : Count.local, + ConfigServerHide.hide_servers ? Count.max_tot : Count.max_loc); + + sendto_one(source_p, form_str(RPL_GLOBALUSERS), me.name, source_p->name, + Count.total, Count.max_tot, Count.total, Count.max_tot); +} + +/* + * mo_users + * parv[0] = sender prefix + * parv[1] = servername + */ +static void +mo_users(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (hunt_server(client_p, source_p, ":%s USERS :%s", 1, + parc, parv) != HUNTED_ISME) + return; + + if (!HasUMode(source_p, UMODE_OPER) && ConfigServerHide.hide_servers) + sendto_one(source_p, form_str(RPL_LOCALUSERS), me.name, source_p->name, + Count.total, Count.max_tot, Count.total, Count.max_tot); + else + sendto_one(source_p, form_str(RPL_LOCALUSERS), me.name, source_p->name, + Count.local, Count.max_loc, Count.local, Count.max_loc); + + sendto_one(source_p, form_str(RPL_GLOBALUSERS), me.name, source_p->name, + Count.total, Count.max_tot, Count.total, Count.max_tot); +} + +static struct Message users_msgtab = { + "USERS", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_users, mo_users, m_ignore, mo_users, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&users_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&users_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_version.c b/modules/m_version.c new file mode 100644 index 0000000..5a9d9cc --- /dev/null +++ b/modules/m_version.c @@ -0,0 +1,189 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_version.c: Shows ircd version information. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "numeric.h" +#include "conf.h" +#include "s_serv.h" +#include "s_user.h" +#include "send.h" +#include "parse.h" +#include "modules.h" + + +/* Option string. */ +static const char serveropts[] = { + ' ', + 'T', + 'S', +#ifdef TS_CURRENT + '0' + TS_CURRENT, +#endif +/* ONLY do TS */ +/* ALWAYS do TS_WARNINGS */ + 'o', + 'w', + '\0' +}; + +/* confopts() + * + * input - client pointer + * output - ircd.conf option string + * side effects - none + */ +static char * +confopts(struct Client *source_p) +{ + static char result[12]; + char *p = result; + + *p++ = 'e'; /* excepts */ + + if (ConfigFileEntry.glines) + *p++ = 'G'; + *p++ = 'g'; + + /* might wanna hide this :P */ + if (ServerInfo.hub && + (!ConfigFileEntry.disable_remote || HasUMode(source_p, UMODE_OPER))) + { + *p++ = 'H'; + } + + *p++ = 'I'; /* invex */ + *p++ = 'K'; /* knock */ + *p++ = 'M'; + + if (ConfigFileEntry.ignore_bogus_ts) + *p++ = 'T'; + *p++ = '6'; + + *p = '\0'; + + return result; +} + +/* + * m_version - VERSION command handler + * parv[0] = sender prefix + * parv[1] = remote server + */ +static void +m_version(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + static time_t last_used = 0; + + if ((last_used + ConfigFileEntry.pace_wait_simple) > CurrentTime) + { + /* safe enough to give this on a local connect only */ + sendto_one(source_p, form_str(RPL_LOAD2HI), + me.name, source_p->name); + return; + } + + last_used = CurrentTime; + + if (!ConfigFileEntry.disable_remote) + if (hunt_server(client_p, source_p, ":%s VERSION :%s", + 1, parc, parv) != HUNTED_ISME) + return; + + sendto_one(source_p, form_str(RPL_VERSION), + me.name, source_p->name, ircd_version, serno, + me.name, confopts(source_p), serveropts); + show_isupport(source_p); +} + +/* + * mo_version - VERSION command handler + * parv[0] = sender prefix + * parv[1] = remote server + */ +static void +mo_version(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + + if (hunt_server(client_p, source_p, ":%s VERSION :%s", + 1, parc, parv) != HUNTED_ISME) + return; + + sendto_one(source_p, form_str(RPL_VERSION), me.name, + source_p->name, ircd_version, + serno, me.name, confopts(source_p), serveropts); + + show_isupport(source_p); +} + +/* + * ms_version - VERSION command handler + * parv[0] = sender prefix + * parv[1] = remote server + */ +static void +ms_version(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (hunt_server(client_p, source_p, ":%s VERSION :%s", + 1, parc, parv) == HUNTED_ISME) + { + sendto_one(source_p, form_str(RPL_VERSION), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), + ircd_version, serno, + me.name, confopts(source_p), serveropts); + show_isupport(source_p); + } +} + +static struct Message version_msgtab = { + "VERSION", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_version, ms_version, m_ignore, mo_version, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&version_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&version_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_wallops.c b/modules/m_wallops.c new file mode 100644 index 0000000..c05a56d --- /dev/null +++ b/modules/m_wallops.c @@ -0,0 +1,112 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_wallops.c: Sends a message to all operators. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "ircd.h" +#include "irc_string.h" +#include "numeric.h" +#include "send.h" +#include "s_user.h" +#include "parse.h" +#include "modules.h" +#include "s_serv.h" + + +/* + * mo_wallops (write to *all* opers currently online) + * parv[0] = sender prefix + * parv[1] = message text + */ +static void +mo_wallops(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *message = parv[1]; + + if (EmptyString(message)) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "WALLOPS"); + return; + } + + sendto_wallops_flags(UMODE_OPERWALL, source_p, "OPERWALL - %s", message); + sendto_server(NULL, CAP_TS6, NOCAPS, + ":%s WALLOPS :%s", ID(source_p), message); + sendto_server(NULL, NOCAPS, CAP_TS6, + ":%s WALLOPS :%s", source_p->name, message); +} + +/* + * ms_wallops (write to *all* opers currently online) + * parv[0] = sender prefix + * parv[1] = message text + */ +static void +ms_wallops(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *message = parv[1]; + + if (EmptyString(message)) + return; + + if (IsClient(source_p)) + sendto_wallops_flags(UMODE_OPERWALL, source_p, "OPERWALL - %s", message); + else + sendto_wallops_flags(UMODE_WALLOP, source_p, "%s", message); + + sendto_server(client_p, CAP_TS6, NOCAPS, + ":%s WALLOPS :%s", ID(source_p), message); + sendto_server(client_p, NOCAPS, CAP_TS6, + ":%s WALLOPS :%s", source_p->name, message); +} + +static struct Message wallops_msgtab = { + "WALLOPS", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_not_oper, ms_wallops, m_ignore, mo_wallops, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&wallops_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&wallops_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_watch.c b/modules/m_watch.c new file mode 100644 index 0000000..8e952f1 --- /dev/null +++ b/modules/m_watch.c @@ -0,0 +1,269 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_watch.c: Maintains notify list + * + * Copyright (C) 1997 Jukka Santala (Donwulff) + * Copyright (C) 2005 by the Hybrid 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 + * + * $Id$ + */ + +#include "stdinc.h" +#include "client.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "conf.h" +#include "send.h" +#include "parse.h" +#include "modules.h" +#include "s_user.h" +#include "watch.h" + + +/* + * RPL_NOWON - Online at the moment (Succesfully added to WATCH-list) + * RPL_NOWOFF - Offline at the moment (Succesfully added to WATCH-list) + * RPL_WATCHOFF - Succesfully removed from WATCH-list. + * ERR_TOOMANYWATCH - Take a guess :> Too many WATCH entries. + */ +static void +show_watch(struct Client *client_p, const char *name, + unsigned int rpl1, unsigned int rpl2) +{ + const struct Client *target_p = NULL; + + if ((target_p = find_person(client_p, name))) + sendto_one(client_p, form_str(rpl1), me.name, client_p->name, + target_p->name, target_p->username, + target_p->host, target_p->tsinfo); + else + sendto_one(client_p, form_str(rpl2), me.name, client_p->name, + name, "*", "*", 0); +} + +/* + * m_watch() + * + * parv[0] = sender prefix + * parv[1] = watch options + */ +static void +m_watch(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) +{ + dlink_node *ptr = NULL; + char *s = NULL; + char *p = NULL; + char *user; + char def[2] = "l"; + unsigned int list_requested = 0; + + /* + * Default to 'l' - list who's currently online + */ + if (parc < 2) + parv[1] = def; + + for (s = strtoken(&p, parv[1], ", "); s; + s = strtoken(&p, NULL, ", ")) + { + if ((user = strchr(s, '!'))) + *user++ = '\0'; /* Not used */ + + /* + * Prefix of "+", they want to add a name to their WATCH + * list. + */ + if (*s == '+') + { + if (*(s + 1) != '\0') + { + if (dlink_list_length(&source_p->localClient->watches) >= + ConfigFileEntry.max_watch) + { + sendto_one(source_p, form_str(ERR_TOOMANYWATCH), me.name, + source_p->name, s + 1, ConfigFileEntry.max_watch); + continue; + } + + watch_add_to_hash_table(s + 1, source_p); + } + + show_watch(source_p, s + 1, RPL_NOWON, RPL_NOWOFF); + continue; + } + + /* + * Prefix of "-", coward wants to remove somebody from their + * WATCH list. So do it. :-) + */ + if (*s == '-') + { + watch_del_from_hash_table(s + 1, source_p); + show_watch(source_p, s + 1, RPL_WATCHOFF, RPL_WATCHOFF); + continue; + } + + /* + * Fancy "C" or "c", they want to nuke their WATCH list and start + * over, so be it. + */ + if (*s == 'C' || *s == 'c') + { + watch_del_watch_list(source_p); + continue; + } + + /* + * Now comes the fun stuff, "S" or "s" returns a status report of + * their WATCH list. I imagine this could be CPU intensive if + * it's done alot, perhaps an auto-lag on this? + */ + if (*s == 'S' || *s == 's') + { + char buf[IRCD_BUFSIZE] = { '\0' }; + const struct Watch *anptr = NULL; + unsigned int count = 0; + + if (list_requested & 0x1) + continue; + + list_requested |= 0x1; + + /* + * Send a list of how many users they have on their WATCH list + * and how many WATCH lists they are on. + */ + if ((anptr = watch_find_hash(source_p->name))) + count = dlink_list_length(&anptr->watched_by); + + sendto_one(source_p, form_str(RPL_WATCHSTAT), + me.name, source_p->name, + dlink_list_length(&source_p->localClient->watches), count); + + /* + * Send a list of everybody in their WATCH list. Be careful + * not to buffer overflow. + */ + if ((ptr = source_p->localClient->watches.head) == NULL) + { + sendto_one(source_p, form_str(RPL_ENDOFWATCHLIST), + me.name, source_p->name, *s); + continue; + } + + anptr = ptr->data; + strlcpy(buf, anptr->nick, sizeof(buf)); + + count = strlen(source_p->name) + strlen(me.name) + 10 + + strlen(buf); + + while ((ptr = ptr->next)) + { + anptr = ptr->data; + + if (count + strlen(anptr->nick) + 1 > IRCD_BUFSIZE - 2) + { + sendto_one(source_p, form_str(RPL_WATCHLIST), + me.name, source_p->name, buf); + buf[0] = '\0'; + count = strlen(source_p->name) + strlen(me.name) + 10; + } + + strcat(buf, " "); + strcat(buf, anptr->nick); + count += (strlen(anptr->nick) + 1); + } + + sendto_one(source_p, form_str(RPL_WATCHLIST), + me.name, source_p->name, buf); + sendto_one(source_p, form_str(RPL_ENDOFWATCHLIST), + me.name, source_p->name, *s); + continue; + } + + /* + * Well that was fun, NOT. Now they want a list of everybody in + * their WATCH list AND if they are online or offline? Sheesh, + * greedy aren't we? + */ + if (*s == 'L' || *s == 'l') + { + const struct Client *target_p = NULL; + + if (list_requested & 0x2) + continue; + + list_requested |= 0x2; + + DLINK_FOREACH(ptr, source_p->localClient->watches.head) + { + const struct Watch *anptr = ptr->data; + + if ((target_p = find_person(source_p, anptr->nick))) + sendto_one(source_p, form_str(RPL_NOWON), me.name, source_p->name, + target_p->name, target_p->username, + target_p->host, target_p->tsinfo); + /* + * But actually, only show them offline if it's a capital + * 'L' (full list wanted). + */ + else if (*s == 'L') + sendto_one(source_p, form_str(RPL_NOWOFF), me.name, + source_p->name, anptr->nick, + "*", "*", anptr->lasttime); + } + + sendto_one(source_p, form_str(RPL_ENDOFWATCHLIST), + me.name, source_p->name, *s); + continue; + } + + /* Hmm.. unknown prefix character.. Ignore it. :-) */ + } +} + +static struct Message watch_msgtab = { + "WATCH", 0, 0, 0, 1, MFLG_SLOW, 0, + { m_unregistered, m_watch, m_ignore, m_ignore, m_watch, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&watch_msgtab); + add_isupport("WATCH", NULL, ConfigFileEntry.max_watch); +} + +static void +module_exit(void) +{ + mod_del_cmd(&watch_msgtab); + delete_isupport("WATCH"); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_who.c b/modules/m_who.c new file mode 100644 index 0000000..fa20fcd --- /dev/null +++ b/modules/m_who.c @@ -0,0 +1,368 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_who.c: Shows who is on a channel. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "channel.h" +#include "channel_mode.h" +#include "hash.h" +#include "ircd.h" +#include "numeric.h" +#include "s_serv.h" +#include "send.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "conf.h" +#include "parse.h" +#include "modules.h" + +static void who_global(struct Client *, char *, int); +static void do_who(struct Client *, struct Client *, + const char *, const char *); +static void do_who_on_channel(struct Client *, struct Channel *, + const char *, int, int); + +/* +** m_who +** parv[0] = sender prefix +** parv[1] = nickname mask list +** parv[2] = additional selection flag, only 'o' for now. +*/ +static void +m_who(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p; + char *mask = parv[1]; + dlink_node *lp; + int server_oper = parc > 2 ? (*parv[2] == 'o') : 0; /* Show OPERS only */ + struct Channel *chptr; + + /* See if mask is there, collapse it or return if not there */ + if (EmptyString(mask)) + { + who_global(source_p, mask, server_oper); + sendto_one(source_p, form_str(RPL_ENDOFWHO), + me.name, source_p->name, "*"); + return; + } + + /* mask isn't NULL at this point. repeat after me... -db */ + collapse(mask); + + /* '/who *' */ + if (!strcmp(mask, "*")) + { + if ((lp = source_p->channel.head) != NULL) + { + struct Channel *mychannel = ((struct Membership *)lp->data)->chptr; + do_who_on_channel(source_p, mychannel, mychannel->chname, 1, + server_oper); + } + + sendto_one(source_p, form_str(RPL_ENDOFWHO), + me.name, source_p->name, "*"); + return; + } + + /* '/who #some_channel' */ + if (IsChanPrefix(*mask)) + { + /* List all users on a given channel */ + if ((chptr = hash_find_channel(mask)) != NULL) + { + if (IsMember(source_p, chptr)) + do_who_on_channel(source_p, chptr, chptr->chname, 1, server_oper); + else if (!SecretChannel(chptr)) + do_who_on_channel(source_p, chptr, chptr->chname, 0, server_oper); + } + + sendto_one(source_p, form_str(RPL_ENDOFWHO), + me.name, source_p->name, mask); + return; + } + + /* '/who nick' */ + if (((target_p = hash_find_client(mask)) != NULL) && + IsClient(target_p) && (!server_oper || HasUMode(target_p, UMODE_OPER))) + { + DLINK_FOREACH(lp, target_p->channel.head) + { + chptr = ((struct Membership *) lp->data)->chptr; + if (PubChannel(chptr) || IsMember(source_p, chptr)) + break; + } + + if (lp != NULL) + do_who(source_p, target_p, chptr->chname, + get_member_status(lp->data, !!HasCap(source_p, CAP_MULTI_PREFIX))); + else + do_who(source_p, target_p, NULL, ""); + + sendto_one(source_p, form_str(RPL_ENDOFWHO), + me.name, source_p->name, mask); + return; + } + + /* '/who 0' */ + if (!strcmp(mask, "0")) + who_global(source_p, NULL, server_oper); + else + who_global(source_p, mask, server_oper); + + /* Wasn't a nick, wasn't a channel, wasn't a '*' so ... */ + sendto_one(source_p, form_str(RPL_ENDOFWHO), + me.name, source_p->name, mask); +} + +/* who_common_channel + * inputs - pointer to client requesting who + * - pointer to channel member chain. + * - char * mask to match + * - int if oper on a server or not + * - pointer to int maxmatches + * output - NONE + * side effects - lists matching clients on specified channel, + * marks matched clients. + * + */ +static void +who_common_channel(struct Client *source_p, struct Channel *chptr, + char *mask, int server_oper, int *maxmatches) +{ + dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, chptr->members.head) + { + struct Client *target_p = ((struct Membership *)ptr->data)->client_p; + + if (!HasUMode(target_p, UMODE_INVISIBLE) || HasFlag(target_p, FLAGS_MARK)) + continue; + + if (server_oper) + if (!HasUMode(target_p, UMODE_OPER) || + (HasUMode(target_p, UMODE_HIDDEN) && !HasUMode(source_p, UMODE_OPER))) + continue; + + AddFlag(target_p, FLAGS_MARK); + + assert(target_p->servptr != NULL); + + if ((mask == NULL) || + match(mask, target_p->name) || match(mask, target_p->username) || + match(mask, target_p->host) || + ((!ConfigServerHide.hide_servers || HasUMode(source_p, UMODE_OPER)) && + match(mask, target_p->servptr->name)) || + match(mask, target_p->info)) + { + do_who(source_p, target_p, NULL, ""); + + if (*maxmatches > 0) + { + if (--(*maxmatches) == 0) + return; + } + } + } +} + +/* who_global() + * + * inputs - pointer to client requesting who + * - char * mask to match + * - int if oper on a server or not + * output - NONE + * side effects - do a global scan of all clients looking for match + * this is slightly expensive on EFnet ... + */ +static void +who_global(struct Client *source_p, char *mask, int server_oper) +{ + struct Channel *chptr; + struct Client *target_p; + dlink_node *lp; + dlink_node *lp_next; + dlink_node *gcptr; + dlink_node *gcptr_next; + int maxmatches = 500; + static time_t last_used = 0; + + if (!HasUMode(source_p, UMODE_OPER)) + { + if ((last_used + ConfigFileEntry.pace_wait) > CurrentTime) + { + /* safe enough to give this on a local connect only */ + sendto_one(source_p, form_str(RPL_LOAD2HI), me.name, source_p->name); + return; + } + + last_used = CurrentTime; + } + + /* first, list all matching invisible clients on common channels */ + DLINK_FOREACH_SAFE(lp, lp_next, source_p->channel.head) + { + chptr = ((struct Membership *)lp->data)->chptr; + who_common_channel(source_p, chptr, mask, server_oper, &maxmatches); + } + + /* second, list all matching visible clients */ + DLINK_FOREACH_SAFE(gcptr, gcptr_next, global_client_list.head) + { + target_p = gcptr->data; + + if (!IsClient(target_p)) + continue; + + if (HasUMode(target_p, UMODE_INVISIBLE)) + { + DelFlag(target_p, FLAGS_MARK); + continue; + } + + if (server_oper) + if (!HasUMode(target_p, UMODE_OPER) || + (HasUMode(target_p, UMODE_HIDDEN) && !HasUMode(source_p, UMODE_OPER))) + continue; + + assert(target_p->servptr != NULL); + + if (!mask || + match(mask, target_p->name) || match(mask, target_p->username) || + match(mask, target_p->host) || match(mask, target_p->servptr->name) || + match(mask, target_p->info)) + { + do_who(source_p, target_p, NULL, ""); + + if (maxmatches > 0) + { + if (--maxmatches == 0) + return; + } + } + } +} + +/* do_who_on_channel() + * + * inputs - pointer to client requesting who + * - pointer to channel to do who on + * - The "real name" of this channel + * - int if source_p is a server oper or not + * - int if client is member or not + * - int server_op flag + * output - NONE + * side effects - do a who on given channel + */ +static void +do_who_on_channel(struct Client *source_p, struct Channel *chptr, + const char *chname, int member, int server_oper) +{ + dlink_node *ptr = NULL, *ptr_next = NULL; + struct Client *target_p; + struct Membership *ms; + + DLINK_FOREACH_SAFE(ptr, ptr_next, chptr->members.head) + { + ms = ptr->data; + target_p = ms->client_p; + + if (member || !HasUMode(target_p, UMODE_INVISIBLE)) + { + if (server_oper) + if (!HasUMode(target_p, UMODE_OPER) || + (HasUMode(target_p, UMODE_HIDDEN) && !HasUMode(source_p, UMODE_OPER))) + continue; + do_who(source_p, target_p, chname, get_member_status(ms, !!HasCap(source_p, CAP_MULTI_PREFIX))); + } + } +} + +/* do_who() + * + * inputs - pointer to client requesting who + * - pointer to client to do who on + * - The reported name + * - channel flags + * output - NONE + * side effects - do a who on given person + */ +static void +do_who(struct Client *source_p, struct Client *target_p, + const char *chname, const char *op_flags) +{ + char status[7]; /* G*@%+\0 */ + + if (HasUMode(source_p, UMODE_OPER)) + snprintf(status, sizeof(status), "%c%s%s", target_p->away[0] ? 'G' : 'H', + HasUMode(target_p, UMODE_OPER) ? "*" : "", op_flags); + else + snprintf(status, sizeof(status), "%c%s%s", target_p->away[0] ? 'G' : 'H', + HasUMode(target_p, UMODE_OPER) && + !HasUMode(target_p, UMODE_HIDDEN) ? "*" : "", op_flags); + + if (ConfigServerHide.hide_servers) + { + sendto_one(source_p, form_str(RPL_WHOREPLY), me.name, source_p->name, + (chname) ? (chname) : "*", + target_p->username, target_p->host, + HasUMode(source_p, UMODE_OPER) ? target_p->servptr->name : "*", + target_p->name, status, 0, target_p->info); + } + else + { + sendto_one(source_p, form_str(RPL_WHOREPLY), me.name, source_p->name, + (chname) ? (chname) : "*", target_p->username, + target_p->host, target_p->servptr->name, target_p->name, + status, target_p->hopcount, target_p->info); + } +} + +static struct Message who_msgtab = { + "WHO", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + {m_unregistered, m_who, m_ignore, m_ignore, m_who, m_ignore} +}; + +static void +module_init(void) +{ + mod_add_cmd(&who_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&who_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_whois.c b/modules/m_whois.c new file mode 100644 index 0000000..682fc10 --- /dev/null +++ b/modules/m_whois.c @@ -0,0 +1,421 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_whois.c: Shows who a user is. + * + * Copyright (C) 2005 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "hash.h" +#include "channel.h" +#include "channel_mode.h" +#include "ircd.h" +#include "numeric.h" +#include "conf.h" +#include "s_misc.h" +#include "s_serv.h" +#include "send.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "parse.h" +#include "modules.h" + + +static void do_whois(struct Client *, int, char *[]); +static int single_whois(struct Client *, struct Client *); +static void whois_person(struct Client *, struct Client *); +static int global_whois(struct Client *, const char *); + + +/* +** m_whois +** parv[0] = sender prefix +** parv[1] = nickname masklist +*/ +static void +m_whois(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + static time_t last_used = 0; + + if (parc < 2 || EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), + me.name, source_p->name); + return; + } + + if (parc > 2 && !EmptyString(parv[2])) + { + /* seeing as this is going across servers, we should limit it */ + if ((last_used + ConfigFileEntry.pace_wait_simple) > CurrentTime) + { + sendto_one(source_p, form_str(RPL_LOAD2HI), + me.name, source_p->name); + return; + } + + last_used = CurrentTime; + + /* if we have serverhide enabled, they can either ask the clients + * server, or our server.. I dont see why they would need to ask + * anything else for info about the client.. --fl_ + */ + if (ConfigFileEntry.disable_remote) + parv[1] = parv[2]; + + if (hunt_server(client_p, source_p, ":%s WHOIS %s :%s", 1, + parc, parv) != HUNTED_ISME) + return; + + parv[1] = parv[2]; + } + + do_whois(source_p, parc, parv); +} + +/* +** mo_whois +** parv[0] = sender prefix +** parv[1] = nickname masklist +*/ +static void +mo_whois(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc < 2 || EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), + me.name, source_p->name); + return; + } + + if (parc > 2 && !EmptyString(parv[2])) + { + if (hunt_server(client_p, source_p, ":%s WHOIS %s :%s", 1, + parc, parv) != HUNTED_ISME) + return; + + parv[1] = parv[2]; + } + + do_whois(source_p, parc, parv); +} + +/* do_whois() + * + * inputs - pointer to /whois source + * - number of parameters + * - pointer to parameters array + * output - pointer to void + * side effects - Does whois + */ +static void +do_whois(struct Client *source_p, int parc, char *parv[]) +{ + static time_t last_used = 0; + struct Client *target_p; + char *nick; + char *p = NULL; + int found = 0; + + nick = parv[1]; + while (*nick == ',') + nick++; + if ((p = strchr(nick,',')) != NULL) + *p = '\0'; + + if (*nick == '\0') + return; + + collapse(nick); + + if (strpbrk(nick, "?#*") == NULL) + { + if ((target_p = hash_find_client(nick)) != NULL) + { + if (IsClient(target_p)) + { + whois_person(source_p, target_p); + found = 1; + } + } + } + else /* wilds is true */ + { + if (!HasUMode(source_p, UMODE_OPER)) + { + if ((last_used + ConfigFileEntry.pace_wait_simple) > CurrentTime) + { + sendto_one(source_p, form_str(RPL_LOAD2HI), + me.name, source_p->name); + return; + } + else + last_used = CurrentTime; + } + + /* Oh-oh wilds is true so have to do it the hard expensive way */ + if (MyClient(source_p)) + found = global_whois(source_p, nick); + } + + if (!found) + { + if (!IsDigit(*nick)) + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, nick); + } + + sendto_one(source_p, form_str(RPL_ENDOFWHOIS), + me.name, source_p->name, parv[1]); +} + +/* global_whois() + * + * Inputs - source_p client to report to + * - target_p client to report on + * Output - if found return 1 + * Side Effects - do a single whois on given client + * writing results to source_p + */ +static int +global_whois(struct Client *source_p, const char *nick) +{ + dlink_node *ptr; + struct Client *target_p; + int found = 0; + + DLINK_FOREACH(ptr, global_client_list.head) + { + target_p = ptr->data; + + if (!IsClient(target_p)) + continue; + + if (!match(nick, target_p->name)) + continue; + + assert(target_p->servptr != NULL); + + /* 'Rules' established for sending a WHOIS reply: + * + * + * - if wildcards are being used dont send a reply if + * the querier isnt any common channels and the + * client in question is invisible and wildcards are + * in use (allow exact matches only); + * + * - only send replies about common or public channels + * the target user(s) are on; + */ + + found |= single_whois(source_p, target_p); + } + + return found; +} + +/* single_whois() + * + * Inputs - source_p client to report to + * - target_p client to report on + * Output - if found return 1 + * Side Effects - do a single whois on given client + * writing results to source_p + */ +static int +single_whois(struct Client *source_p, struct Client *target_p) +{ + dlink_node *ptr = NULL; + + if (!HasUMode(target_p, UMODE_INVISIBLE) || target_p == source_p) + { + /* always show user if they are visible (no +i) */ + whois_person(source_p, target_p); + return 1; + } + + /* target_p is +i. Check if it is on any common channels with source_p */ + DLINK_FOREACH(ptr, target_p->channel.head) + { + struct Channel *chptr = ((struct Membership *) ptr->data)->chptr; + + if (IsMember(source_p, chptr)) + { + whois_person(source_p, target_p); + return 1; + } + } + + return 0; +} + +/* whois_person() + * + * inputs - source_p client to report to + * - target_p client to report on + * output - NONE + * side effects - + */ +static void +whois_person(struct Client *source_p, struct Client *target_p) +{ + char buf[IRCD_BUFSIZE]; + dlink_node *lp; + struct Client *server_p; + struct Channel *chptr; + struct Membership *ms; + int cur_len = 0; + int mlen; + char *t = NULL; + int tlen; + int reply_to_send = 0; + int show_ip = 0; + + server_p = target_p->servptr; + + sendto_one(source_p, form_str(RPL_WHOISUSER), + me.name, source_p->name, target_p->name, + target_p->username, target_p->host, target_p->info); + + cur_len = mlen = snprintf(buf, sizeof(buf), form_str(RPL_WHOISCHANNELS), + me.name, source_p->name, target_p->name, ""); + t = buf + mlen; + + DLINK_FOREACH(lp, target_p->channel.head) + { + ms = lp->data; + chptr = ms->chptr; + + if (ShowChannel(source_p, chptr)) + { + if ((cur_len + 3 + strlen(chptr->chname) + 1) > (IRCD_BUFSIZE - 2)) + { + *(t - 1) = '\0'; + sendto_one(source_p, "%s", buf); + cur_len = mlen; + t = buf + mlen; + } + + tlen = ircsprintf(t, "%s%s ", get_member_status(ms, 1), chptr->chname); + t += tlen; + cur_len += tlen; + reply_to_send = 1; + } + } + + if (reply_to_send) + { + *(t - 1) = '\0'; + sendto_one(source_p, "%s", buf); + } + + if (HasUMode(source_p, UMODE_OPER) || !ConfigServerHide.hide_servers || target_p == source_p) + sendto_one(source_p, form_str(RPL_WHOISSERVER), + me.name, source_p->name, target_p->name, + server_p->name, server_p->info); + else + sendto_one(source_p, form_str(RPL_WHOISSERVER), + me.name, source_p->name, target_p->name, + ConfigServerHide.hidden_name, + ServerInfo.network_desc); + + if (HasUMode(target_p, UMODE_REGISTERED)) + sendto_one(source_p, form_str(RPL_WHOISREGNICK), + me.name, source_p->name, target_p->name); + + if (target_p->away[0]) + sendto_one(source_p, form_str(RPL_AWAY), + me.name, source_p->name, target_p->name, + target_p->away); + + if (HasUMode(target_p, UMODE_CALLERID) && !HasUMode(target_p, UMODE_SOFTCALLERID)) + sendto_one(source_p, form_str(RPL_TARGUMODEG), + me.name, source_p->name, target_p->name); + + if (HasUMode(target_p, UMODE_OPER)) + if (!HasUMode(target_p, UMODE_HIDDEN) || HasUMode(source_p, UMODE_OPER)) + sendto_one(source_p, form_str(HasUMode(target_p, UMODE_ADMIN) ? RPL_WHOISADMIN : + RPL_WHOISOPERATOR), + me.name, source_p->name, target_p->name); + + if (strcmp(target_p->sockhost, "0")) + { + if (HasUMode(source_p, UMODE_ADMIN) || source_p == target_p) + show_ip = 1; + else if (IsIPSpoof(target_p)) + show_ip = (HasUMode(source_p, UMODE_OPER) && !ConfigFileEntry.hide_spoof_ips); + else + show_ip = 1; + + sendto_one(source_p, form_str(RPL_WHOISACTUALLY), + me.name, source_p->name, target_p->name, + show_ip ? target_p->sockhost : "255.255.255.255"); + } + + if (MyConnect(target_p)) /* Can't do any of this if not local! db */ + { +#ifdef HAVE_LIBCRYPTO + if (target_p->localClient->fd.ssl) + sendto_one(source_p, form_str(RPL_WHOISSECURE), + me.name, source_p->name, target_p->name); +#endif + sendto_one(source_p, form_str(RPL_WHOISIDLE), + me.name, source_p->name, target_p->name, + CurrentTime - target_p->localClient->last_privmsg, + target_p->localClient->firsttime); + + if (HasUMode(target_p, UMODE_OPER) && target_p != source_p) + if (HasUMode(target_p, UMODE_SPY)) + sendto_one(target_p, ":%s NOTICE %s :*** Notice -- %s (%s@%s) [%s] is doing " + "a whois on you", me.name, target_p->name, source_p->name, + source_p->username, source_p->host, source_p->servptr->name); + } +} + +static struct Message whois_msgtab = { + "WHOIS", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_whois, mo_whois, m_ignore, mo_whois, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&whois_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&whois_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_whowas.c b/modules/m_whowas.c new file mode 100644 index 0000000..2f6da27 --- /dev/null +++ b/modules/m_whowas.c @@ -0,0 +1,175 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_whois.c: Shows who a user was. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "whowas.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" +#include "ircd_defs.h" +#include "numeric.h" +#include "s_serv.h" +#include "s_user.h" +#include "send.h" +#include "conf.h" +#include "parse.h" +#include "modules.h" + + +static void +whowas_do(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + int cur = 0; + int max = -1; + char *p = NULL, *nick = NULL; + const dlink_node *ptr = NULL; + + if (parc > 2) + { + max = atoi(parv[2]); + + if (!MyConnect(source_p) && max > 20) + max = 20; + } + + if (parc > 3) + if (hunt_server(client_p, source_p, ":%s WHOWAS %s %s :%s", 3, + parc, parv) != HUNTED_ISME) + return; + + nick = parv[1]; + while (*nick == ',') + nick++; + if ((p = strchr(nick,',')) != NULL) + *p = '\0'; + if (*nick == '\0') + return; + + DLINK_FOREACH(ptr, WHOWASHASH[strhash(nick)].head) + { + const struct Whowas *temp = ptr->data; + + if (!irccmp(nick, temp->name)) + { + sendto_one(source_p, form_str(RPL_WHOWASUSER), + me.name, source_p->name, temp->name, + temp->username, temp->hostname, + temp->realname); + + if (ConfigServerHide.hide_servers && !HasUMode(source_p, UMODE_OPER)) + sendto_one(source_p, form_str(RPL_WHOISSERVER), + me.name, source_p->name, temp->name, + ServerInfo.network_name, myctime(temp->logoff)); + else + sendto_one(source_p, form_str(RPL_WHOISSERVER), + me.name, source_p->name, temp->name, + temp->servername, myctime(temp->logoff)); + ++cur; + } + + if (max > 0 && cur >= max) + break; + } + + if (!cur) + sendto_one(source_p, form_str(ERR_WASNOSUCHNICK), + me.name, source_p->name, nick); + + sendto_one(source_p, form_str(RPL_ENDOFWHOWAS), + me.name, source_p->name, parv[1]); +} + +/* +** m_whowas +** parv[0] = sender prefix +** parv[1] = nickname queried +*/ +static void +m_whowas(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + static time_t last_used = 0; + + if (parc < 2 || EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), + me.name, source_p->name); + return; + } + + if ((last_used + ConfigFileEntry.pace_wait) > CurrentTime) + { + sendto_one(source_p,form_str(RPL_LOAD2HI), + me.name, source_p->name); + return; + } + + last_used = CurrentTime; + + whowas_do(client_p, source_p, parc, parv); +} + +static void +mo_whowas(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc < 2 || EmptyString(parv[1])) + { + sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), + me.name, source_p->name); + return; + } + + whowas_do(client_p, source_p, parc, parv); +} + +static struct Message whowas_msgtab = { + "WHOWAS", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_whowas, mo_whowas, m_ignore, mo_whowas, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&whowas_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&whowas_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/modules/m_xline.c b/modules/m_xline.c new file mode 100644 index 0000000..3a70299 --- /dev/null +++ b/modules/m_xline.c @@ -0,0 +1,467 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * m_xline.c: xlines an user. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "client.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "hostmask.h" +#include "numeric.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "conf.h" +#include "log.h" +#include "s_misc.h" +#include "send.h" +#include "hash.h" +#include "s_serv.h" +#include "parse.h" +#include "modules.h" +#include "resv.h" + + +static int valid_xline(struct Client *, char *, char *, int); +static void write_xline(struct Client *, char *, char *, time_t); +static void remove_xline(struct Client *, char *); +static int remove_txline_match(const char *); + +static void relay_xline(struct Client *, char *[]); + +/* mo_xline() + * + * inputs - pointer to server + * - pointer to client + * - parameter count + * - parameter list + * output - + * side effects - x line is added + * + */ +static void +mo_xline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *reason = NULL; + char *gecos = NULL; + struct ConfItem *conf = NULL; + struct MatchItem *match_item = NULL; + char *target_server = NULL; + time_t tkline_time = 0; + + if (!HasOFlag(source_p, OPER_FLAG_X)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "xline"); + return; + } + + /* + * XLINE <gecos> <time> ON <mask> :<reason> + * XLINE <gecos> ON <mask> :<reason> + */ + if (parse_aline("XLINE", source_p, parc, parv, AWILD, &gecos, NULL, + &tkline_time, &target_server, &reason) < 0) + return; + + if (target_server != NULL) + { + /* if a given expire time is given, ENCAP it */ + if (tkline_time != 0) + sendto_match_servs(source_p, target_server, CAP_ENCAP, + "ENCAP %s XLINE %d %s 0 :%s", + target_server, (int)tkline_time, gecos, reason); + else + sendto_match_servs(source_p, target_server, CAP_CLUSTER, + "XLINE %s %s %d :%s", + target_server, gecos, (int)tkline_time, reason); + + /* Allow ON to apply local xline as well if it matches */ + if (!match(target_server, me.name)) + return; + } + else + { + if (tkline_time != 0) + cluster_a_line(source_p, "ENCAP", CAP_ENCAP, SHARED_XLINE, + "XLINE %d %s 0 :%s", (int)tkline_time, gecos, reason); + else + cluster_a_line(source_p, "XLINE", CAP_KLN, SHARED_XLINE, + "%s 0 :%s", gecos, reason); + } + + if (!valid_xline(source_p, gecos, reason, 0)) + return; + + if ((conf = find_matching_name_conf(XLINE_TYPE, gecos, + NULL, NULL, 0)) != NULL) + { + match_item = map_to_conf(conf); + + sendto_one(source_p, ":%s NOTICE %s :[%s] already X-Lined by [%s] - %s", + me.name, source_p->name, gecos, + conf->name, match_item->reason); + return; + } + + write_xline(source_p, gecos, reason, tkline_time); +} + +/* ms_xline() + * + * inputs - oper, target server, xline, {type}, reason + * deprecate {type} reserve for temp xlines later? XXX + * + * outputs - none + * side effects - propagates xline, applies it if we are a target + */ +static void +ms_xline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc != 5 || EmptyString(parv[4])) + return; + + if (!IsClient(source_p)) + return; + + if (!valid_xline(source_p, parv[2], parv[4], 0)) + return; + + relay_xline(source_p, parv); +} + +/* me_xline() + * + * inputs - server + * - client (oper) + * - parc number of arguments + * - parv list of arguments + * via parv[] + * parv[1] = target + * parv[2] = server + * parv[3] = xline + * parv[4] = time + * parv[5] = reason + * + * outputs - none + * side effects - + */ +static void +me_xline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (!IsClient(source_p) || parc != 5) + return; + + relay_xline(source_p, parv); +} + +static void +relay_xline(struct Client *source_p, char *parv[]) +{ + struct ConfItem *conf; + struct MatchItem *match_item; + int t_sec; + + t_sec = atoi(parv[3]); + /* XXX kludge! */ + if (t_sec < 3) + t_sec = 0; + + sendto_match_servs(source_p, parv[1], CAP_CLUSTER, + "XLINE %s %s %s :%s", + parv[1], parv[2], parv[3], parv[4]); + + if (!match(parv[1], me.name)) + return; + + if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(ULINE_TYPE, source_p->servptr->name, + source_p->username, source_p->host, + SHARED_XLINE)) + { + if ((conf = find_matching_name_conf(XLINE_TYPE, parv[2], + NULL, NULL, 0)) != NULL) + { + match_item = map_to_conf(conf); + sendto_one(source_p, ":%s NOTICE %s :[%s] already X-Lined by [%s] - %s", + ID_or_name(&me, source_p->from), + ID_or_name(source_p, source_p->from), + parv[2], conf->name, match_item->reason); + return; + } + + write_xline(source_p, parv[2], parv[4], t_sec); + } +} + +/* mo_unxline() + * + * inputs - pointer to server + * - pointer to client + * - parameter count + * - parameter list + * output - + * side effects - removes a xline + */ +static void +mo_unxline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + char *gecos = NULL; + char *target_server = NULL; + + if (!HasOFlag(source_p, OPER_FLAG_X)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "unxline"); + return; + } + + /* UNXLINE bill ON irc.server.com */ + if (parse_aline("UNXLINE", source_p, parc, parv, 0, &gecos, + NULL, NULL, &target_server, NULL) < 0) + return; + + if (target_server != NULL) + { + sendto_match_servs(source_p, target_server, CAP_CLUSTER, + "UNXLINE %s %s", target_server, gecos); + + /* Allow ON to apply local unxline as well if it matches */ + if (!match(target_server, me.name)) + return; + } + else + cluster_a_line(source_p, "UNXLINE", CAP_CLUSTER, SHARED_UNXLINE, + "%s", gecos); + + remove_xline(source_p, gecos); +} + +/* ms_unxline() + * + * inputs - oper, target server, gecos + * outputs - none + * side effects - propagates unxline, applies it if we are a target + */ +static void +ms_unxline(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + if (parc != 3) + return; + + if (!IsClient(source_p) || EmptyString(parv[2])) + return; + + sendto_match_servs(source_p, parv[1], CAP_CLUSTER, + "UNXLINE %s %s", parv[1], parv[2]); + + if (!match(parv[1], me.name)) + return; + + if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(ULINE_TYPE, source_p->servptr->name, + source_p->username, source_p->host, + SHARED_UNXLINE)) + remove_xline(source_p, parv[2]); +} + +/* valid_xline() + * + * inputs - client to complain to, gecos, reason, whether to complain + * outputs - 1 for valid, else 0 + * side effects - complains to client, when warn != 0 + */ +static int +valid_xline(struct Client *source_p, char *gecos, char *reason, int warn) +{ + if (EmptyString(reason)) + { + if (warn) + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, "XLINE"); + return 0; + } + + if (strchr(gecos, '"')) + { + sendto_one(source_p, ":%s NOTICE %s :Invalid character '\"'", + me.name, source_p->name); + return 0; + } + + if (!valid_wild_card_simple(gecos)) + { + if (warn) + sendto_one(source_p, ":%s NOTICE %s :Please include at least %d non-wildcard characters with the xline", + me.name, source_p->name, ConfigFileEntry.min_nonwildcard_simple); + + return 0; + } + + return 1; +} + +/* write_xline() + * + * inputs - client taking credit for xline, gecos, reason, xline type + * outputs - none + * side effects - when successful, adds an xline to the conf + */ +static void +write_xline(struct Client *source_p, char *gecos, char *reason, + time_t tkline_time) +{ + struct ConfItem *conf; + struct MatchItem *match_item; + const char *current_date; + time_t cur_time; + + conf = make_conf_item(XLINE_TYPE); + match_item = map_to_conf(conf); + + collapse(gecos); + DupString(conf->name, gecos); + DupString(match_item->reason, reason); + DupString(match_item->oper_reason, ""); /* XXX */ + cur_time = CurrentTime; + current_date = smalldate(cur_time); + + if (tkline_time != 0) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s added temporary %d min. X-Line for [%s] [%s]", + get_oper_name(source_p), (int)tkline_time/60, + conf->name, match_item->reason); + sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. X-Line [%s]", + MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from), + source_p->name, (int)tkline_time/60, conf->name); + ilog(LOG_TYPE_KLINE, "%s added temporary %d min. X-Line for [%s] [%s]", + source_p->name, (int)tkline_time/60, + conf->name, match_item->reason); + match_item->hold = CurrentTime + tkline_time; + add_temp_line(conf); + } + else + write_conf_line(source_p, conf, current_date, cur_time); + rehashed_klines = 1; +} + +static void +remove_xline(struct Client *source_p, char *gecos) +{ + /* XXX use common temporary un function later */ + if (remove_txline_match(gecos)) + { + sendto_one(source_p, + ":%s NOTICE %s :Un-xlined [%s] from temporary X-Lines", + me.name, source_p->name, gecos); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has removed the temporary X-Line for: [%s]", + get_oper_name(source_p), gecos); + ilog(LOG_TYPE_KLINE, "%s removed temporary X-Line for [%s]", + source_p->name, gecos); + return; + } + + if (remove_conf_line(XLINE_TYPE, source_p, gecos, NULL) > 0) + { + sendto_one(source_p, ":%s NOTICE %s :X-Line for [%s] is removed", + me.name, source_p->name, gecos); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s has removed the X-Line for: [%s]", + get_oper_name(source_p), gecos); + ilog(LOG_TYPE_KLINE, "%s removed X-Line for [%s]", + get_oper_name(source_p), gecos); + } + else + sendto_one(source_p, ":%s NOTICE %s :No X-Line for %s", + me.name, source_p->name, gecos); +} + +/* static int remove_tkline_match(const char *host, const char *user) + * + * Inputs: gecos + * Output: returns YES on success, NO if no tkline removed. + * Side effects: Any matching tklines are removed. + */ +static int +remove_txline_match(const char *gecos) +{ + dlink_node *ptr = NULL, *next_ptr = NULL; + struct ConfItem *conf = NULL; + + DLINK_FOREACH_SAFE(ptr, next_ptr, temporary_xlines.head) + { + conf = ptr->data; + + if (irccmp(gecos, conf->name) == 0) + { + dlinkDelete(ptr, &temporary_xlines); + free_dlink_node(ptr); + delete_conf_item(conf); + + return 1; + } + } + + return 0; +} + +static struct Message xline_msgtab = { + "XLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, ms_xline, me_xline, mo_xline, m_ignore } +}; + +static struct Message unxline_msgtab = { + "UNXLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, + { m_unregistered, m_not_oper, ms_unxline, m_ignore, mo_unxline, m_ignore } +}; + +static void +module_init(void) +{ + mod_add_cmd(&xline_msgtab); + mod_add_cmd(&unxline_msgtab); +} + +static void +module_exit(void) +{ + mod_del_cmd(&xline_msgtab); + mod_del_cmd(&unxline_msgtab); +} + +struct module module_entry = { + .node = { NULL, NULL, NULL }, + .name = NULL, + .version = "$Revision$", + .handle = NULL, + .modinit = module_init, + .modexit = module_exit, + .flags = 0 +}; diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..2f51356 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,62 @@ +AUTOMAKE_OPTIONS = foreign + +sbin_PROGRAMS = ircd + +AM_YFLAGS = -d + +AM_CPPFLAGS = $(LTDLINCL) -I$(top_srcdir)/include +ircd_LDFLAGS = -export-dynamic +ircd_LDADD = $(LIBLTDL) +ircd_DEPENDENCIES = $(LTDLDEPS) + +ircd_SOURCES = balloc.c \ + channel.c \ + channel_mode.c \ + client.c \ + conf.c \ + conf_parser.y \ + conf_lexer.l \ + csvlib.c \ + dbuf.c \ + event.c \ + fdlist.c \ + getopt.c \ + hash.c \ + hook.c \ + hostmask.c \ + irc_res.c \ + irc_reslib.c \ + irc_string.c \ + ircd.c \ + ircd_signal.c \ + list.c \ + listener.c \ + log.c \ + match.c \ + memory.c \ + modules.c \ + motd.c \ + rng_mt.c \ + numeric.c \ + packet.c \ + parse.c \ + s_bsd_epoll.c \ + s_bsd_poll.c \ + s_bsd_sigio.c \ + s_bsd_devpoll.c \ + s_bsd_kqueue.c \ + s_bsd_select.c \ + restart.c \ + resv.c \ + rsa.c \ + s_auth.c \ + s_bsd.c \ + s_gline.c \ + s_misc.c \ + s_serv.c \ + s_user.c \ + send.c \ + sprintf_irc.c \ + version.c \ + watch.c \ + whowas.c diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..a8102c7 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,728 @@ +# Makefile.in generated by automake 1.12.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +sbin_PROGRAMS = ircd$(EXEEXT) +subdir = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/depcomp $(top_srcdir)/ylwrap conf_lexer.c \ + conf_parser.c conf_parser.h +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(sbindir)" +PROGRAMS = $(sbin_PROGRAMS) +am_ircd_OBJECTS = balloc.$(OBJEXT) channel.$(OBJEXT) \ + channel_mode.$(OBJEXT) client.$(OBJEXT) conf.$(OBJEXT) \ + conf_parser.$(OBJEXT) conf_lexer.$(OBJEXT) csvlib.$(OBJEXT) \ + dbuf.$(OBJEXT) event.$(OBJEXT) fdlist.$(OBJEXT) \ + getopt.$(OBJEXT) hash.$(OBJEXT) hook.$(OBJEXT) \ + hostmask.$(OBJEXT) irc_res.$(OBJEXT) irc_reslib.$(OBJEXT) \ + irc_string.$(OBJEXT) ircd.$(OBJEXT) ircd_signal.$(OBJEXT) \ + list.$(OBJEXT) listener.$(OBJEXT) log.$(OBJEXT) \ + match.$(OBJEXT) memory.$(OBJEXT) modules.$(OBJEXT) \ + motd.$(OBJEXT) rng_mt.$(OBJEXT) numeric.$(OBJEXT) \ + packet.$(OBJEXT) parse.$(OBJEXT) s_bsd_epoll.$(OBJEXT) \ + s_bsd_poll.$(OBJEXT) s_bsd_sigio.$(OBJEXT) \ + s_bsd_devpoll.$(OBJEXT) s_bsd_kqueue.$(OBJEXT) \ + s_bsd_select.$(OBJEXT) restart.$(OBJEXT) resv.$(OBJEXT) \ + rsa.$(OBJEXT) s_auth.$(OBJEXT) s_bsd.$(OBJEXT) \ + s_gline.$(OBJEXT) s_misc.$(OBJEXT) s_serv.$(OBJEXT) \ + s_user.$(OBJEXT) send.$(OBJEXT) sprintf_irc.$(OBJEXT) \ + version.$(OBJEXT) watch.$(OBJEXT) whowas.$(OBJEXT) +ircd_OBJECTS = $(am_ircd_OBJECTS) +am__DEPENDENCIES_1 = +ircd_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(ircd_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MAINTAINER_MODE_FALSE@am__skiplex = test -f $@ || +LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) +LTLEXCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS) +YLWRAP = $(top_srcdir)/ylwrap +@MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ || +am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ + -e s/c++$$/h++/ -e s/c$$/h/ +YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) +LTYACCCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) +SOURCES = $(ircd_SOURCES) +DIST_SOURCES = $(ircd_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBDIR = @LIBDIR@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PREFIX = @PREFIX@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +AM_YFLAGS = -d +AM_CPPFLAGS = $(LTDLINCL) -I$(top_srcdir)/include +ircd_LDFLAGS = -export-dynamic +ircd_LDADD = $(LIBLTDL) +ircd_DEPENDENCIES = $(LTDLDEPS) +ircd_SOURCES = balloc.c \ + channel.c \ + channel_mode.c \ + client.c \ + conf.c \ + conf_parser.y \ + conf_lexer.l \ + csvlib.c \ + dbuf.c \ + event.c \ + fdlist.c \ + getopt.c \ + hash.c \ + hook.c \ + hostmask.c \ + irc_res.c \ + irc_reslib.c \ + irc_string.c \ + ircd.c \ + ircd_signal.c \ + list.c \ + listener.c \ + log.c \ + match.c \ + memory.c \ + modules.c \ + motd.c \ + rng_mt.c \ + numeric.c \ + packet.c \ + parse.c \ + s_bsd_epoll.c \ + s_bsd_poll.c \ + s_bsd_sigio.c \ + s_bsd_devpoll.c \ + s_bsd_kqueue.c \ + s_bsd_select.c \ + restart.c \ + resv.c \ + rsa.c \ + s_auth.c \ + s_bsd.c \ + s_gline.c \ + s_misc.c \ + s_serv.c \ + s_user.c \ + send.c \ + sprintf_irc.c \ + version.c \ + watch.c \ + whowas.c + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .l .lo .o .obj .y +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sbindir)" && rm -f $$files + +clean-sbinPROGRAMS: + @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +conf_parser.h: conf_parser.c + @if test ! -f $@; then rm -f conf_parser.c; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) conf_parser.c; else :; fi +ircd$(EXEEXT): $(ircd_OBJECTS) $(ircd_DEPENDENCIES) $(EXTRA_ircd_DEPENDENCIES) + @rm -f ircd$(EXEEXT) + $(ircd_LINK) $(ircd_OBJECTS) $(ircd_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/balloc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel_mode.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf_lexer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf_parser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csvlib.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdlist.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hook.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hostmask.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc_res.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc_reslib.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc_string.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ircd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ircd_signal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/listener.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/match.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modules.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/motd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/numeric.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/restart.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rng_mt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_auth.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_bsd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_bsd_devpoll.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_bsd_epoll.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_bsd_kqueue.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_bsd_poll.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_bsd_select.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_bsd_sigio.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_gline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_misc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_serv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_user.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/send.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sprintf_irc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/watch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/whowas.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +.l.c: + $(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) + +.y.c: + $(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscopelist: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(sbindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -rm -f conf_lexer.c + -rm -f conf_parser.c + -rm -f conf_parser.h +clean: clean-am + +clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-sbinPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-sbinPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-sbinPROGRAMS cscopelist ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-sbinPROGRAMS install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-sbinPROGRAMS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/balloc.c b/src/balloc.c new file mode 100644 index 0000000..c2c0733 --- /dev/null +++ b/src/balloc.c @@ -0,0 +1,503 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * Original credit lines follow: + * + * File: balloc.c + * Owner: Wohali (Joan Touzet) + * + * Modified 2001/11/29 for mmap() support by Aaron Sethman <androsyn@ratbox.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +/*! \file balloc.c + * \brief A block allocator + * \version $Id$ + * + * About the block allocator + * + * Basically we have three ways of getting memory off of the operating + * system. Below are this list of methods and the order of preference. + * + * 1. mmap() anonymous pages with the MMAP_ANON flag.\n + * 2. mmap() via the /dev/zero trick.\n + * 3. malloc()\n + * + * The advantages of 1 and 2 are this. We can munmap() the pages which will + * return the pages back to the operating system, thus reducing the size + * of the process as the memory is unused. malloc() on many systems just keeps + * a heap of memory to itself, which never gets given back to the OS, except on + * exit. This of course is bad, if say we have an event that causes us to allocate + * say, 200MB of memory, while our normal memory consumption would be 15MB. In the + * malloc() case, the amount of memory allocated to our process never goes down, as + * malloc() has it locked up in its heap. With the mmap() method, we can munmap() + * the block and return it back to the OS, thus causing our memory consumption to go + * down after we no longer need it. + */ + + +#include "stdinc.h" +#ifdef HAVE_MMAP /* We've got mmap() that is good */ +#include <sys/mman.h> + +/* HP-UX sucks */ +#ifdef MAP_ANONYMOUS +#ifndef MAP_ANON +#define MAP_ANON MAP_ANONYMOUS +#endif +#endif /* MAP_ANONYMOUS */ +#endif + +#include "list.h" +#include "balloc.h" +#include "memory.h" +#include "irc_string.h" +#include "client.h" +#include "send.h" +#include "numeric.h" +#include "fdlist.h" +#include "event.h" + + +static BlockHeap *heap_list = NULL; + +static int BlockHeapGarbageCollect(BlockHeap *); +static void heap_garbage_collection(void *); + +/*! \brief Returns memory for the block back to either the malloc heap + * in case of !HAVE_MMAP, or back to the OS otherwise. + * \param ptr Pointer to memory to be freed + * \param size The size of the memory space + */ +static void +free_block(void *ptr, size_t size) +{ +#ifdef HAVE_MMAP + munmap(ptr, size); +#else + free(ptr); +#endif +} + +#ifdef HAVE_MMAP +#ifndef MAP_ANON /* But we cannot mmap() anonymous pages */ + /* So we mmap() /dev/zero, which is just as good */ +static fde_t dpfd; +#endif +#endif + +/*! \brief Opens /dev/zero and saves the file handle for + * future allocations. + */ +void +initBlockHeap(void) +{ +#ifdef HAVE_MMAP +#ifndef MAP_ANON + int zero_fd = open("/dev/zero", O_RDWR); + + if (zero_fd < 0) + outofmemory(); + fd_open(&dpfd, zero_fd, 0, "Anonymous mmap()"); +#endif + eventAdd("heap_garbage_collection", &heap_garbage_collection, NULL, 119); +#endif +} + +/*! + * \param size Size of block to allocate + * \return Address pointer to allocated data space + */ +static void * +get_block(size_t size) +{ +#ifdef HAVE_MMAP + void *ptr = NULL; + +#ifndef MAP_ANON + ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dpfd.fd, 0); +#else + ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); +#endif + return ptr == MAP_FAILED ? NULL : ptr; +#else + return malloc(size); +#endif +} + +static void +heap_garbage_collection(void *arg) +{ + BlockHeap *bh; + + for (bh = heap_list; bh != NULL; bh = bh->next) + BlockHeapGarbageCollect(bh); +} + +/*! \brief Allocates a new block for addition to a blockheap + * \param bh Pointer to parent blockheap + * \return 0 if successful, 1 if not + */ +static int +newblock(BlockHeap *bh) +{ + MemBlock *newblk = NULL; + Block *b = NULL; + int i = 0; + void *offset = NULL; + + /* Setup the initial data structure. */ + if ((b = calloc(1, sizeof(Block))) == NULL) + return 1; + + b->freeElems = bh->elemsPerBlock; + b->next = bh->base; + b->alloc_size = bh->elemsPerBlock * (bh->elemSize + sizeof(MemBlock)); + b->elems = get_block(b->alloc_size); + + if (b->elems == NULL) + return 1; + + offset = b->elems; + + /* Setup our blocks now */ + for (; i < bh->elemsPerBlock; ++i) + { + void *data; + + newblk = offset; + newblk->block = b; + data = (void *)((size_t)offset + sizeof(MemBlock)); + + dlinkAdd(data, &newblk->self, &b->free_list); + offset = (void *)((size_t)offset + bh->elemSize + sizeof(MemBlock)); + } + + ++bh->blocksAllocated; + bh->freeElems += bh->elemsPerBlock; + bh->base = b; + + return 0; +} + +/*! \brief Creates a new blockheap + * + * Creates a new blockheap from which smaller blocks can be allocated. + * Intended to be used instead of multiple calls to malloc() when + * performance is an issue. + * + * \param name Name of the blockheap + * \param elemsize Size of the basic element to be stored + * \param elemsperblock Number of elements to be stored in a single block of + * memory. When the blockheap runs out of free memory, + * it will allocate elemsize * elemsperblock more. + * \return Pointer to new BlockHeap, or NULL if unsuccessful + */ +BlockHeap * +BlockHeapCreate(const char *const name, size_t elemsize, int elemsperblock) +{ + BlockHeap *bh = NULL; + assert(elemsize > 0 && elemsperblock > 0); + + /* Catch idiotic requests up front */ + if ((elemsize <= 0) || (elemsperblock <= 0)) + outofmemory(); /* die.. out of memory */ + + /* Allocate our new BlockHeap */ + if ((bh = calloc(1, sizeof(BlockHeap))) == NULL) + outofmemory(); /* die.. out of memory */ + + if ((elemsize % sizeof(void *)) != 0) + { + /* Pad to even pointer boundary */ + elemsize += sizeof(void *); + elemsize &= ~(sizeof(void *) - 1); + } + + bh->name = name; + bh->elemSize = elemsize; + bh->elemsPerBlock = elemsperblock; + + /* Be sure our malloc was successful */ + if (newblock(bh)) + { + if (bh != NULL) + free(bh); + + outofmemory(); /* die.. out of memory */ + } + + bh->next = heap_list; + heap_list = bh; + + return bh; +} + +/*! \brief Returns a pointer to a struct within our BlockHeap that's free for + * the taking. + * \param bh Pointer to the Blockheap + * \return Address pointer to allocated data space, or NULL if unsuccessful + */ +void * +BlockHeapAlloc(BlockHeap *bh) +{ + Block *walker = NULL; + dlink_node *new_node = NULL; + + assert(bh != NULL); + + if (bh->freeElems == 0) + { + /* Allocate new block and assign */ + /* newblock returns 1 if unsuccessful, 0 if not */ + if (newblock(bh)) + { + /* That didn't work..try to garbage collect */ + BlockHeapGarbageCollect(bh); + + if (newblock(bh)) + outofmemory(); /* Well that didn't work either...bail */ + } + } + + for (walker = bh->base; walker != NULL; walker = walker->next) + { + if (walker->freeElems > 0) + { + --bh->freeElems; + --walker->freeElems; + new_node = walker->free_list.head; + + dlinkDelete(new_node, &walker->free_list); + assert(new_node->data != NULL); + + memset(new_node->data, 0, bh->elemSize); + return new_node->data; + } + } + + assert(0 == 1); + outofmemory(); + return NULL; +} + +/*! \brief Returns an element to the free pool, does not free() + * \param bh Pointer to BlockHeap containing element + * \param ptr Pointer to element to be "freed" + * \return 0 if successful, 1 if element not contained within BlockHeap + */ +int +BlockHeapFree(BlockHeap *bh, void *ptr) +{ + Block *block = NULL; + struct MemBlock *memblock = NULL; + + assert(bh != NULL); + assert(ptr != NULL); + + memblock = (void *)((size_t)ptr - sizeof(MemBlock)); + assert(memblock->block != NULL); + + if (memblock->block == NULL) + outofmemory(); + + block = memblock->block; + ++bh->freeElems; + ++block->freeElems; + mem_frob(ptr, bh->elemSize); + + dlinkAdd(ptr, &memblock->self, &block->free_list); + return 0; +} + +/*! \brief Performs garbage collection on the block heap. + * + * Performs garbage collection on the block heap. Any blocks that are + * completely unallocated are removed from the heap. Garbage collection + * will \b never remove the root node of the heap. + * + * \param bh Pointer to the BlockHeap to be cleaned up + * \return 0 if successful, 1 if bh == NULL + */ +static int +BlockHeapGarbageCollect(BlockHeap *bh) +{ + Block *walker = NULL, *last = NULL; + + assert(bh != NULL); + + if (bh->freeElems < bh->elemsPerBlock || bh->blocksAllocated == 1) + { + /* There couldn't possibly be an entire free block. Return. */ + return 0; + } + + walker = bh->base; + + while (walker != NULL) + { + if (walker->freeElems == bh->elemsPerBlock) + { + free_block(walker->elems, walker->alloc_size); + + if (last != NULL) + { + last->next = walker->next; + + if (walker != NULL) + free(walker); + walker = last->next; + } + else + { + bh->base = walker->next; + + if (walker != NULL) + free(walker); + walker = bh->base; + } + + --bh->blocksAllocated; + bh->freeElems -= bh->elemsPerBlock; + } + else + { + last = walker; + walker = walker->next; + } + } + + return 0; +} + +/*! \brief Completely free()s a BlockHeap. Use for cleanup. + * \param bh Pointer to the BlockHeap to be destroyed + * \return 0 if successful, 1 if bh == NULL + */ +int +BlockHeapDestroy(BlockHeap *bh) +{ + Block *walker = NULL, *next = NULL; + + if (bh == NULL) + return 1; + + for (walker = bh->base; walker != NULL; walker = next) + { + next = walker->next; + free_block(walker->elems, walker->alloc_size); + + if (walker != NULL) + free(walker); + } + + if (heap_list == bh) + heap_list = bh->next; + else { + BlockHeap *prev; + + for (prev = heap_list; prev->next != bh; prev = prev->next) + /* nothing */ ; + prev->next = bh->next; + } + + free(bh); + return 0; +} + +/*! \brief Returns the number of bytes being used + * \param bh Pointer to a BlockHeap + * \return Number of bytes being used + */ +static size_t +block_heap_get_used_mem(const BlockHeap *const bh) +{ + return(((bh->blocksAllocated * + bh->elemsPerBlock)-bh->freeElems) * + (bh->elemSize + sizeof(MemBlock))); +} + +/*! \brief Returns the number of bytes being free for further allocations + * \param bh Pointer to a BlockHeap + * \return Number of bytes being free for further allocations + */ +static size_t +block_heap_get_free_mem(const BlockHeap *const bh) +{ + return(bh->freeElems * (bh->elemSize + sizeof(MemBlock))); +} + +/*! \brief Returns the total number of bytes of memory belonging to a heap + * \param bh Pointer to a BlockHeap + * \return Total number of bytes of memory belonging to a heap + */ +static size_t +block_heap_get_size_mem(const BlockHeap *const bh) +{ + return(((bh->blocksAllocated * + bh->elemsPerBlock)) * + (bh->elemSize + sizeof(MemBlock))); +} + +/*! \brief Returns the number of elements being used. + * \param bh Pointer to a BlockHeap + * \return Number of elements being free for further allocations + */ +static unsigned int +block_heap_get_used_elm(const BlockHeap *const bh) +{ + return((bh->blocksAllocated * + bh->elemsPerBlock)-bh->freeElems); +} + +/*! \brief Returns the number of elements being free for further allocations. + * \param bh Pointer to a BlockHeap + * \return Number of elements being free for further allocations + */ +static unsigned int +block_heap_get_free_elm(const BlockHeap *const bh) +{ + return(bh->freeElems); +} + +/*! \brief Returns the number of total elements belonging to a heap. + * Includes \b free and \b used elements. + * \param bh Pointer to a BlockHeap + * \return Number of total elements belonging to a heap + */ +static unsigned int +block_heap_get_size_elm(const BlockHeap *const bh) +{ + return(bh->blocksAllocated * bh->elemsPerBlock); +} + +void +block_heap_report_stats(struct Client *client_p) +{ + const BlockHeap *bh = NULL; + + for (bh = heap_list; bh != NULL; bh = bh->next) + sendto_one(client_p, ":%s %d %s z :%s mempool: used %u/%u free %u/%u (size %u/%u)", + me.name, RPL_STATSDEBUG, client_p->name, bh->name, + block_heap_get_used_elm(bh), + block_heap_get_used_mem(bh), + block_heap_get_free_elm(bh), + block_heap_get_free_mem(bh), + block_heap_get_size_elm(bh), + block_heap_get_size_mem(bh)); +} diff --git a/src/channel.c b/src/channel.c new file mode 100644 index 0000000..14e6a14 --- /dev/null +++ b/src/channel.c @@ -0,0 +1,864 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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 + */ + +/*! \file channel.c + * \brief Responsible for managing channels, members, bans and topics + * \version $Id$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "hash.h" +#include "hostmask.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "s_serv.h" /* captab */ +#include "s_user.h" +#include "send.h" +#include "conf.h" /* ConfigFileEntry, ConfigChannel */ +#include "event.h" +#include "memory.h" +#include "balloc.h" + +struct config_channel_entry ConfigChannel; +dlink_list global_channel_list = { NULL, NULL, 0 }; +BlockHeap *ban_heap; /*! \todo ban_heap shouldn't be a global var */ + +static BlockHeap *member_heap = NULL; +static BlockHeap *channel_heap = NULL; + +static char buf[IRCD_BUFSIZE]; +static char modebuf[MODEBUFLEN]; +static char parabuf[MODEBUFLEN]; + + +/*! \brief Initializes the channel blockheap, adds known channel CAPAB + */ +void +init_channels(void) +{ + add_capability("EX", CAP_EX, 1); + add_capability("IE", CAP_IE, 1); + add_capability("CHW", CAP_CHW, 1); + + channel_heap = BlockHeapCreate("channel", sizeof(struct Channel), CHANNEL_HEAP_SIZE); + ban_heap = BlockHeapCreate("ban", sizeof(struct Ban), BAN_HEAP_SIZE); + member_heap = BlockHeapCreate("member", sizeof(struct Membership), CHANNEL_HEAP_SIZE*2); +} + +/*! \brief adds a user to a channel by adding another link to the + * channels member chain. + * \param chptr pointer to channel to add client to + * \param who pointer to client (who) to add + * \param flags flags for chanops etc + * \param flood_ctrl whether to count this join in flood calculations + */ +void +add_user_to_channel(struct Channel *chptr, struct Client *who, + unsigned int flags, int flood_ctrl) +{ + struct Membership *ms = NULL; + + if (GlobalSetOptions.joinfloodtime > 0) + { + if (flood_ctrl) + chptr->number_joined++; + + chptr->number_joined -= (CurrentTime - chptr->last_join_time) * + (((float)GlobalSetOptions.joinfloodcount) / + (float)GlobalSetOptions.joinfloodtime); + + if (chptr->number_joined <= 0) + { + chptr->number_joined = 0; + ClearJoinFloodNoticed(chptr); + } + else if (chptr->number_joined >= GlobalSetOptions.joinfloodcount) + { + chptr->number_joined = GlobalSetOptions.joinfloodcount; + + if (!IsSetJoinFloodNoticed(chptr)) + { + SetJoinFloodNoticed(chptr); + sendto_realops_flags(UMODE_BOTS, L_ALL, + "Possible Join Flooder %s on %s target: %s", + get_client_name(who, HIDE_IP), + who->servptr->name, chptr->chname); + } + } + + chptr->last_join_time = CurrentTime; + } + + ms = BlockHeapAlloc(member_heap); + ms->client_p = who; + ms->chptr = chptr; + ms->flags = flags; + + dlinkAdd(ms, &ms->channode, &chptr->members); + dlinkAdd(ms, &ms->usernode, &who->channel); +} + +/*! \brief deletes an user from a channel by removing a link in the + * channels member chain. + * \param member pointer to Membership struct + */ +void +remove_user_from_channel(struct Membership *member) +{ + struct Client *client_p = member->client_p; + struct Channel *chptr = member->chptr; + + dlinkDelete(&member->channode, &chptr->members); + dlinkDelete(&member->usernode, &client_p->channel); + + BlockHeapFree(member_heap, member); + + if (chptr->members.head == NULL) + destroy_channel(chptr); +} + +/* send_members() + * + * inputs - + * output - NONE + * side effects - + */ +static void +send_members(struct Client *client_p, struct Channel *chptr, + char *lmodebuf, char *lparabuf) +{ + struct Membership *ms; + dlink_node *ptr; + int tlen; /* length of text to append */ + char *t, *start; /* temp char pointer */ + + start = t = buf + ircsprintf(buf, ":%s SJOIN %lu %s %s %s:", + ID_or_name(&me, client_p), + (unsigned long)chptr->channelts, + chptr->chname, lmodebuf, lparabuf); + + DLINK_FOREACH(ptr, chptr->members.head) + { + ms = ptr->data; + + tlen = strlen(IsCapable(client_p, CAP_TS6) ? + ID(ms->client_p) : ms->client_p->name) + 1; /* nick + space */ + + if (ms->flags & CHFL_CHANOP) + tlen++; +#ifdef HALFOPS + else if (ms->flags & CHFL_HALFOP) + tlen++; +#endif + if (ms->flags & CHFL_VOICE) + tlen++; + + /* space will be converted into CR, but we also need space for LF.. + * That's why we use '- 1' here + * -adx */ + if (t + tlen - buf > IRCD_BUFSIZE - 1) + { + *(t - 1) = '\0'; /* kill the space and terminate the string */ + sendto_one(client_p, "%s", buf); + t = start; + } + + if ((ms->flags & (CHFL_CHANOP | CHFL_HALFOP))) + *t++ = (!(ms->flags & CHFL_CHANOP) && IsCapable(client_p, CAP_HOPS)) ? + '%' : '@'; + if ((ms->flags & CHFL_VOICE)) + *t++ = '+'; + + if (IsCapable(client_p, CAP_TS6)) + strcpy(t, ID(ms->client_p)); + else + strcpy(t, ms->client_p->name); + t += strlen(t); + *t++ = ' '; + } + + /* should always be non-NULL unless we have a kind of persistent channels */ + if (chptr->members.head != NULL) + t--; /* take the space out */ + *t = '\0'; + sendto_one(client_p, "%s", buf); +} + +/*! \brief sends +b/+e/+I + * \param client_p client pointer to server + * \param chptr pointer to channel + * \param top pointer to top of mode link list to send + * \param flag char flag flagging type of mode. Currently this can be 'b', e' or 'I' + */ +static void +send_mode_list(struct Client *client_p, struct Channel *chptr, + dlink_list *top, char flag) +{ + int ts5 = !IsCapable(client_p, CAP_TS6); + dlink_node *lp; + struct Ban *banptr; + char pbuf[IRCD_BUFSIZE]; + int tlen, mlen, cur_len, count = 0; + char *mp = NULL, *pp = pbuf; + + if (top == NULL || top->length == 0) + return; + + if (ts5) + mlen = ircsprintf(buf, ":%s MODE %s +", me.name, chptr->chname); + else + mlen = ircsprintf(buf, ":%s BMASK %lu %s %c :", me.id, + (unsigned long)chptr->channelts, chptr->chname, flag); + + /* MODE needs additional one byte for space between buf and pbuf */ + cur_len = mlen + ts5; + mp = buf + mlen; + + DLINK_FOREACH(lp, top->head) + { + banptr = lp->data; + + /* must add another b/e/I letter if we use MODE */ + tlen = banptr->len + 3 + ts5; + + /* + * send buffer and start over if we cannot fit another ban, + * or if the target is non-ts6 and we have too many modes in + * in this line. + */ + if (cur_len + (tlen - 1) > IRCD_BUFSIZE - 2 || + (!IsCapable(client_p, CAP_TS6) && + (count >= MAXMODEPARAMS || pp - pbuf >= MODEBUFLEN))) + { + *(pp - 1) = '\0'; /* get rid of trailing space on buffer */ + sendto_one(client_p, "%s%s%s", buf, ts5 ? " " : "", pbuf); + + cur_len = mlen + ts5; + mp = buf + mlen; + pp = pbuf; + count = 0; + } + + count++; + if (ts5) + { + *mp++ = flag; + *mp = '\0'; + } + + pp += ircsprintf(pp, "%s!%s@%s ", banptr->name, banptr->username, + banptr->host); + cur_len += tlen; + } + + *(pp - 1) = '\0'; /* get rid of trailing space on buffer */ + sendto_one(client_p, "%s%s%s", buf, ts5 ? " " : "", pbuf); +} + +/*! \brief send "client_p" a full list of the modes for channel chptr + * \param client_p pointer to client client_p + * \param chptr pointer to channel pointer + */ +void +send_channel_modes(struct Client *client_p, struct Channel *chptr) +{ + *modebuf = *parabuf = '\0'; + channel_modes(chptr, client_p, modebuf, parabuf); + send_members(client_p, chptr, modebuf, parabuf); + + send_mode_list(client_p, chptr, &chptr->banlist, 'b'); + + if (IsCapable(client_p, CAP_EX)) + send_mode_list(client_p, chptr, &chptr->exceptlist, 'e'); + if (IsCapable(client_p, CAP_IE)) + send_mode_list(client_p, chptr, &chptr->invexlist, 'I'); +} + +/*! \brief check channel name for invalid characters + * \param name pointer to channel name string + * \param local indicates whether it's a local or remote creation + * \return 0 if invalid, 1 otherwise + */ +int +check_channel_name(const char *name, int local) +{ + const char *p = name; + const int max_length = local ? LOCAL_CHANNELLEN : CHANNELLEN; + assert(name != NULL); + + if (!IsChanPrefix(*p)) + return 0; + + if (!local || !ConfigChannel.disable_fake_channels) + { + while (*++p) + if (!IsChanChar(*p)) + return 0; + } + else + { + while (*++p) + if (!IsVisibleChanChar(*p)) + return 0; + } + + return p - name <= max_length; +} + +void +remove_ban(struct Ban *bptr, dlink_list *list) +{ + dlinkDelete(&bptr->node, list); + + MyFree(bptr->name); + MyFree(bptr->username); + MyFree(bptr->host); + MyFree(bptr->who); + + BlockHeapFree(ban_heap, bptr); +} + +/* free_channel_list() + * + * inputs - pointer to dlink_list + * output - NONE + * side effects - + */ +void +free_channel_list(dlink_list *list) +{ + dlink_node *ptr = NULL, *next_ptr = NULL; + + DLINK_FOREACH_SAFE(ptr, next_ptr, list->head) + remove_ban(ptr->data, list); + + assert(list->tail == NULL && list->head == NULL); +} + +/*! \brief Get Channel block for chname (and allocate a new channel + * block, if it didn't exist before) + * \param chname channel name + * \return channel block + */ +struct Channel * +make_channel(const char *chname) +{ + struct Channel *chptr = NULL; + + assert(!EmptyString(chname)); + + chptr = BlockHeapAlloc(channel_heap); + + /* doesn't hurt to set it here */ + chptr->channelts = CurrentTime; + chptr->last_join_time = CurrentTime; + + strlcpy(chptr->chname, chname, sizeof(chptr->chname)); + dlinkAdd(chptr, &chptr->node, &global_channel_list); + + hash_add_channel(chptr); + + return chptr; +} + +/*! \brief walk through this channel, and destroy it. + * \param chptr channel pointer + */ +void +destroy_channel(struct Channel *chptr) +{ + dlink_node *ptr = NULL, *ptr_next = NULL; + + DLINK_FOREACH_SAFE(ptr, ptr_next, chptr->invites.head) + del_invite(chptr, ptr->data); + + /* free ban/exception/invex lists */ + free_channel_list(&chptr->banlist); + free_channel_list(&chptr->exceptlist); + free_channel_list(&chptr->invexlist); + + dlinkDelete(&chptr->node, &global_channel_list); + hash_del_channel(chptr); + + BlockHeapFree(channel_heap, chptr); +} + +/*! + * \param chptr pointer to channel + * \return string pointer "=" if public, "@" if secret else "*" + */ +static const char * +channel_pub_or_secret(const struct Channel *chptr) +{ + if (SecretChannel(chptr)) + return "@"; + if (PrivateChannel(chptr)) + return "*"; + return "="; +} + +/*! \brief lists all names on given channel + * \param source_p pointer to client struct requesting names + * \param chptr pointer to channel block + * \param show_eon show ENDOFNAMES numeric or not + * (don't want it with /names with no params) + */ +void +channel_member_names(struct Client *source_p, struct Channel *chptr, + int show_eon) +{ + struct Client *target_p = NULL; + struct Membership *ms = NULL; + dlink_node *ptr = NULL; + char lbuf[IRCD_BUFSIZE + 1]; + char *t = NULL, *start = NULL; + int tlen = 0; + int is_member = IsMember(source_p, chptr); + int multi_prefix = HasCap(source_p, CAP_MULTI_PREFIX) != 0; + + if (PubChannel(chptr) || is_member) + { + t = lbuf + ircsprintf(lbuf, form_str(RPL_NAMREPLY), + me.name, source_p->name, + channel_pub_or_secret(chptr), + chptr->chname); + start = t; + + DLINK_FOREACH(ptr, chptr->members.head) + { + ms = ptr->data; + target_p = ms->client_p; + + if (HasUMode(target_p, UMODE_INVISIBLE) && !is_member) + continue; + + tlen = strlen(target_p->name) + 1; /* nick + space */ + + if (!multi_prefix) + { + if (ms->flags & (CHFL_CHANOP | CHFL_HALFOP | CHFL_VOICE)) + ++tlen; + } + else + { + if (ms->flags & CHFL_CHANOP) + ++tlen; + if (ms->flags & CHFL_HALFOP) + ++tlen; + if (ms->flags & CHFL_VOICE) + ++tlen; + } + + if (t + tlen - lbuf > IRCD_BUFSIZE - 2) + { + *(t - 1) = '\0'; + sendto_one(source_p, "%s", lbuf); + t = start; + } + + t += ircsprintf(t, "%s%s ", get_member_status(ms, multi_prefix), + target_p->name); + } + + if (tlen != 0) + { + *(t - 1) = '\0'; + sendto_one(source_p, "%s", lbuf); + } + } + + if (show_eon) + sendto_one(source_p, form_str(RPL_ENDOFNAMES), + me.name, source_p->name, chptr->chname); +} + +/*! \brief adds client to invite list + * \param chptr pointer to channel block + * \param who pointer to client to add invite to + */ +void +add_invite(struct Channel *chptr, struct Client *who) +{ + del_invite(chptr, who); + + /* + * delete last link in chain if the list is max length + */ + if (dlink_list_length(&who->localClient->invited) >= + ConfigChannel.max_chans_per_user) + del_invite(who->localClient->invited.tail->data, who); + + /* add client to channel invite list */ + dlinkAdd(who, make_dlink_node(), &chptr->invites); + + /* add channel to the end of the client invite list */ + dlinkAdd(chptr, make_dlink_node(), &who->localClient->invited); +} + +/*! \brief Delete Invite block from channel invite list + * and client invite list + * \param chptr pointer to Channel struct + * \param who pointer to client to remove invites from + */ +void +del_invite(struct Channel *chptr, struct Client *who) +{ + dlink_node *ptr = NULL; + + if ((ptr = dlinkFindDelete(&who->localClient->invited, chptr))) + free_dlink_node(ptr); + + if ((ptr = dlinkFindDelete(&chptr->invites, who))) + free_dlink_node(ptr); +} + +/* get_member_status() + * + * inputs - pointer to struct Membership + * - YES if we can combine different flags + * output - string either @, +, % or "" depending on whether + * chanop, voiced or user + * side effects - + * + * NOTE: Returned string is usually a static buffer + * (like in get_client_name) + */ +const char * +get_member_status(const struct Membership *ms, int combine) +{ + static char buffer[4]; + char *p = NULL; + + if (ms == NULL) + return ""; + p = buffer; + + if (ms->flags & CHFL_CHANOP) + { + if (!combine) + return "@"; + *p++ = '@'; + } + +#ifdef HALFOPS + if (ms->flags & CHFL_HALFOP) + { + if (!combine) + return "%"; + *p++ = '%'; + } +#endif + + if (ms->flags & CHFL_VOICE) + *p++ = '+'; + *p = '\0'; + + return buffer; +} + +/*! + * \param who pointer to Client to check + * \param list pointer to ban list to search + * \return 1 if ban found for given n!u\@h mask, 0 otherwise + * + */ +static int +find_bmask(const struct Client *who, const dlink_list *const list) +{ + const dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, list->head) + { + const struct Ban *bp = ptr->data; + + if (match(bp->name, who->name) && match(bp->username, who->username)) + { + switch (bp->type) + { + case HM_HOST: + if (match(bp->host, who->host) || match(bp->host, who->sockhost)) + return 1; + break; + case HM_IPV4: + if (who->localClient->aftype == AF_INET) + if (match_ipv4(&who->localClient->ip, &bp->addr, bp->bits)) + return 1; + break; +#ifdef IPV6 + case HM_IPV6: + if (who->localClient->aftype == AF_INET6) + if (match_ipv6(&who->localClient->ip, &bp->addr, bp->bits)) + return 1; + break; +#endif + default: + assert(0); + } + } + } + + return 0; +} + +/*! + * \param chptr pointer to channel block + * \param who pointer to client to check access fo + * \return 0 if not banned, 1 otherwise + */ +int +is_banned(const struct Channel *chptr, const struct Client *who) +{ + if (find_bmask(who, &chptr->banlist)) + if (!find_bmask(who, &chptr->exceptlist)) + return 1; + + return 0; +} + +/*! + * \param source_p pointer to client attempting to join + * \param chptr pointer to channel + * \param key key sent by client attempting to join if present + * \return ERR_BANNEDFROMCHAN, ERR_INVITEONLYCHAN, ERR_CHANNELISFULL + * or 0 if allowed to join. + */ +int +can_join(struct Client *source_p, struct Channel *chptr, const char *key) +{ + if (is_banned(chptr, source_p)) + return ERR_BANNEDFROMCHAN; + +#ifdef HAVE_LIBCRYPTO + if ((chptr->mode.mode & MODE_SSLONLY) && !source_p->localClient->fd.ssl) + return ERR_SSLONLYCHAN; +#endif + + if ((chptr->mode.mode & MODE_REGONLY) && !HasUMode(source_p, UMODE_REGISTERED)) + return ERR_NEEDREGGEDNICK; + + if ((chptr->mode.mode & MODE_OPERONLY) && !HasUMode(source_p, UMODE_OPER)) + return ERR_OPERONLYCHAN; + + if (chptr->mode.mode & MODE_INVITEONLY) + if (!dlinkFind(&source_p->localClient->invited, chptr)) + if (!find_bmask(source_p, &chptr->invexlist)) + return ERR_INVITEONLYCHAN; + + if (chptr->mode.key[0] && (!key || strcmp(chptr->mode.key, key))) + return ERR_BADCHANNELKEY; + + if (chptr->mode.limit && dlink_list_length(&chptr->members) >= + chptr->mode.limit) + return ERR_CHANNELISFULL; + + return 0; +} + +int +has_member_flags(struct Membership *ms, unsigned int flags) +{ + if (ms != NULL) + return ms->flags & flags; + return 0; +} + +struct Membership * +find_channel_link(struct Client *client_p, struct Channel *chptr) +{ + dlink_node *ptr = NULL; + + if (!IsClient(client_p)) + return NULL; + + DLINK_FOREACH(ptr, client_p->channel.head) + if (((struct Membership *)ptr->data)->chptr == chptr) + return ptr->data; + + return NULL; +} + +/*! + * \param chptr pointer to Channel struct + * \param source_p pointer to Client struct + * \param ms pointer to Membership struct (can be NULL) + * \return CAN_SEND_OPV if op or voiced on channel\n + * CAN_SEND_NONOP if can send to channel but is not an op\n + * ERR_CANNOTSENDTOCHAN or ERR_NEEDREGGEDNICK if they cannot send to channel\n + */ +int +can_send(struct Channel *chptr, struct Client *source_p, struct Membership *ms) +{ + if (IsServer(source_p) || HasFlag(source_p, FLAGS_SERVICE)) + return CAN_SEND_OPV; + + if (MyClient(source_p) && !IsExemptResv(source_p)) + if (!(HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.oper_pass_resv)) + if (!hash_find_resv(chptr->chname) == ConfigChannel.restrict_channels) + return ERR_CANNOTSENDTOCHAN; + + if (ms != NULL || (ms = find_channel_link(source_p, chptr))) + { + if (ms->flags & (CHFL_CHANOP|CHFL_HALFOP|CHFL_VOICE)) + return CAN_SEND_OPV; + + /* cache can send if quiet_on_ban and banned */ + if (ConfigChannel.quiet_on_ban && MyClient(source_p)) + { + if (ms->flags & CHFL_BAN_SILENCED) + return ERR_CANNOTSENDTOCHAN; + + if (!(ms->flags & CHFL_BAN_CHECKED)) + { + if (is_banned(chptr, source_p)) + { + ms->flags |= (CHFL_BAN_CHECKED|CHFL_BAN_SILENCED); + return ERR_CANNOTSENDTOCHAN; + } + + ms->flags |= CHFL_BAN_CHECKED; + } + } + } + else if (chptr->mode.mode & MODE_NOPRIVMSGS) + return ERR_CANNOTSENDTOCHAN; + + if (chptr->mode.mode & MODE_MODERATED) + return ERR_CANNOTSENDTOCHAN; + + return CAN_SEND_NONOP; +} + +/*! \brief Updates the client's oper_warn_count_down, warns the + * IRC operators if necessary, and updates + * join_leave_countdown as needed. + * \param source_p pointer to struct Client to check + * \param name channel name or NULL if this is a part. + */ +void +check_spambot_warning(struct Client *source_p, const char *name) +{ + int t_delta = 0; + int decrement_count = 0; + + if ((GlobalSetOptions.spam_num && + (source_p->localClient->join_leave_count >= + GlobalSetOptions.spam_num))) + { + if (source_p->localClient->oper_warn_count_down > 0) + source_p->localClient->oper_warn_count_down--; + else + source_p->localClient->oper_warn_count_down = 0; + + if (source_p->localClient->oper_warn_count_down == 0) + { + /* Its already known as a possible spambot */ + if (name != NULL) + sendto_realops_flags(UMODE_BOTS, L_ALL, + "User %s (%s@%s) trying to join %s is a possible spambot", + source_p->name, source_p->username, + source_p->host, name); + else + sendto_realops_flags(UMODE_BOTS, L_ALL, + "User %s (%s@%s) is a possible spambot", + source_p->name, source_p->username, + source_p->host); + source_p->localClient->oper_warn_count_down = OPER_SPAM_COUNTDOWN; + } + } + else + { + if ((t_delta = (CurrentTime - source_p->localClient->last_leave_time)) > + JOIN_LEAVE_COUNT_EXPIRE_TIME) + { + decrement_count = (t_delta / JOIN_LEAVE_COUNT_EXPIRE_TIME); + if (decrement_count > source_p->localClient->join_leave_count) + source_p->localClient->join_leave_count = 0; + else + source_p->localClient->join_leave_count -= decrement_count; + } + else + { + if ((CurrentTime - (source_p->localClient->last_join_time)) < + GlobalSetOptions.spam_time) + { + /* oh, its a possible spambot */ + source_p->localClient->join_leave_count++; + } + } + + if (name != NULL) + source_p->localClient->last_join_time = CurrentTime; + else + source_p->localClient->last_leave_time = CurrentTime; + } +} + +/*! \brief compares usercount and servercount against their split + * values and adjusts splitmode accordingly + * \param unused Unused address pointer + */ +void +check_splitmode(void *unused) +{ + if (splitchecking && (ConfigChannel.no_join_on_split || + ConfigChannel.no_create_on_split)) + { + const unsigned int server = dlink_list_length(&global_serv_list); + + if (!splitmode && ((server < split_servers) || (Count.total < split_users))) + { + splitmode = 1; + + sendto_realops_flags(UMODE_ALL,L_ALL, + "Network split, activating splitmode"); + eventAddIsh("check_splitmode", check_splitmode, NULL, 10); + } + else if (splitmode && (server > split_servers) && (Count.total > split_users)) + { + splitmode = 0; + + sendto_realops_flags(UMODE_ALL, L_ALL, + "Network rejoined, deactivating splitmode"); + eventDelete(check_splitmode, NULL); + } + } +} + +/*! \brief Sets the channel topic for chptr + * \param chptr Pointer to struct Channel + * \param topic The topic string + * \param topic_info n!u\@h formatted string of the topic setter + * \param topicts timestamp on the topic + */ +void +set_channel_topic(struct Channel *chptr, const char *topic, + const char *topic_info, time_t topicts) +{ + strlcpy(chptr->topic, topic, sizeof(chptr->topic)); + strlcpy(chptr->topic_info, topic_info, sizeof(chptr->topic_info)); + chptr->topic_time = topicts; +} diff --git a/src/channel_mode.c b/src/channel_mode.c new file mode 100644 index 0000000..4751ec4 --- /dev/null +++ b/src/channel_mode.c @@ -0,0 +1,1797 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * channel_mode.c: Controls modes on channels. + * + * Copyright (C) 2005 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "hash.h" +#include "hostmask.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "s_serv.h" /* captab */ +#include "s_user.h" +#include "send.h" +#include "whowas.h" +#include "conf.h" /* ConfigFileEntry, ConfigChannel */ +#include "event.h" +#include "memory.h" +#include "balloc.h" +#include "log.h" +#include "parse.h" + +/* some small utility functions */ +static char *check_string(char *); +static char *fix_key(char *); +static char *fix_key_old(char *); +static void chm_nosuch(struct Client *, struct Client *, + struct Channel *, int, int *, char **, int *, int, + int, char, void *, const char *); +static void chm_simple(struct Client *, struct Client *, struct Channel *, + int, int *, char **, int *, int, int, char, void *, + const char *); +static void chm_registered(struct Client *, struct Client *, struct Channel *, + int, int *, char **, int *, int, int, char, void *, + const char *); +static void chm_limit(struct Client *, struct Client *, struct Channel *, + int, int *, char **, int *, int, int, char, void *, + const char *); +static void chm_key(struct Client *, struct Client *, struct Channel *, + int, int *, char **, int *, int, int, char, void *, + const char *); +static void chm_op(struct Client *, struct Client *, struct Channel *, int, + int *, char **, int *, int, int, char, void *, + const char *); +#ifdef HALFOPS +static void chm_hop(struct Client *, struct Client *, struct Channel *, int, + int *, char **, int *, int, int, char, void *, + const char *); +#endif +static void chm_voice(struct Client *, struct Client *, struct Channel *, + int, int *, char **, int *, int, int, char, void *, + const char *); +static void chm_ban(struct Client *, struct Client *, struct Channel *, int, + int *, char **, int *, int, int, char, void *, + const char *); +static void chm_except(struct Client *, struct Client *, struct Channel *, + int, int *, char **, int *, int, int, char, void *, + const char *); +static void chm_invex(struct Client *, struct Client *, struct Channel *, + int, int *, char **, int *, int, int, char, void *, + const char *); +static void send_cap_mode_changes(struct Client *, struct Client *, + struct Channel *, unsigned int, unsigned int); +static void send_mode_changes(struct Client *, struct Client *, + struct Channel *, char *); + +/* 10 is a magic number in hybrid 6 NFI where it comes from -db */ +#define BAN_FUDGE 10 +#define NCHCAPS (sizeof(channel_capabs)/sizeof(int)) +#define NCHCAP_COMBOS (1 << NCHCAPS) + +static char nuh_mask[MAXPARA][IRCD_BUFSIZE]; +/* some buffers for rebuilding channel/nick lists with ,'s */ +static char modebuf[IRCD_BUFSIZE]; +static char parabuf[MODEBUFLEN]; +static struct ChModeChange mode_changes[IRCD_BUFSIZE]; +static int mode_count; +static int mode_limit; /* number of modes set other than simple */ +static int simple_modes_mask; /* bit mask of simple modes already set */ +#ifdef HALFOPS +static int channel_capabs[] = { CAP_EX, CAP_IE, CAP_TS6, CAP_HOPS }; +#else +static int channel_capabs[] = { CAP_EX, CAP_IE, CAP_TS6 }; +#endif +static struct ChCapCombo chcap_combos[NCHCAP_COMBOS]; +extern BlockHeap *ban_heap; + + +/* XXX check_string is propably not longer required in add_id and del_id */ +/* check_string() + * + * inputs - string to check + * output - pointer to modified string + * side effects - Fixes a string so that the first white space found + * becomes an end of string marker (`\0`). + * returns the 'fixed' string or "*" if the string + * was NULL length or a NULL pointer. + */ +static char * +check_string(char *s) +{ + char *str = s; + static char star[] = "*"; + + if (EmptyString(s)) + return star; + + for (; *s; ++s) + { + if (IsSpace(*s)) + { + *s = '\0'; + break; + } + } + + return str; +} + +/* + * Ban functions to work with mode +b/e/d/I + */ +/* add the specified ID to the channel.. + * -is 8/9/00 + */ + +int +add_id(struct Client *client_p, struct Channel *chptr, char *banid, int type) +{ + dlink_list *list = NULL; + dlink_node *ban = NULL; + size_t len = 0; + struct Ban *ban_p = NULL; + unsigned int num_mask; + char name[NICKLEN + 1]; + char user[USERLEN + 1]; + char host[HOSTLEN + 1]; + struct split_nuh_item nuh; + + /* dont let local clients overflow the b/e/I lists */ + if (MyClient(client_p)) + { + num_mask = dlink_list_length(&chptr->banlist) + + dlink_list_length(&chptr->exceptlist) + + dlink_list_length(&chptr->invexlist); + + if (num_mask >= ConfigChannel.max_bans) + { + sendto_one(client_p, form_str(ERR_BANLISTFULL), + me.name, client_p->name, chptr->chname, banid); + return 0; + } + + collapse(banid); + } + + nuh.nuhmask = check_string(banid); + nuh.nickptr = name; + nuh.userptr = user; + nuh.hostptr = host; + + nuh.nicksize = sizeof(name); + nuh.usersize = sizeof(user); + nuh.hostsize = sizeof(host); + + split_nuh(&nuh); + + /* + * Re-assemble a new n!u@h and print it back to banid for sending + * the mode to the channel. + */ + len = ircsprintf(banid, "%s!%s@%s", name, user, host); + + switch (type) + { + case CHFL_BAN: + list = &chptr->banlist; + clear_ban_cache(chptr); + break; + case CHFL_EXCEPTION: + list = &chptr->exceptlist; + clear_ban_cache(chptr); + break; + case CHFL_INVEX: + list = &chptr->invexlist; + break; + default: + assert(0); + return 0; + } + + DLINK_FOREACH(ban, list->head) + { + ban_p = ban->data; + if (!irccmp(ban_p->name, name) && + !irccmp(ban_p->username, user) && + !irccmp(ban_p->host, host)) + { + return 0; + } + } + + ban_p = BlockHeapAlloc(ban_heap); + + DupString(ban_p->name, name); + DupString(ban_p->username, user); + DupString(ban_p->host, host); + + ban_p->when = CurrentTime; + ban_p->len = len - 2; /* -2 for @ and ! */ + ban_p->type = parse_netmask(host, &ban_p->addr, &ban_p->bits); + + if (IsClient(client_p)) + { + ban_p->who = MyMalloc(strlen(client_p->name) + + strlen(client_p->username) + + strlen(client_p->host) + 3); + ircsprintf(ban_p->who, "%s!%s@%s", client_p->name, + client_p->username, client_p->host); + } + else + DupString(ban_p->who, client_p->name); + + dlinkAdd(ban_p, &ban_p->node, list); + + return 1; +} + +/* + * inputs - pointer to channel + * - pointer to ban id + * - type of ban, i.e. ban, exception, invex + * output - 0 for failure, 1 for success + * side effects - + */ +static int +del_id(struct Channel *chptr, char *banid, int type) +{ + dlink_list *list; + dlink_node *ban; + struct Ban *banptr; + char name[NICKLEN + 1]; + char user[USERLEN + 1]; + char host[HOSTLEN + 1]; + struct split_nuh_item nuh; + + if (banid == NULL) + return 0; + + nuh.nuhmask = check_string(banid); + nuh.nickptr = name; + nuh.userptr = user; + nuh.hostptr = host; + + nuh.nicksize = sizeof(name); + nuh.usersize = sizeof(user); + nuh.hostsize = sizeof(host); + + split_nuh(&nuh); + + /* + * Re-assemble a new n!u@h and print it back to banid for sending + * the mode to the channel. + */ + ircsprintf(banid, "%s!%s@%s", name, user, host); + + switch (type) + { + case CHFL_BAN: + list = &chptr->banlist; + clear_ban_cache(chptr); + break; + case CHFL_EXCEPTION: + list = &chptr->exceptlist; + clear_ban_cache(chptr); + break; + case CHFL_INVEX: + list = &chptr->invexlist; + break; + default: + sendto_realops_flags(UMODE_ALL, L_ALL, + "del_id() called with unknown ban type %d!", type); + return 0; + } + + DLINK_FOREACH(ban, list->head) + { + banptr = ban->data; + + if (!irccmp(name, banptr->name) && + !irccmp(user, banptr->username) && + !irccmp(host, banptr->host)) + { + remove_ban(banptr, list); + return 1; + } + } + + return 0; +} + +const struct mode_letter chan_modes[] = { + { MODE_INVITEONLY, 'i' }, + { MODE_MODERATED, 'm' }, + { MODE_NOPRIVMSGS, 'n' }, + { MODE_PRIVATE, 'p' }, + { MODE_REGISTERED, 'r' }, + { MODE_SECRET, 's' }, + { MODE_TOPICLIMIT, 't' }, + { MODE_OPERONLY, 'O' }, + { MODE_REGONLY, 'R' }, + { MODE_SSLONLY, 'S' }, + { 0, '\0' } +}; + +/* channel_modes() + * + * inputs - pointer to channel + * - pointer to client + * - pointer to mode buf + * - pointer to parameter buf + * output - NONE + * side effects - write the "simple" list of channel modes for channel + * chptr onto buffer mbuf with the parameters in pbuf. + */ +void +channel_modes(struct Channel *chptr, struct Client *client_p, + char *mbuf, char *pbuf) +{ + const struct mode_letter *tab = chan_modes; + + *mbuf++ = '+'; + *pbuf = '\0'; + + for (; tab->mode; ++tab) + if (chptr->mode.mode & tab->mode) + *mbuf++ = tab->letter; + + if (chptr->mode.limit) + { + *mbuf++ = 'l'; + + if (IsServer(client_p) || HasFlag(client_p, FLAGS_SERVICE) || IsMember(client_p, chptr)) + pbuf += ircsprintf(pbuf, "%d ", chptr->mode.limit); + } + + if (chptr->mode.key[0]) + { + *mbuf++ = 'k'; + + if (IsServer(client_p) || HasFlag(client_p, FLAGS_SERVICE) || IsMember(client_p, chptr)) + ircsprintf(pbuf, "%s ", chptr->mode.key); + } + + *mbuf = '\0'; +} + +/* fix_key() + * + * inputs - pointer to key to clean up + * output - pointer to cleaned up key + * side effects - input string is modified + * + * stolen from Undernet's ircd -orabidoo + */ +static char * +fix_key(char *arg) +{ + unsigned char *s, *t, c; + + for (s = t = (unsigned char *)arg; (c = *s); s++) + { + c &= 0x7f; + if (c != ':' && c > ' ' && c != ',') + *t++ = c; + } + + *t = '\0'; + return(arg); +} + +/* fix_key_old() + * + * inputs - pointer to key to clean up + * output - pointer to cleaned up key + * side effects - input string is modifed + * + * Here we attempt to be compatible with older non-hybrid servers. + * We can't back down from the ':' issue however. --Rodder + */ +static char * +fix_key_old(char *arg) +{ + unsigned char *s, *t, c; + + for (s = t = (unsigned char *)arg; (c = *s); s++) + { + c &= 0x7f; + if ((c != 0x0a) && (c != ':') && (c != 0x0d) && (c != ',')) + *t++ = c; + } + + *t = '\0'; + return(arg); +} + +/* bitmasks for various error returns that set_channel_mode should only return + * once per call -orabidoo + */ + +#define SM_ERR_NOTS 0x00000001 /* No TS on channel */ +#define SM_ERR_NOOPS 0x00000002 /* No chan ops */ +#define SM_ERR_UNKNOWN 0x00000004 +#define SM_ERR_RPL_B 0x00000008 +#define SM_ERR_RPL_E 0x00000010 +#define SM_ERR_NOTONCHANNEL 0x00000020 /* Not on channel */ +#define SM_ERR_RPL_I 0x00000040 +#define SM_ERR_NOTOPER 0x00000080 +#define SM_ERR_ONLYSERVER 0x00000100 + +/* Now lets do some stuff to keep track of what combinations of + * servers exist... + * Note that the number of combinations doubles each time you add + * something to this list. Each one is only quick if no servers use that + * combination, but if the numbers get too high here MODE will get too + * slow. I suggest if you get more than 7 here, you consider getting rid + * of some and merging or something. If it wasn't for irc+cs we would + * probably not even need to bother about most of these, but unfortunately + * we do. -A1kmm + */ + +/* void init_chcap_usage_counts(void) + * + * Inputs - none + * Output - none + * Side-effects - Initialises the usage counts to zero. Fills in the + * chcap_yes and chcap_no combination tables. + */ +void +init_chcap_usage_counts(void) +{ + unsigned long m, c, y, n; + + memset(chcap_combos, 0, sizeof(chcap_combos)); + + /* For every possible combination */ + for (m = 0; m < NCHCAP_COMBOS; m++) + { + /* Check each capab */ + for (c = y = n = 0; c < NCHCAPS; c++) + { + if ((m & (1 << c)) == 0) + n |= channel_capabs[c]; + else + y |= channel_capabs[c]; + } + chcap_combos[m].cap_yes = y; + chcap_combos[m].cap_no = n; + } +} + +/* void set_chcap_usage_counts(struct Client *serv_p) + * Input: serv_p; The client whose capabs to register. + * Output: none + * Side-effects: Increments the usage counts for the correct capab + * combination. + */ +void +set_chcap_usage_counts(struct Client *serv_p) +{ + int n; + + for (n = 0; n < NCHCAP_COMBOS; n++) + { + if (((serv_p->localClient->caps & chcap_combos[n].cap_yes) == + chcap_combos[n].cap_yes) && + ((serv_p->localClient->caps & chcap_combos[n].cap_no) == 0)) + { + chcap_combos[n].count++; + return; + } + } + + /* This should be impossible -A1kmm. */ + assert(0); +} + +/* void set_chcap_usage_counts(struct Client *serv_p) + * + * Inputs - serv_p; The client whose capabs to register. + * Output - none + * Side-effects - Decrements the usage counts for the correct capab + * combination. + */ +void +unset_chcap_usage_counts(struct Client *serv_p) +{ + int n; + + for (n = 0; n < NCHCAP_COMBOS; n++) + { + if ((serv_p->localClient->caps & chcap_combos[n].cap_yes) == + chcap_combos[n].cap_yes && + (serv_p->localClient->caps & chcap_combos[n].cap_no) == 0) + { + /* Hopefully capabs can't change dynamically or anything... */ + assert(chcap_combos[n].count > 0); + chcap_combos[n].count--; + return; + } + } + + /* This should be impossible -A1kmm. */ + assert(0); +} + +/* Mode functions handle mode changes for a particular mode... */ +static void +chm_nosuch(struct Client *client_p, struct Client *source_p, + struct Channel *chptr, int parc, int *parn, + char **parv, int *errors, int alev, int dir, char c, void *d, + const char *chname) +{ + if (*errors & SM_ERR_UNKNOWN) + return; + + *errors |= SM_ERR_UNKNOWN; + sendto_one(source_p, form_str(ERR_UNKNOWNMODE), me.name, + source_p->name, c); +} + +static void +chm_simple(struct Client *client_p, struct Client *source_p, struct Channel *chptr, + int parc, int *parn, char **parv, int *errors, int alev, int dir, + char c, void *d, const char *chname) +{ + long mode_type; + + mode_type = (long)d; + + if ((alev < CHACCESS_HALFOP) || + ((mode_type == MODE_PRIVATE) && (alev < CHACCESS_CHANOP))) + { + if (!(*errors & SM_ERR_NOOPS)) + sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ? + ERR_NOTONCHANNEL : ERR_CHANOPRIVSNEEDED), + me.name, source_p->name, chname); + *errors |= SM_ERR_NOOPS; + return; + } + + /* If have already dealt with this simple mode, ignore it */ + if (simple_modes_mask & mode_type) + return; + + simple_modes_mask |= mode_type; + + /* setting + */ + /* Apparently, (though no one has ever told the hybrid group directly) + * admins don't like redundant mode checking. ok. It would have been nice + * if you had have told us directly. I've left the original code snippets + * in place. + * + * -Dianora + */ + if ((dir == MODE_ADD)) /* && !(chptr->mode.mode & mode_type)) */ + { + chptr->mode.mode |= mode_type; + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_ADD; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count++].arg = NULL; + } + else if ((dir == MODE_DEL)) /* && (chptr->mode.mode & mode_type)) */ + { + /* setting - */ + + chptr->mode.mode &= ~mode_type; + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_DEL; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count++].arg = NULL; + } +} + +static void +chm_registered(struct Client *client_p, struct Client *source_p, struct Channel *chptr, + int parc, int *parn, char **parv, int *errors, int alev, int dir, + char c, void *d, const char *chname) +{ + long mode_type; + + mode_type = (long)d; + + + if (!IsServer(source_p) && !HasFlag(source_p, FLAGS_SERVICE)) + { + if (!(*errors & SM_ERR_ONLYSERVER)) + sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ? + ERR_NOTONCHANNEL : ERR_ONLYSERVERSCANCHANGE), + me.name, source_p->name, chname); + *errors |= SM_ERR_ONLYSERVER; + return; + } + + /* If have already dealt with this simple mode, ignore it */ + if (simple_modes_mask & mode_type) + return; + + simple_modes_mask |= mode_type; + + /* setting + */ + /* Apparently, (though no one has ever told the hybrid group directly) + * admins don't like redundant mode checking. ok. It would have been nice + * if you had have told us directly. I've left the original code snippets + * in place. + * + * -Dianora + */ + if ((dir == MODE_ADD)) /* && !(chptr->mode.mode & mode_type)) */ + { + chptr->mode.mode |= mode_type; + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_ADD; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count++].arg = NULL; + } + else if ((dir == MODE_DEL)) /* && (chptr->mode.mode & mode_type)) */ + { + /* setting - */ + + chptr->mode.mode &= ~mode_type; + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_DEL; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count++].arg = NULL; + } +} + +static void +chm_operonly(struct Client *client_p, struct Client *source_p, struct Channel *chptr, + int parc, int *parn, char **parv, int *errors, int alev, int dir, + char c, void *d, const char *chname) +{ + long mode_type; + + mode_type = (long)d; + + if ((alev < CHACCESS_HALFOP) || + ((mode_type == MODE_PRIVATE) && (alev < CHACCESS_CHANOP))) + { + if (!(*errors & SM_ERR_NOOPS)) + sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ? + ERR_NOTONCHANNEL : ERR_CHANOPRIVSNEEDED), + me.name, source_p->name, chname); + *errors |= SM_ERR_NOOPS; + return; + } + else if (MyClient(source_p) && !HasUMode(source_p, UMODE_OPER)) + { + if (!(*errors & SM_ERR_NOTOPER)) + { + if (alev == CHACCESS_NOTONCHAN) + sendto_one(source_p, form_str(ERR_NOTONCHANNEL), + me.name, source_p->name, chname); + else + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + } + + *errors |= SM_ERR_NOTOPER; + return; + } + + /* If have already dealt with this simple mode, ignore it */ + if (simple_modes_mask & mode_type) + return; + + simple_modes_mask |= mode_type; + + if ((dir == MODE_ADD)) /* && !(chptr->mode.mode & mode_type)) */ + { + chptr->mode.mode |= mode_type; + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_ADD; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count++].arg = NULL; + } + else if ((dir == MODE_DEL)) /* && (chptr->mode.mode & mode_type)) */ + { + /* setting - */ + + chptr->mode.mode &= ~mode_type; + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_DEL; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count++].arg = NULL; + } +} + +static void +chm_ban(struct Client *client_p, struct Client *source_p, + struct Channel *chptr, int parc, int *parn, + char **parv, int *errors, int alev, int dir, char c, void *d, + const char *chname) +{ + char *mask = NULL; + + if (dir == MODE_QUERY || parc <= *parn) + { + dlink_node *ptr = NULL; + + if (*errors & SM_ERR_RPL_B) + return; + + *errors |= SM_ERR_RPL_B; + + DLINK_FOREACH(ptr, chptr->banlist.head) + { + const struct Ban *banptr = ptr->data; + sendto_one(client_p, form_str(RPL_BANLIST), + me.name, client_p->name, chname, + banptr->name, banptr->username, banptr->host, + banptr->who, banptr->when); + } + + sendto_one(source_p, form_str(RPL_ENDOFBANLIST), me.name, + source_p->name, chname); + return; + } + + if (alev < CHACCESS_HALFOP) + { + if (!(*errors & SM_ERR_NOOPS)) + sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ? + ERR_NOTONCHANNEL : ERR_CHANOPRIVSNEEDED), + me.name, source_p->name, chname); + *errors |= SM_ERR_NOOPS; + return; + } + + if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS)) + return; + + mask = nuh_mask[*parn]; + memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn])); + ++*parn; + + if (IsServer(client_p)) + if (strchr(mask, ' ')) + return; + + switch (dir) + { + case MODE_ADD: + if (!add_id(source_p, chptr, mask, CHFL_BAN)) + return; + break; + case MODE_DEL: + if (!del_id(chptr, mask, CHFL_BAN)) + return; + break; + default: + assert(0); + } + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = dir; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count++].arg = mask; +} + +static void +chm_except(struct Client *client_p, struct Client *source_p, + struct Channel *chptr, int parc, int *parn, + char **parv, int *errors, int alev, int dir, char c, void *d, + const char *chname) +{ + char *mask = NULL; + + if (alev < CHACCESS_HALFOP) + { + if (!(*errors & SM_ERR_NOOPS)) + sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ? + ERR_NOTONCHANNEL : ERR_CHANOPRIVSNEEDED), + me.name, source_p->name, chname); + *errors |= SM_ERR_NOOPS; + return; + } + + if (dir == MODE_QUERY || parc <= *parn) + { + dlink_node *ptr = NULL; + + if (*errors & SM_ERR_RPL_E) + return; + + *errors |= SM_ERR_RPL_E; + + DLINK_FOREACH(ptr, chptr->exceptlist.head) + { + const struct Ban *banptr = ptr->data; + sendto_one(client_p, form_str(RPL_EXCEPTLIST), + me.name, client_p->name, chname, + banptr->name, banptr->username, banptr->host, + banptr->who, banptr->when); + } + + sendto_one(source_p, form_str(RPL_ENDOFEXCEPTLIST), me.name, + source_p->name, chname); + return; + } + + if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS)) + return; + + mask = nuh_mask[*parn]; + memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn])); + ++*parn; + + if (IsServer(client_p)) + if (strchr(mask, ' ')) + return; + + switch (dir) + { + case MODE_ADD: + if (!add_id(source_p, chptr, mask, CHFL_EXCEPTION)) + return; + break; + case MODE_DEL: + if (!del_id(chptr, mask, CHFL_EXCEPTION)) + return; + break; + default: + assert(0); + } + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = dir; + mode_changes[mode_count].caps = CAP_EX; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ONLY_CHANOPS; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count++].arg = mask; +} + +static void +chm_invex(struct Client *client_p, struct Client *source_p, + struct Channel *chptr, int parc, int *parn, + char **parv, int *errors, int alev, int dir, char c, void *d, + const char *chname) +{ + char *mask = NULL; + + if (alev < CHACCESS_HALFOP) + { + if (!(*errors & SM_ERR_NOOPS)) + sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ? + ERR_NOTONCHANNEL : ERR_CHANOPRIVSNEEDED), + me.name, source_p->name, chname); + *errors |= SM_ERR_NOOPS; + return; + } + + if (dir == MODE_QUERY || parc <= *parn) + { + dlink_node *ptr = NULL; + + if (*errors & SM_ERR_RPL_I) + return; + + *errors |= SM_ERR_RPL_I; + + DLINK_FOREACH(ptr, chptr->invexlist.head) + { + const struct Ban *banptr = ptr->data; + sendto_one(client_p, form_str(RPL_INVITELIST), me.name, + client_p->name, chname, + banptr->name, banptr->username, banptr->host, + banptr->who, banptr->when); + } + + sendto_one(source_p, form_str(RPL_ENDOFINVITELIST), me.name, + source_p->name, chname); + return; + } + + if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS)) + return; + + mask = nuh_mask[*parn]; + memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn])); + ++*parn; + + if (IsServer(client_p)) + if (strchr(mask, ' ')) + return; + + switch (dir) + { + case MODE_ADD: + if (!add_id(source_p, chptr, mask, CHFL_INVEX)) + return; + break; + case MODE_DEL: + if (!del_id(chptr, mask, CHFL_INVEX)) + return; + break; + default: + assert(0); + } + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = dir; + mode_changes[mode_count].caps = CAP_IE; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ONLY_CHANOPS; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count++].arg = mask; +} + +/* + * inputs - pointer to channel + * output - none + * side effects - clear ban cache + */ +void +clear_ban_cache(struct Channel *chptr) +{ + dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, chptr->members.head) + { + struct Membership *ms = ptr->data; + + if (MyConnect(ms->client_p)) + ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED); + } +} + +void +clear_ban_cache_client(struct Client *client_p) +{ + dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, client_p->channel.head) + { + struct Membership *ms = ptr->data; + ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED); + } +} + +static void +chm_op(struct Client *client_p, struct Client *source_p, + struct Channel *chptr, int parc, int *parn, + char **parv, int *errors, int alev, int dir, char c, void *d, + const char *chname) +{ + char *opnick; + struct Client *targ_p; + struct Membership *member; + int caps = 0; + + if (alev < CHACCESS_CHANOP) + { + if (!(*errors & SM_ERR_NOOPS)) + sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ? + ERR_NOTONCHANNEL : ERR_CHANOPRIVSNEEDED), + me.name, source_p->name, chname); + *errors |= SM_ERR_NOOPS; + return; + } + + if ((dir == MODE_QUERY) || (parc <= *parn)) + return; + + opnick = parv[(*parn)++]; + + if ((targ_p = find_chasing(client_p, source_p, opnick, NULL)) == NULL) + return; + if (!IsClient(targ_p)) + return; + + if ((member = find_channel_link(targ_p, chptr)) == NULL) + { + if (!(*errors & SM_ERR_NOTONCHANNEL)) + sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL), + me.name, source_p->name, opnick, chname); + *errors |= SM_ERR_NOTONCHANNEL; + return; + } + + if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS)) + return; + + /* no redundant mode changes */ + if (dir == MODE_ADD && has_member_flags(member, CHFL_CHANOP)) + return; + if (dir == MODE_DEL && !has_member_flags(member, CHFL_CHANOP)) + { +#ifdef HALFOPS + if (has_member_flags(member, CHFL_HALFOP)) + { + --*parn; + chm_hop(client_p, source_p, chptr, parc, parn, parv, errors, alev, + dir, c, d, chname); + } +#endif + return; + } + +#ifdef HALFOPS + if (dir == MODE_ADD && has_member_flags(member, CHFL_HALFOP)) + { + /* promoting from % to @ is visible only to CAP_HOPS servers */ + mode_changes[mode_count].letter = 'h'; + mode_changes[mode_count].dir = MODE_DEL; + mode_changes[mode_count].caps = caps = CAP_HOPS; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count].arg = targ_p->name; + mode_changes[mode_count++].client = targ_p; + } +#endif + + mode_changes[mode_count].letter = 'o'; + mode_changes[mode_count].dir = dir; + mode_changes[mode_count].caps = caps; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].id = targ_p->id; + mode_changes[mode_count].arg = targ_p->name; + mode_changes[mode_count++].client = targ_p; + + if (dir == MODE_ADD) + { + AddMemberFlag(member, CHFL_CHANOP); + DelMemberFlag(member, CHFL_DEOPPED | CHFL_HALFOP); + } + else + DelMemberFlag(member, CHFL_CHANOP); +} + +#ifdef HALFOPS +static void +chm_hop(struct Client *client_p, struct Client *source_p, + struct Channel *chptr, int parc, int *parn, + char **parv, int *errors, int alev, int dir, char c, void *d, + const char *chname) +{ + char *opnick; + struct Client *targ_p; + struct Membership *member; + + /* *sigh* - dont allow halfops to set +/-h, they could fully control a + * channel if there were no ops - it doesnt solve anything.. MODE_PRIVATE + * when used with MODE_SECRET is paranoid - cant use +p + * + * it needs to be optional per channel - but not via +p, that or remove + * paranoid.. -- fl_ + * + * +p means paranoid, it is useless for anything else on modern IRC, as + * list isn't really usable. If you want to have a private channel these + * days, you set it +s. Halfops can no longer remove simple modes when + * +p is set (although they can set +p) so it is safe to use this to + * control whether they can (de)halfop... + */ + if (alev < + ((chptr->mode.mode & MODE_PRIVATE) ? CHACCESS_CHANOP : CHACCESS_HALFOP)) + { + if (!(*errors & SM_ERR_NOOPS)) + sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ? + ERR_NOTONCHANNEL : ERR_CHANOPRIVSNEEDED), + me.name, source_p->name, chname); + *errors |= SM_ERR_NOOPS; + return; + } + + if ((dir == MODE_QUERY) || (parc <= *parn)) + return; + + opnick = parv[(*parn)++]; + + if ((targ_p = find_chasing(client_p, source_p, opnick, NULL)) == NULL) + return; + if (!IsClient(targ_p)) + return; + + if ((member = find_channel_link(targ_p, chptr)) == NULL) + { + if (!(*errors & SM_ERR_NOTONCHANNEL)) + sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL), + me.name, source_p->name, opnick, chname); + *errors |= SM_ERR_NOTONCHANNEL; + return; + } + + if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS)) + return; + + /* no redundant mode changes */ + if (dir == MODE_ADD && has_member_flags(member, CHFL_HALFOP | CHFL_CHANOP)) + return; + if (dir == MODE_DEL && !has_member_flags(member, CHFL_HALFOP)) + return; + + mode_changes[mode_count].letter = 'h'; + mode_changes[mode_count].dir = dir; + mode_changes[mode_count].caps = CAP_HOPS; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].id = targ_p->id; + mode_changes[mode_count].arg = targ_p->name; + mode_changes[mode_count++].client = targ_p; + + mode_changes[mode_count].letter = 'o'; + mode_changes[mode_count].dir = dir; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = CAP_HOPS; + mode_changes[mode_count].mems = ONLY_SERVERS; + mode_changes[mode_count].id = targ_p->id; + mode_changes[mode_count].arg = targ_p->name; + mode_changes[mode_count++].client = targ_p; + + if (dir == MODE_ADD) + { + AddMemberFlag(member, CHFL_HALFOP); + DelMemberFlag(member, CHFL_DEOPPED); + } + else + DelMemberFlag(member, CHFL_HALFOP); +} +#endif + +static void +chm_voice(struct Client *client_p, struct Client *source_p, + struct Channel *chptr, int parc, int *parn, + char **parv, int *errors, int alev, int dir, char c, void *d, + const char *chname) +{ + char *opnick; + struct Client *targ_p; + struct Membership *member; + + if (alev < CHACCESS_HALFOP) + { + if (!(*errors & SM_ERR_NOOPS)) + sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ? + ERR_NOTONCHANNEL : ERR_CHANOPRIVSNEEDED), + me.name, source_p->name, chname); + *errors |= SM_ERR_NOOPS; + return; + } + + if ((dir == MODE_QUERY) || parc <= *parn) + return; + + opnick = parv[(*parn)++]; + + if ((targ_p = find_chasing(client_p, source_p, opnick, NULL)) == NULL) + return; + if (!IsClient(targ_p)) + return; + + if ((member = find_channel_link(targ_p, chptr)) == NULL) + { + if (!(*errors & SM_ERR_NOTONCHANNEL)) + sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL), + me.name, source_p->name, opnick, chname); + *errors |= SM_ERR_NOTONCHANNEL; + return; + } + + if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS)) + return; + + /* no redundant mode changes */ + if (dir == MODE_ADD && has_member_flags(member, CHFL_VOICE)) + return; + if (dir == MODE_DEL && !has_member_flags(member, CHFL_VOICE)) + return; + + mode_changes[mode_count].letter = 'v'; + mode_changes[mode_count].dir = dir; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].id = targ_p->id; + mode_changes[mode_count].arg = targ_p->name; + mode_changes[mode_count++].client = targ_p; + + if (dir == MODE_ADD) + AddMemberFlag(member, CHFL_VOICE); + else + DelMemberFlag(member, CHFL_VOICE); +} + +static void +chm_limit(struct Client *client_p, struct Client *source_p, + struct Channel *chptr, int parc, int *parn, + char **parv, int *errors, int alev, int dir, char c, void *d, + const char *chname) +{ + int i, limit; + char *lstr; + + if (alev < CHACCESS_HALFOP) + { + if (!(*errors & SM_ERR_NOOPS)) + sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ? + ERR_NOTONCHANNEL : ERR_CHANOPRIVSNEEDED), + me.name, source_p->name, chname); + *errors |= SM_ERR_NOOPS; + return; + } + + if (dir == MODE_QUERY) + return; + + if ((dir == MODE_ADD) && parc > *parn) + { + lstr = parv[(*parn)++]; + + if ((limit = atoi(lstr)) <= 0) + return; + + ircsprintf(lstr, "%d", limit); + + /* if somebody sets MODE #channel +ll 1 2, accept latter --fl */ + for (i = 0; i < mode_count; i++) + { + if (mode_changes[i].letter == c && mode_changes[i].dir == MODE_ADD) + mode_changes[i].letter = 0; + } + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_ADD; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count++].arg = lstr; + + chptr->mode.limit = limit; + } + else if (dir == MODE_DEL) + { + if (!chptr->mode.limit) + return; + + chptr->mode.limit = 0; + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_DEL; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count++].arg = NULL; + } +} + +static void +chm_key(struct Client *client_p, struct Client *source_p, + struct Channel *chptr, int parc, int *parn, + char **parv, int *errors, int alev, int dir, char c, void *d, + const char *chname) +{ + int i; + char *key; + + if (alev < CHACCESS_HALFOP) + { + if (!(*errors & SM_ERR_NOOPS)) + sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ? + ERR_NOTONCHANNEL : ERR_CHANOPRIVSNEEDED), + me.name, source_p->name, chname); + *errors |= SM_ERR_NOOPS; + return; + } + + if (dir == MODE_QUERY) + return; + + if ((dir == MODE_ADD) && parc > *parn) + { + key = parv[(*parn)++]; + + if (MyClient(source_p)) + fix_key(key); + else + fix_key_old(key); + + if (*key == '\0') + return; + + assert(key[0] != ' '); + strlcpy(chptr->mode.key, key, sizeof(chptr->mode.key)); + + /* if somebody does MODE #channel +kk a b, accept latter --fl */ + for (i = 0; i < mode_count; i++) + { + if (mode_changes[i].letter == c && mode_changes[i].dir == MODE_ADD) + mode_changes[i].letter = 0; + } + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_ADD; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count++].arg = chptr->mode.key; + } + else if (dir == MODE_DEL) + { + if (parc > *parn) + (*parn)++; + + if (chptr->mode.key[0] == '\0') + return; + + chptr->mode.key[0] = '\0'; + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_DEL; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count++].arg = "*"; + } +} + +struct ChannelMode +{ + void (*func) (struct Client *client_p, struct Client *source_p, + struct Channel *chptr, int parc, int *parn, char **parv, + int *errors, int alev, int dir, char c, void *d, + const char *chname); + void *d; +}; + +static struct ChannelMode ModeTable[255] = +{ + {chm_nosuch, NULL}, + {chm_nosuch, NULL}, /* A */ + {chm_nosuch, NULL}, /* B */ + {chm_nosuch, NULL}, /* C */ + {chm_nosuch, NULL}, /* D */ + {chm_nosuch, NULL}, /* E */ + {chm_nosuch, NULL}, /* F */ + {chm_nosuch, NULL}, /* G */ + {chm_nosuch, NULL}, /* H */ + {chm_invex, NULL}, /* I */ + {chm_nosuch, NULL}, /* J */ + {chm_nosuch, NULL}, /* K */ + {chm_nosuch, NULL}, /* L */ + {chm_nosuch, NULL}, /* M */ + {chm_nosuch, NULL}, /* N */ + {chm_operonly, (void *) MODE_OPERONLY}, /* O */ + {chm_nosuch, NULL}, /* P */ + {chm_nosuch, NULL}, /* Q */ + {chm_simple, (void *) MODE_REGONLY}, /* R */ + {chm_simple, (void *) MODE_SSLONLY}, /* S */ + {chm_nosuch, NULL}, /* T */ + {chm_nosuch, NULL}, /* U */ + {chm_nosuch, NULL}, /* V */ + {chm_nosuch, NULL}, /* W */ + {chm_nosuch, NULL}, /* X */ + {chm_nosuch, NULL}, /* Y */ + {chm_nosuch, NULL}, /* Z */ + {chm_nosuch, NULL}, + {chm_nosuch, NULL}, + {chm_nosuch, NULL}, + {chm_nosuch, NULL}, + {chm_nosuch, NULL}, + {chm_nosuch, NULL}, + {chm_nosuch, NULL}, /* a */ + {chm_ban, NULL}, /* b */ + {chm_nosuch, NULL}, /* c */ + {chm_nosuch, NULL}, /* d */ + {chm_except, NULL}, /* e */ + {chm_nosuch, NULL}, /* f */ + {chm_nosuch, NULL}, /* g */ +#ifdef HALFOPS + {chm_hop, NULL}, /* h */ +#else + {chm_nosuch, NULL}, /* h */ +#endif + {chm_simple, (void *) MODE_INVITEONLY}, /* i */ + {chm_nosuch, NULL}, /* j */ + {chm_key, NULL}, /* k */ + {chm_limit, NULL}, /* l */ + {chm_simple, (void *) MODE_MODERATED}, /* m */ + {chm_simple, (void *) MODE_NOPRIVMSGS}, /* n */ + {chm_op, NULL}, /* o */ + {chm_simple, (void *) MODE_PRIVATE}, /* p */ + {chm_nosuch, NULL}, /* q */ + {chm_registered, (void *) MODE_REGISTERED}, /* r */ + {chm_simple, (void *) MODE_SECRET}, /* s */ + {chm_simple, (void *) MODE_TOPICLIMIT}, /* t */ + {chm_nosuch, NULL}, /* u */ + {chm_voice, NULL}, /* v */ + {chm_nosuch, NULL}, /* w */ + {chm_nosuch, NULL}, /* x */ + {chm_nosuch, NULL}, /* y */ + {chm_nosuch, NULL}, /* z */ +}; + +/* get_channel_access() + * + * inputs - pointer to Client struct + * - pointer to Membership struct + * output - CHACCESS_CHANOP if we should let them have + * chanop level access, 0 for peon level access. + * side effects - NONE + */ +static int +get_channel_access(struct Client *source_p, struct Membership *member) +{ + /* Let hacked servers in for now... */ + if (!MyClient(source_p)) + return CHACCESS_CHANOP; + + if (member == NULL) + return CHACCESS_NOTONCHAN; + + /* just to be sure.. */ + assert(source_p == member->client_p); + + if (has_member_flags(member, CHFL_CHANOP)) + return CHACCESS_CHANOP; + +#ifdef HALFOPS + if (has_member_flags(member, CHFL_HALFOP)) + return CHACCESS_HALFOP; +#endif + + return CHACCESS_PEON; +} + +/* void send_cap_mode_changes(struct Client *client_p, + * struct Client *source_p, + * struct Channel *chptr, int cap, int nocap) + * Input: The client sending(client_p), the source client(source_p), + * the channel to send mode changes for(chptr) + * Output: None. + * Side-effects: Sends the appropriate mode changes to capable servers. + * + * send_cap_mode_changes() will loop the server list itself, because + * at this point in time we have 4 capabs for channels, CAP_IE, CAP_EX, + * and a server could support any number of these.. + * so we make the modebufs per server, tailoring them to each servers + * specific demand. Its not very pretty, but its one of the few realistic + * ways to handle having this many capabs for channel modes.. --fl_ + * + * Reverted back to my original design, except that we now keep a count + * of the number of servers which each combination as an optimisation, so + * the capabs combinations which are not needed are not worked out. -A1kmm + */ +/* rewritten to ensure parabuf < MODEBUFLEN -db */ + +static void +send_cap_mode_changes(struct Client *client_p, struct Client *source_p, + struct Channel *chptr, unsigned int cap, unsigned int nocap) +{ + int i, mbl, pbl, arglen, nc, mc; + int len; + const char *arg = NULL; + char *parptr; + int dir = MODE_QUERY; + + mc = 0; + nc = 0; + pbl = 0; + + parabuf[0] = '\0'; + parptr = parabuf; + + if ((cap & CAP_TS6) && source_p->id[0] != '\0') + mbl = ircsprintf(modebuf, ":%s TMODE %lu %s ", source_p->id, + (unsigned long)chptr->channelts, chptr->chname); + else + mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->name, + chptr->chname); + + /* loop the list of - modes we have */ + for (i = 0; i < mode_count; i++) + { + /* if they dont support the cap we need, or they do support a cap they + * cant have, then dont add it to the modebuf.. that way they wont see + * the mode + */ + if ((mode_changes[i].letter == 0) || + ((cap & mode_changes[i].caps) != mode_changes[i].caps) + || ((nocap & mode_changes[i].nocaps) != mode_changes[i].nocaps)) + continue; + + arg = ""; + + if ((cap & CAP_TS6) && mode_changes[i].id) + arg = mode_changes[i].id; + if (*arg == '\0') + arg = mode_changes[i].arg; + + /* if we're creeping past the buf size, we need to send it and make + * another line for the other modes + * XXX - this could give away server topology with uids being + * different lengths, but not much we can do, except possibly break + * them as if they were the longest of the nick or uid at all times, + * which even then won't work as we don't always know the uid -A1kmm. + */ + if (arg != NULL) + arglen = strlen(arg); + else + arglen = 0; + + if ((mc == MAXMODEPARAMS) || + ((arglen + mbl + pbl + 2) > IRCD_BUFSIZE) || + (pbl + arglen + BAN_FUDGE) >= MODEBUFLEN) + { + if (nc != 0) + sendto_server(client_p, cap, nocap, + "%s %s", + modebuf, parabuf); + nc = 0; + mc = 0; + + if ((cap & CAP_TS6) && source_p->id[0] != '\0') + mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->id, + chptr->chname); + else + mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->name, + chptr->chname); + + pbl = 0; + parabuf[0] = '\0'; + parptr = parabuf; + dir = MODE_QUERY; + } + + if (dir != mode_changes[i].dir) + { + modebuf[mbl++] = (mode_changes[i].dir == MODE_ADD) ? '+' : '-'; + dir = mode_changes[i].dir; + } + + modebuf[mbl++] = mode_changes[i].letter; + modebuf[mbl] = '\0'; + nc++; + + if (arg != NULL) + { + len = ircsprintf(parptr, "%s ", arg); + pbl += len; + parptr += len; + mc++; + } + } + + if (pbl && parabuf[pbl - 1] == ' ') + parabuf[pbl - 1] = 0; + + if (nc != 0) + sendto_server(client_p, cap, nocap, + "%s %s", modebuf, parabuf); +} + +/* void send_mode_changes(struct Client *client_p, + * struct Client *source_p, + * struct Channel *chptr) + * Input: The client sending(client_p), the source client(source_p), + * the channel to send mode changes for(chptr), + * mode change globals. + * Output: None. + * Side-effects: Sends the appropriate mode changes to other clients + * and propagates to servers. + */ +/* ensure parabuf < MODEBUFLEN -db */ +static void +send_mode_changes(struct Client *client_p, struct Client *source_p, + struct Channel *chptr, char *chname) +{ + int i, mbl, pbl, arglen, nc, mc; + int len; + const char *arg = NULL; + char *parptr; + int dir = MODE_QUERY; + + /* bail out if we have nothing to do... */ + if (!mode_count) + return; + + if (IsServer(source_p)) + mbl = ircsprintf(modebuf, ":%s MODE %s ", (IsHidden(source_p) || + ConfigServerHide.hide_servers) ? + me.name : source_p->name, chname); + else + mbl = ircsprintf(modebuf, ":%s!%s@%s MODE %s ", source_p->name, + source_p->username, source_p->host, chname); + + mc = 0; + nc = 0; + pbl = 0; + + parabuf[0] = '\0'; + parptr = parabuf; + + for (i = 0; i < mode_count; i++) + { + if (mode_changes[i].letter == 0 || + mode_changes[i].mems == NON_CHANOPS || + mode_changes[i].mems == ONLY_SERVERS) + continue; + + arg = mode_changes[i].arg; + if (arg != NULL) + arglen = strlen(arg); + else + arglen = 0; + + if ((mc == MAXMODEPARAMS) || + ((arglen + mbl + pbl + 2) > IRCD_BUFSIZE) || + ((arglen + pbl + BAN_FUDGE) >= MODEBUFLEN)) + { + if (mbl && modebuf[mbl - 1] == '-') + modebuf[mbl - 1] = '\0'; + + if (nc != 0) + sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf); + + nc = 0; + mc = 0; + + if (IsServer(source_p)) + mbl = ircsprintf(modebuf, ":%s MODE %s ", me.name, chname); + else + mbl = ircsprintf(modebuf, ":%s!%s@%s MODE %s ", source_p->name, + source_p->username, source_p->host, chname); + + pbl = 0; + parabuf[0] = '\0'; + parptr = parabuf; + dir = MODE_QUERY; + } + + if (dir != mode_changes[i].dir) + { + modebuf[mbl++] = (mode_changes[i].dir == MODE_ADD) ? '+' : '-'; + dir = mode_changes[i].dir; + } + + modebuf[mbl++] = mode_changes[i].letter; + modebuf[mbl] = '\0'; + nc++; + + if (arg != NULL) + { + len = ircsprintf(parptr, "%s ", arg); + pbl += len; + parptr += len; + mc++; + } + } + + if (pbl && parabuf[pbl - 1] == ' ') + parabuf[pbl - 1] = 0; + + if (nc != 0) + sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf); + + nc = 0; + mc = 0; + + /* Now send to servers... */ + for (i = 0; i < NCHCAP_COMBOS; i++) + if (chcap_combos[i].count != 0) + send_cap_mode_changes(client_p, source_p, chptr, + chcap_combos[i].cap_yes, + chcap_combos[i].cap_no); +} + +/* void set_channel_mode(struct Client *client_p, struct Client *source_p, + * struct Channel *chptr, int parc, char **parv, + * char *chname) + * Input: The client we received this from, the client this originated + * from, the channel, the parameter count starting at the modes, + * the parameters, the channel name. + * Output: None. + * Side-effects: Changes the channel membership and modes appropriately, + * sends the appropriate MODE messages to the appropriate + * clients. + */ +void +set_channel_mode(struct Client *client_p, struct Client *source_p, struct Channel *chptr, + struct Membership *member, int parc, char *parv[], char *chname) +{ + int dir = MODE_ADD; + int parn = 1; + int alevel, errors = 0; + char *ml = parv[0], c; + int table_position; + + mode_count = 0; + mode_limit = 0; + simple_modes_mask = 0; + + alevel = get_channel_access(source_p, member); + + for (; (c = *ml) != '\0'; ml++) + { +#if 0 + if(mode_count > 20) + break; +#endif + switch (c) + { + case '+': + dir = MODE_ADD; + break; + case '-': + dir = MODE_DEL; + break; + case '=': + dir = MODE_QUERY; + break; + default: + if (c < 'A' || c > 'z') + table_position = 0; + else + table_position = c - 'A' + 1; + ModeTable[table_position].func(client_p, source_p, chptr, + parc, &parn, + parv, &errors, alevel, dir, c, + ModeTable[table_position].d, + chname); + break; + } + } + + send_mode_changes(client_p, source_p, chptr, chname); +} diff --git a/src/client.c b/src/client.c new file mode 100644 index 0000000..4341716 --- /dev/null +++ b/src/client.c @@ -0,0 +1,1205 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * client.c: Controls clients. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "channel_mode.h" +#include "event.h" +#include "fdlist.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" +#include "s_gline.h" +#include "numeric.h" +#include "packet.h" +#include "s_auth.h" +#include "s_bsd.h" +#include "conf.h" +#include "log.h" +#include "s_misc.h" +#include "s_serv.h" +#include "send.h" +#include "whowas.h" +#include "s_user.h" +#include "dbuf.h" +#include "memory.h" +#include "hostmask.h" +#include "balloc.h" +#include "listener.h" +#include "irc_res.h" +#include "userhost.h" +#include "watch.h" + +dlink_list listing_client_list = { NULL, NULL, 0 }; +/* Pointer to beginning of Client list */ +dlink_list global_client_list = {NULL, NULL, 0}; +/* unknown/client pointer lists */ +dlink_list unknown_list = {NULL, NULL, 0}; +dlink_list local_client_list = {NULL, NULL, 0}; +dlink_list serv_list = {NULL, NULL, 0}; +dlink_list global_serv_list = {NULL, NULL, 0}; +dlink_list oper_list = {NULL, NULL, 0}; + +static EVH check_pings; + +static BlockHeap *client_heap = NULL; +static BlockHeap *lclient_heap = NULL; + +static dlink_list dead_list = { NULL, NULL, 0}; +static dlink_list abort_list = { NULL, NULL, 0}; + +static dlink_node *eac_next; /* next aborted client to exit */ + +static void check_pings_list(dlink_list *); +static void check_unknowns_list(void); +static void ban_them(struct Client *, struct ConfItem *); + + +/* init_client() + * + * inputs - NONE + * output - NONE + * side effects - initialize client free memory + */ +void +init_client(void) +{ + /* start off the check ping event .. -- adrian + * Every 30 seconds is plenty -- db + */ + client_heap = BlockHeapCreate("client", sizeof(struct Client), CLIENT_HEAP_SIZE); + lclient_heap = BlockHeapCreate("local client", sizeof(struct LocalUser), LCLIENT_HEAP_SIZE); + eventAdd("check_pings", check_pings, NULL, 5); +} + +/* + * make_client - create a new Client struct and set it to initial state. + * + * from == NULL, create local client (a client connected + * to a socket). + * WARNING: This leaves the client in a dangerous + * state where fd == -1, dead flag is not set and + * the client is on the unknown_list; therefore, + * the first thing to do after calling make_client(NULL) + * is setting fd to something reasonable. -adx + * + * from, create remote client (behind a socket + * associated with the client defined by + * 'from'). ('from' is a local client!!). + */ +struct Client * +make_client(struct Client *from) +{ + struct Client *client_p = BlockHeapAlloc(client_heap); + + if (from == NULL) + { + client_p->from = client_p; /* 'from' of local client is self! */ + client_p->localClient = BlockHeapAlloc(lclient_heap); + client_p->localClient->since = CurrentTime; + client_p->localClient->lasttime = CurrentTime; + client_p->localClient->firsttime = CurrentTime; + client_p->localClient->registration = REG_INIT; + + /* as good a place as any... */ + dlinkAdd(client_p, &client_p->localClient->lclient_node, &unknown_list); + } + else + client_p->from = from; /* 'from' of local client is self! */ + + client_p->idhnext = client_p; + client_p->hnext = client_p; + client_p->status = STAT_UNKNOWN; + strcpy(client_p->username, "unknown"); + strcpy(client_p->svid, "0"); + + return client_p; +} + +/* + * free_client + * + * inputs - pointer to client + * output - NONE + * side effects - client pointed to has its memory freed + */ +static void +free_client(struct Client *client_p) +{ + assert(client_p != NULL); + assert(client_p != &me); + assert(client_p->hnext == client_p); + assert(client_p->idhnext == client_p); + assert(client_p->channel.head == NULL); + assert(dlink_list_length(&client_p->channel) == 0); + assert(dlink_list_length(&client_p->whowas) == 0); + assert(!IsServer(client_p) || IsServer(client_p) && client_p->serv); + + MyFree(client_p->serv); + + if (MyConnect(client_p)) + { + assert(client_p->localClient->invited.head == NULL); + assert(dlink_list_length(&client_p->localClient->invited) == 0); + assert(dlink_list_length(&client_p->localClient->watches) == 0); + assert(IsClosing(client_p) && IsDead(client_p)); + + MyFree(client_p->localClient->response); + MyFree(client_p->localClient->auth_oper); + + /* + * clean up extra sockets from P-lines which have been discarded. + */ + if (client_p->localClient->listener) + { + assert(0 < client_p->localClient->listener->ref_count); + if (0 == --client_p->localClient->listener->ref_count && + !client_p->localClient->listener->active) + free_listener(client_p->localClient->listener); + } + + dbuf_clear(&client_p->localClient->buf_recvq); + dbuf_clear(&client_p->localClient->buf_sendq); + + BlockHeapFree(lclient_heap, client_p->localClient); + } + + BlockHeapFree(client_heap, client_p); +} + +/* + * check_pings - go through the local client list and check activity + * kill off stuff that should die + * + * inputs - NOT USED (from event) + * output - next time_t when check_pings() should be called again + * side effects - + * + * + * A PING can be sent to clients as necessary. + * + * Client/Server ping outs are handled. + */ + +/* + * Addon from adrian. We used to call this after nextping seconds, + * however I've changed it to run once a second. This is only for + * PING timeouts, not K/etc-line checks (thanks dianora!). Having it + * run once a second makes life a lot easier - when a new client connects + * and they need a ping in 4 seconds, if nextping was set to 20 seconds + * we end up waiting 20 seconds. This is stupid. :-) + * I will optimise (hah!) check_pings() once I've finished working on + * tidying up other network IO evilnesses. + * -- adrian + */ + +static void +check_pings(void *notused) +{ + check_pings_list(&local_client_list); + check_pings_list(&serv_list); + check_unknowns_list(); +} + +/* check_pings_list() + * + * inputs - pointer to list to check + * output - NONE + * side effects - + */ +static void +check_pings_list(dlink_list *list) +{ + char scratch[32]; /* way too generous but... */ + struct Client *client_p; /* current local client_p being examined */ + int ping, pingwarn; /* ping time value from client */ + dlink_node *ptr, *next_ptr; + + DLINK_FOREACH_SAFE(ptr, next_ptr, list->head) + { + client_p = ptr->data; + + /* + ** Note: No need to notify opers here. It's + ** already done when "FLAGS_DEADSOCKET" is set. + */ + if (IsDead(client_p)) + { + /* Ignore it, its been exited already */ + continue; + } + + if (!IsRegistered(client_p)) + ping = CONNECTTIMEOUT, pingwarn = 0; + else + ping = get_client_ping(client_p, &pingwarn); + + if (ping < CurrentTime - client_p->localClient->lasttime) + { + if (!IsPingSent(client_p)) + { + /* + * if we havent PINGed the connection and we havent + * heard from it in a while, PING it to make sure + * it is still alive. + */ + SetPingSent(client_p); + ClearPingWarning(client_p); + client_p->localClient->lasttime = CurrentTime - ping; + sendto_one(client_p, "PING :%s", ID_or_name(&me, client_p)); + } + else + { + if (CurrentTime - client_p->localClient->lasttime >= 2 * ping) + { + /* + * If the client/server hasn't talked to us in 2*ping seconds + * and it has a ping time, then close its connection. + */ + if (IsServer(client_p) || IsHandshake(client_p)) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "No response from %s, closing link", + get_client_name(client_p, HIDE_IP)); + sendto_realops_flags(UMODE_ALL, L_OPER, + "No response from %s, closing link", + get_client_name(client_p, MASK_IP)); + ilog(LOG_TYPE_IRCD, "No response from %s, closing link", + get_client_name(client_p, HIDE_IP)); + } + + snprintf(scratch, sizeof(scratch), "Ping timeout: %d seconds", + (int)(CurrentTime - client_p->localClient->lasttime)); + exit_client(client_p, &me, scratch); + } + else if (!IsPingWarning(client_p) && pingwarn > 0 && + (IsServer(client_p) || IsHandshake(client_p)) && + CurrentTime - client_p->localClient->lasttime >= ping + pingwarn) + { + /* + * If the server hasn't replied in pingwarn seconds after sending + * the PING, notify the opers so that they are aware of the problem. + */ + SetPingWarning(client_p); + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Warning, no response from %s in %d seconds", + get_client_name(client_p, HIDE_IP), pingwarn); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Warning, no response from %s in %d seconds", + get_client_name(client_p, MASK_IP), pingwarn); + ilog(LOG_TYPE_IRCD, "No response from %s in %d seconds", + get_client_name(client_p, HIDE_IP), pingwarn); + } + } + } + } +} + +/* check_unknowns_list() + * + * inputs - pointer to list of unknown clients + * output - NONE + * side effects - unknown clients get marked for termination after n seconds + */ +static void +check_unknowns_list(void) +{ + dlink_node *ptr, *next_ptr; + + DLINK_FOREACH_SAFE(ptr, next_ptr, unknown_list.head) + { + struct Client *client_p = ptr->data; + + /* + * Check UNKNOWN connections - if they have been in this state + * for > 30s, close them. + */ + if (IsAuthFinished(client_p) && (CurrentTime - client_p->localClient->firsttime) > 30) + exit_client(client_p, &me, "Registration timed out"); + } +} + +/* check_conf_klines() + * + * inputs - NONE + * output - NONE + * side effects - Check all connections for a pending kline against the + * client, exit the client if a kline matches. + */ +void +check_conf_klines(void) +{ + struct Client *client_p = NULL; /* current local client_p being examined */ + struct AccessItem *aconf = NULL; + struct ConfItem *conf = NULL; + dlink_node *ptr, *next_ptr; + + DLINK_FOREACH_SAFE(ptr, next_ptr, local_client_list.head) + { + client_p = ptr->data; + + /* If a client is already being exited + */ + if (IsDead(client_p) || !IsClient(client_p)) + continue; + + /* if there is a returned struct ConfItem then kill it */ + if ((aconf = find_dline_conf(&client_p->localClient->ip, + client_p->localClient->aftype)) != NULL) + { + if (aconf->status & CONF_EXEMPTDLINE) + continue; + + conf = unmap_conf_item(aconf); + ban_them(client_p, conf); + continue; /* and go examine next fd/client_p */ + } + + if (ConfigFileEntry.glines && (aconf = find_gline(client_p))) + { + if (IsExemptKline(client_p) || + IsExemptGline(client_p)) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "GLINE over-ruled for %s, client is %sline_exempt", + get_client_name(client_p, HIDE_IP), IsExemptKline(client_p) ? "k" : "g"); + continue; + } + + conf = unmap_conf_item(aconf); + ban_them(client_p, conf); + /* and go examine next fd/client_p */ + continue; + } + + if ((aconf = find_kill(client_p)) != NULL) + { + + /* if there is a returned struct AccessItem.. then kill it */ + if (IsExemptKline(client_p)) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "KLINE over-ruled for %s, client is kline_exempt", + get_client_name(client_p, HIDE_IP)); + continue; + } + + conf = unmap_conf_item(aconf); + ban_them(client_p, conf); + continue; + } + + /* if there is a returned struct MatchItem then kill it */ + if ((conf = find_matching_name_conf(XLINE_TYPE, client_p->info, + NULL, NULL, 0)) != NULL || + (conf = find_matching_name_conf(RXLINE_TYPE, client_p->info, + NULL, NULL, 0)) != NULL) + { + ban_them(client_p, conf); + continue; + } + } + + /* also check the unknowns list for new dlines */ + DLINK_FOREACH_SAFE(ptr, next_ptr, unknown_list.head) + { + client_p = ptr->data; + + if ((aconf = find_dline_conf(&client_p->localClient->ip, + client_p->localClient->aftype))) + { + if (aconf->status & CONF_EXEMPTDLINE) + continue; + + exit_client(client_p, &me, "D-lined"); + } + } +} + +/* + * ban_them + * + * inputs - pointer to client to ban + * - pointer to ConfItem + * output - NONE + * side effects - given client_p is banned + */ +static void +ban_them(struct Client *client_p, struct ConfItem *conf) +{ + const char *user_reason = NULL; /* What is sent to user */ + struct AccessItem *aconf = NULL; + struct MatchItem *xconf = NULL; + const char *type_string = NULL; + const char dline_string[] = "D-line"; + const char kline_string[] = "K-line"; + const char gline_string[] = "G-line"; + const char xline_string[] = "X-line"; + + switch (conf->type) + { + case RKLINE_TYPE: + case KLINE_TYPE: + type_string = kline_string; + aconf = map_to_conf(conf); + break; + case DLINE_TYPE: + type_string = dline_string; + aconf = map_to_conf(conf); + break; + case GLINE_TYPE: + type_string = gline_string; + aconf = map_to_conf(conf); + break; + case RXLINE_TYPE: + case XLINE_TYPE: + type_string = xline_string; + xconf = map_to_conf(conf); + ++xconf->count; + break; + default: + assert(0); + break; + } + + if (aconf != NULL) + user_reason = aconf->reason ? aconf->reason : type_string; + if (xconf != NULL) + user_reason = xconf->reason ? xconf->reason : type_string; + + sendto_realops_flags(UMODE_ALL, L_ALL, "%s active for %s", + type_string, get_client_name(client_p, HIDE_IP)); + + if (IsClient(client_p)) + sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP), + me.name, client_p->name, user_reason); + + exit_client(client_p, &me, user_reason); +} + +/* update_client_exit_stats() + * + * input - pointer to client + * output - NONE + * side effects - + */ +static void +update_client_exit_stats(struct Client *client_p) +{ + if (IsClient(client_p)) + { + assert(Count.total > 0); + --Count.total; + if (HasUMode(client_p, UMODE_OPER)) + --Count.oper; + if (HasUMode(client_p, UMODE_INVISIBLE)) + --Count.invisi; + } + else if (IsServer(client_p)) + sendto_realops_flags(UMODE_EXTERNAL, L_ALL, "Server %s split from %s", + client_p->name, client_p->servptr->name); + + if (splitchecking && !splitmode) + check_splitmode(NULL); +} + +/* find_person() + * + * inputs - pointer to name + * output - return client pointer + * side effects - find person by (nick)name + */ +struct Client * +find_person(const struct Client *client_p, const char *name) +{ + struct Client *c2ptr = NULL; + + if (IsDigit(*name)) + { + if ((c2ptr = hash_find_id(name)) != NULL) + { + /* invisible users shall not be found by UID guessing */ + if (HasUMode(c2ptr, UMODE_INVISIBLE)) + if (!IsServer(client_p) && !HasFlag(client_p, FLAGS_SERVICE)) + c2ptr = NULL; + } + } + else + c2ptr = hash_find_client(name); + + return ((c2ptr != NULL && IsClient(c2ptr)) ? c2ptr : NULL); +} + +/* + * find_chasing - find the client structure for a nick name (user) + * using history mechanism if necessary. If the client is not found, + * an error message (NO SUCH NICK) is generated. If the client was found + * through the history, chasing will be 1 and otherwise 0. + */ +struct Client * +find_chasing(struct Client *client_p, struct Client *source_p, const char *user, int *chasing) +{ + struct Client *who = find_person(client_p, user); + + if (chasing) + *chasing = 0; + + if (who) + return who; + + if (IsDigit(*user)) + return NULL; + + if ((who = get_history(user, + (time_t)ConfigFileEntry.kill_chase_time_limit)) + == NULL) + { + sendto_one(source_p, form_str(ERR_NOSUCHNICK), + me.name, source_p->name, user); + return NULL; + } + + if (chasing) + *chasing = 1; + + return who; +} + +/* + * get_client_name - Return the name of the client + * for various tracking and + * admin purposes. The main purpose of this function is to + * return the "socket host" name of the client, if that + * differs from the advertised name (other than case). + * But, this can be used to any client structure. + * + * NOTE 1: + * Watch out the allocation of "nbuf", if either source_p->name + * or source_p->sockhost gets changed into pointers instead of + * directly allocated within the structure... + * + * NOTE 2: + * Function return either a pointer to the structure (source_p) or + * to internal buffer (nbuf). *NEVER* use the returned pointer + * to modify what it points!!! + */ +const char * +get_client_name(const struct Client *client, enum addr_mask_type type) +{ + static char nbuf[HOSTLEN * 2 + USERLEN + 5]; + + assert(client != NULL); + + if (!MyConnect(client)) + return client->name; + + if (IsServer(client) || IsConnecting(client) || IsHandshake(client)) + { + if (!irccmp(client->name, client->host)) + return client->name; + else if (ConfigServerHide.hide_server_ips) + type = MASK_IP; + } + + if (ConfigFileEntry.hide_spoof_ips) + if (type == SHOW_IP && IsIPSpoof(client)) + type = MASK_IP; + + /* And finally, let's get the host information, ip or name */ + switch (type) + { + case SHOW_IP: + snprintf(nbuf, sizeof(nbuf), "%s[%s@%s]", + client->name, + client->username, client->sockhost); + break; + case MASK_IP: + if (client->localClient->aftype == AF_INET) + snprintf(nbuf, sizeof(nbuf), "%s[%s@255.255.255.255]", + client->name, client->username); + else + snprintf(nbuf, sizeof(nbuf), "%s[%s@ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]", + client->name, client->username); + break; + default: + snprintf(nbuf, sizeof(nbuf), "%s[%s@%s]", + client->name, + client->username, client->host); + } + + return nbuf; +} + +void +free_exited_clients(void) +{ + dlink_node *ptr = NULL, *next = NULL; + + DLINK_FOREACH_SAFE(ptr, next, dead_list.head) + { + free_client(ptr->data); + dlinkDelete(ptr, &dead_list); + free_dlink_node(ptr); + } +} + +/* + * Exit one client, local or remote. Assuming all dependents have + * been already removed, and socket closed for local client. + * + * The only messages generated are QUITs on channels. + */ +static void +exit_one_client(struct Client *source_p, const char *quitmsg) +{ + dlink_node *lp = NULL, *next_lp = NULL; + + assert(!IsMe(source_p)); + + if (IsClient(source_p)) + { + if (source_p->servptr->serv != NULL) + dlinkDelete(&source_p->lnode, &source_p->servptr->serv->client_list); + + /* + * If a person is on a channel, send a QUIT notice + * to every client (person) on the same channel (so + * that the client can show the "**signoff" message). + * (Note: The notice is to the local clients *only*) + */ + sendto_common_channels_local(source_p, 0, ":%s!%s@%s QUIT :%s", + source_p->name, source_p->username, + source_p->host, quitmsg); + DLINK_FOREACH_SAFE(lp, next_lp, source_p->channel.head) + remove_user_from_channel(lp->data); + + add_history(source_p, 0); + off_history(source_p); + + watch_check_hash(source_p, RPL_LOGOFF); + + if (MyConnect(source_p)) + { + /* Clean up invitefield */ + DLINK_FOREACH_SAFE(lp, next_lp, source_p->localClient->invited.head) + del_invite(lp->data, source_p); + + del_all_accepts(source_p); + } + } + else if (IsServer(source_p)) + { + dlinkDelete(&source_p->lnode, &source_p->servptr->serv->server_list); + + if ((lp = dlinkFindDelete(&global_serv_list, source_p)) != NULL) + free_dlink_node(lp); + } + + /* Remove source_p from the client lists */ + if (HasID(source_p)) + hash_del_id(source_p); + if (source_p->name[0]) + hash_del_client(source_p); + + if (IsUserHostIp(source_p)) + delete_user_host(source_p->username, source_p->host, !MyConnect(source_p)); + + /* remove from global client list + * NOTE: source_p->node.next cannot be NULL if the client is added + * to global_client_list (there is always &me at its end) + */ + if (source_p != NULL && source_p->node.next != NULL) + dlinkDelete(&source_p->node, &global_client_list); + + update_client_exit_stats(source_p); + + /* Check to see if the client isn't already on the dead list */ + assert(dlinkFind(&dead_list, source_p) == NULL); + + /* add to dead client dlist */ + SetDead(source_p); + dlinkAdd(source_p, make_dlink_node(), &dead_list); +} + +/* Recursively send QUITs and SQUITs for source_p and all its dependent clients + * and servers to those servers that need them. A server needs the client + * QUITs if it can't figure them out from the SQUIT (ie pre-TS4) or if it + * isn't getting the SQUIT because of @#(*&@)# hostmasking. With TS4, once + * a link gets a SQUIT, it doesn't need any QUIT/SQUITs for clients depending + * on that one -orabidoo + * + * This is now called on each local server -adx + */ +static void +recurse_send_quits(struct Client *original_source_p, struct Client *source_p, + struct Client *from, struct Client *to, const char *comment, + const char *splitstr) +{ + dlink_node *ptr, *next; + struct Client *target_p; + + assert(to != source_p); /* should be already removed from serv_list */ + + /* If this server can handle quit storm (QS) removal + * of dependents, just send the SQUIT + */ + if (!IsCapable(to, CAP_QS)) + DLINK_FOREACH_SAFE(ptr, next, source_p->serv->client_list.head) + { + target_p = ptr->data; + sendto_one(to, ":%s QUIT :%s", target_p->name, splitstr); + } + + DLINK_FOREACH_SAFE(ptr, next, source_p->serv->server_list.head) + recurse_send_quits(original_source_p, ptr->data, from, to, + comment, splitstr); + + if ((source_p == original_source_p && to != from) || + !IsCapable(to, CAP_QS)) + { + /* don't use a prefix here - we have to be 100% sure the message + * will be accepted without Unknown prefix etc.. */ + sendto_one(to, "SQUIT %s :%s", ID_or_name(source_p, to), comment); + } +} + +/* + * Remove all clients that depend on source_p; assumes all (S)QUITs have + * already been sent. we make sure to exit a server's dependent clients + * and servers before the server itself; exit_one_client takes care of + * actually removing things off llists. tweaked from +CSr31 -orabidoo + */ +static void +recurse_remove_clients(struct Client *source_p, const char *quitmsg) +{ + dlink_node *ptr, *next; + + DLINK_FOREACH_SAFE(ptr, next, source_p->serv->client_list.head) + exit_one_client(ptr->data, quitmsg); + + DLINK_FOREACH_SAFE(ptr, next, source_p->serv->server_list.head) + { + recurse_remove_clients(ptr->data, quitmsg); + exit_one_client(ptr->data, quitmsg); + } +} + +/* +** Remove *everything* that depends on source_p, from all lists, and sending +** all necessary QUITs and SQUITs. source_p itself is still on the lists, +** and its SQUITs have been sent except for the upstream one -orabidoo +*/ +static void +remove_dependents(struct Client *source_p, struct Client *from, + const char *comment, const char *splitstr) +{ + dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, serv_list.head) + recurse_send_quits(source_p, source_p, from, ptr->data, + comment, splitstr); + + recurse_remove_clients(source_p, splitstr); +} + +/* + * exit_client - exit a client of any type. Generally, you can use + * this on any struct Client, regardless of its state. + * + * Note, you shouldn't exit remote _users_ without first doing + * AddFlag(x, FLAGS_KILLED) and propagating a kill or similar message. + * However, it is perfectly correct to call exit_client to force a _server_ + * quit (either local or remote one). + * + * inputs: - a client pointer that is going to be exited + * - for servers, the second argument is a pointer to who + * is firing the server. This side won't get any generated + * messages. NEVER NULL! + * output: none + * side effects: the client is delinked from all lists, disconnected, + * and the rest of IRC network is notified of the exit. + * Client memory is scheduled to be freed + */ +void +exit_client(struct Client *source_p, struct Client *from, const char *comment) +{ + dlink_node *m = NULL; + + if (MyConnect(source_p)) + { + /* DO NOT REMOVE. exit_client can be called twice after a failed + * read/write. + */ + if (IsClosing(source_p)) + return; + + SetClosing(source_p); + + if (IsIpHash(source_p)) + remove_one_ip(&source_p->localClient->ip); + + if (source_p->localClient->auth) + { + delete_auth(source_p->localClient->auth); + source_p->localClient->auth = NULL; + } + + /* + * This source_p could have status of one of STAT_UNKNOWN, STAT_CONNECTING + * STAT_HANDSHAKE or STAT_UNKNOWN + * all of which are lumped together into unknown_list + * + * In all above cases IsRegistered() will not be true. + */ + if (!IsRegistered(source_p)) + { + assert(dlinkFind(&unknown_list, source_p)); + + dlinkDelete(&source_p->localClient->lclient_node, &unknown_list); + } + else if (IsClient(source_p)) + { + time_t on_for = CurrentTime - source_p->localClient->firsttime; + assert(Count.local > 0); + Count.local--; + + if (HasUMode(source_p, UMODE_OPER)) + if ((m = dlinkFindDelete(&oper_list, source_p)) != NULL) + free_dlink_node(m); + + assert(dlinkFind(&local_client_list, source_p)); + dlinkDelete(&source_p->localClient->lclient_node, &local_client_list); + + if (source_p->localClient->list_task != NULL) + free_list_task(source_p->localClient->list_task, source_p); + + watch_del_watch_list(source_p); + sendto_realops_flags(UMODE_CCONN, L_ALL, "Client exiting: %s (%s@%s) [%s] [%s]", + source_p->name, source_p->username, source_p->host, comment, + ConfigFileEntry.hide_spoof_ips && IsIPSpoof(source_p) ? + "255.255.255.255" : source_p->sockhost); + sendto_realops_flags(UMODE_CCONN_FULL, L_ALL, "CLIEXIT: %s %s %s %s 0 %s", + source_p->name, + source_p->username, + source_p->host, + ConfigFileEntry.hide_spoof_ips && IsIPSpoof(source_p) ? + "255.255.255.255" : source_p->sockhost, + comment); + ilog(LOG_TYPE_USER, "%s (%3u:%02u:%02u): %s!%s@%s %llu/%llu", + myctime(source_p->localClient->firsttime), (unsigned int)(on_for / 3600), + (unsigned int)((on_for % 3600)/60), (unsigned int)(on_for % 60), + source_p->name, source_p->username, source_p->host, + source_p->localClient->send.bytes>>10, + source_p->localClient->recv.bytes>>10); + } + else if (IsServer(source_p)) + { + assert(Count.myserver > 0); + --Count.myserver; + + assert(dlinkFind(&serv_list, source_p)); + dlinkDelete(&source_p->localClient->lclient_node, &serv_list); + unset_chcap_usage_counts(source_p); + } + + if (!IsDead(source_p)) + { + if (IsServer(source_p)) + { + /* for them, we are exiting the network */ + sendto_one(source_p, ":%s SQUIT %s :%s", + ID_or_name(from, source_p), me.name, comment); + } + + sendto_one(source_p, "ERROR :Closing Link: %s (%s)", + source_p->host, comment); + } + + /* + ** Currently only server connections can have + ** depending remote clients here, but it does no + ** harm to check for all local clients. In + ** future some other clients than servers might + ** have remotes too... + ** + ** Close the Client connection first and mark it + ** so that no messages are attempted to send to it. + ** Remember it makes source_p->from == NULL. + */ + close_connection(source_p); + } + + if (IsServer(source_p)) + { + char splitstr[HOSTLEN + HOSTLEN + 2]; + + /* This shouldn't ever happen */ + assert(source_p->serv != NULL && source_p->servptr != NULL); + + if (ConfigServerHide.hide_servers) + /* + * Set netsplit message to "*.net *.split" to still show + * that its a split, but hide the servers splitting + */ + strcpy(splitstr, "*.net *.split"); + else + snprintf(splitstr, sizeof(splitstr), "%s %s", + source_p->servptr->name, source_p->name); + + remove_dependents(source_p, from->from, comment, splitstr); + + if (source_p->servptr == &me) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s was connected for %d seconds. %llu/%llu sendK/recvK.", + source_p->name, (int)(CurrentTime - source_p->localClient->firsttime), + source_p->localClient->send.bytes >> 10, + source_p->localClient->recv.bytes >> 10); + ilog(LOG_TYPE_IRCD, "%s was connected for %d seconds. %llu/%llu sendK/recvK.", + source_p->name, (int)(CurrentTime - source_p->localClient->firsttime), + source_p->localClient->send.bytes >> 10, + source_p->localClient->recv.bytes >> 10); + } + } + else if (IsClient(source_p) && !HasFlag(source_p, FLAGS_KILLED)) + { + sendto_server(from->from, CAP_TS6, NOCAPS, + ":%s QUIT :%s", ID(source_p), comment); + sendto_server(from->from, NOCAPS, CAP_TS6, + ":%s QUIT :%s", source_p->name, comment); + } + + /* The client *better* be off all of the lists */ + assert(dlinkFind(&unknown_list, source_p) == NULL); + assert(dlinkFind(&local_client_list, source_p) == NULL); + assert(dlinkFind(&serv_list, source_p) == NULL); + assert(dlinkFind(&oper_list, source_p) == NULL); + + exit_one_client(source_p, comment); +} + +/* + * dead_link_on_write - report a write error if not already dead, + * mark it as dead then exit it + */ +void +dead_link_on_write(struct Client *client_p, int ierrno) +{ + dlink_node *ptr; + + if (IsDefunct(client_p)) + return; + + dbuf_clear(&client_p->localClient->buf_recvq); + dbuf_clear(&client_p->localClient->buf_sendq); + + assert(dlinkFind(&abort_list, client_p) == NULL); + ptr = make_dlink_node(); + /* don't let exit_aborted_clients() finish yet */ + dlinkAddTail(client_p, ptr, &abort_list); + + if (eac_next == NULL) + eac_next = ptr; + + SetDead(client_p); /* You are dead my friend */ +} + +/* + * dead_link_on_read - report a read error if not already dead, + * mark it as dead then exit it + */ +void +dead_link_on_read(struct Client *client_p, int error) +{ + char errmsg[255]; + int current_error; + + if (IsDefunct(client_p)) + return; + + dbuf_clear(&client_p->localClient->buf_recvq); + dbuf_clear(&client_p->localClient->buf_sendq); + + current_error = get_sockerr(client_p->localClient->fd.fd); + + if (IsServer(client_p) || IsHandshake(client_p)) + { + int connected = CurrentTime - client_p->localClient->firsttime; + + if (error == 0) + { + /* Admins get the real IP */ + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Server %s closed the connection", + get_client_name(client_p, SHOW_IP)); + + /* Opers get a masked IP */ + sendto_realops_flags(UMODE_ALL, L_OPER, + "Server %s closed the connection", + get_client_name(client_p, MASK_IP)); + + ilog(LOG_TYPE_IRCD, "Server %s closed the connection", + get_client_name(client_p, SHOW_IP)); + } + else + { + report_error(L_ADMIN, "Lost connection to %s: %s", + get_client_name(client_p, SHOW_IP), current_error); + report_error(L_OPER, "Lost connection to %s: %s", + get_client_name(client_p, MASK_IP), current_error); + } + + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s had been connected for %d day%s, %2d:%02d:%02d", + client_p->name, connected/86400, + (connected/86400 == 1) ? "" : "s", + (connected % 86400) / 3600, (connected % 3600) / 60, + connected % 60); + } + + if (error == 0) + strlcpy(errmsg, "Remote host closed the connection", + sizeof(errmsg)); + else + snprintf(errmsg, sizeof(errmsg), "Read error: %s", + strerror(current_error)); + + exit_client(client_p, &me, errmsg); +} + +void +exit_aborted_clients(void) +{ + dlink_node *ptr; + struct Client *target_p; + const char *notice; + + DLINK_FOREACH_SAFE(ptr, eac_next, abort_list.head) + { + target_p = ptr->data; + eac_next = ptr->next; + + if (target_p == NULL) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "Warning: null client on abort_list!"); + dlinkDelete(ptr, &abort_list); + free_dlink_node(ptr); + continue; + } + + dlinkDelete(ptr, &abort_list); + + if (IsSendQExceeded(target_p)) + notice = "Max SendQ exceeded"; + else + notice = "Write error: connection closed"; + + exit_client(target_p, &me, notice); + free_dlink_node(ptr); + } +} + +/* + * accept processing, this adds a form of "caller ID" to ircd + * + * If a client puts themselves into "caller ID only" mode, + * only clients that match a client pointer they have put on + * the accept list will be allowed to message them. + * + * Diane Bruce, "Dianora" db@db.net + */ + +void +del_accept(struct split_nuh_item *accept_p, struct Client *client_p) +{ + dlinkDelete(&accept_p->node, &client_p->localClient->acceptlist); + + MyFree(accept_p->nickptr); + MyFree(accept_p->userptr); + MyFree(accept_p->hostptr); + MyFree(accept_p); +} + +struct split_nuh_item * +find_accept(const char *nick, const char *user, + const char *host, struct Client *client_p, int do_match) +{ + dlink_node *ptr = NULL; + /* XXX We wouldn't need that if match() would return 0 on match */ + int (*cmpfunc)(const char *, const char *) = do_match ? match : irccmp; + + DLINK_FOREACH(ptr, client_p->localClient->acceptlist.head) + { + struct split_nuh_item *accept_p = ptr->data; + + if (cmpfunc(accept_p->nickptr, nick) == do_match && + cmpfunc(accept_p->userptr, user) == do_match && + cmpfunc(accept_p->hostptr, host) == do_match) + return accept_p; + } + + return NULL; +} + +/* accept_message() + * + * inputs - pointer to source client + * - pointer to target client + * output - 1 if accept this message 0 if not + * side effects - See if source is on target's allow list + */ +int +accept_message(struct Client *source, + struct Client *target) +{ + dlink_node *ptr = NULL; + + if (source == target || find_accept(source->name, source->username, + source->host, target, 1)) + return 1; + + if (HasUMode(target, UMODE_SOFTCALLERID)) + DLINK_FOREACH(ptr, target->channel.head) + if (IsMember(source, ((struct Membership *)ptr->data)->chptr)) + return 1; + + return 0; +} + +/* del_all_accepts() + * + * inputs - pointer to exiting client + * output - NONE + * side effects - Walk through given clients acceptlist and remove all entries + */ +void +del_all_accepts(struct Client *client_p) +{ + dlink_node *ptr = NULL, *next_ptr = NULL; + + DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->acceptlist.head) + del_accept(ptr->data, client_p); +} diff --git a/src/conf.c b/src/conf.c new file mode 100644 index 0000000..b5adf94 --- /dev/null +++ b/src/conf.c @@ -0,0 +1,3622 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * conf.c: Configuration file functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "ircd_defs.h" +#include "balloc.h" +#include "conf.h" +#include "s_serv.h" +#include "resv.h" +#include "channel.h" +#include "client.h" +#include "event.h" +#include "hook.h" +#include "irc_string.h" +#include "s_bsd.h" +#include "ircd.h" +#include "listener.h" +#include "hostmask.h" +#include "modules.h" +#include "numeric.h" +#include "fdlist.h" +#include "log.h" +#include "send.h" +#include "s_gline.h" +#include "memory.h" +#include "irc_res.h" +#include "userhost.h" +#include "s_user.h" +#include "channel_mode.h" +#include "parse.h" +#include "s_misc.h" + +struct Callback *client_check_cb = NULL; +struct config_server_hide ConfigServerHide; + +/* general conf items link list root, other than k lines etc. */ +dlink_list service_items = { NULL, NULL, 0 }; +dlink_list server_items = { NULL, NULL, 0 }; +dlink_list cluster_items = { NULL, NULL, 0 }; +dlink_list oconf_items = { NULL, NULL, 0 }; +dlink_list uconf_items = { NULL, NULL, 0 }; +dlink_list xconf_items = { NULL, NULL, 0 }; +dlink_list rxconf_items = { NULL, NULL, 0 }; +dlink_list rkconf_items = { NULL, NULL, 0 }; +dlink_list nresv_items = { NULL, NULL, 0 }; +dlink_list class_items = { NULL, NULL, 0 }; + +dlink_list temporary_xlines = { NULL, NULL, 0 }; +dlink_list temporary_resv = { NULL, NULL, 0 }; + +extern unsigned int lineno; +extern char linebuf[]; +extern char conffilebuf[IRCD_BUFSIZE]; +extern int yyparse(); /* defined in y.tab.c */ + +struct conf_parser_context conf_parser_ctx = { 0, 0, NULL }; + +/* internally defined functions */ +static void read_conf(FILE *); +static void clear_out_old_conf(void); +static void flush_deleted_I_P(void); +static void expire_tklines(dlink_list *); +static void garbage_collect_ip_entries(void); +static int hash_ip(struct irc_ssaddr *); +static int verify_access(struct Client *, const char *); +static int attach_iline(struct Client *, struct ConfItem *); +static struct ip_entry *find_or_add_ip(struct irc_ssaddr *); +static void parse_conf_file(int, int); +static dlink_list *map_to_list(ConfType); +static struct AccessItem *find_regexp_kline(const char *[]); +static int find_user_host(struct Client *, char *, char *, char *, unsigned int); + +/* + * bit_len + */ +static int cidr_limit_reached(int, struct irc_ssaddr *, struct ClassItem *); +static void remove_from_cidr_check(struct irc_ssaddr *, struct ClassItem *); +static void destroy_cidr_class(struct ClassItem *); + +static void flags_to_ascii(unsigned int, const unsigned int[], char *, int); + +/* address of default class conf */ +static struct ConfItem *class_default; + +/* usually, with hash tables, you use a prime number... + * but in this case I am dealing with ip addresses, + * not ascii strings. + */ +#define IP_HASH_SIZE 0x1000 + +struct ip_entry +{ + struct irc_ssaddr ip; + int count; + time_t last_attempt; + struct ip_entry *next; +}; + +static struct ip_entry *ip_hash_table[IP_HASH_SIZE]; +static BlockHeap *ip_entry_heap = NULL; +static int ip_entries_count = 0; + + +void * +map_to_conf(struct ConfItem *aconf) +{ + void *conf; + conf = (void *)((uintptr_t)aconf + + (uintptr_t)sizeof(struct ConfItem)); + return(conf); +} + +struct ConfItem * +unmap_conf_item(void *aconf) +{ + struct ConfItem *conf; + + conf = (struct ConfItem *)((uintptr_t)aconf - + (uintptr_t)sizeof(struct ConfItem)); + return(conf); +} + +/* conf_dns_callback() + * + * inputs - pointer to struct AccessItem + * - pointer to DNSReply reply + * output - none + * side effects - called when resolver query finishes + * if the query resulted in a successful search, hp will contain + * a non-null pointer, otherwise hp will be null. + * if successful save hp in the conf item it was called with + */ +static void +conf_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name) +{ + struct AccessItem *aconf = vptr; + + aconf->dns_pending = 0; + + if (addr != NULL) + memcpy(&aconf->addr, addr, sizeof(aconf->addr)); + else + aconf->dns_failed = 1; +} + +/* conf_dns_lookup() + * + * do a nameserver lookup of the conf host + * if the conf entry is currently doing a ns lookup do nothing, otherwise + * allocate a dns_query and start ns lookup. + */ +static void +conf_dns_lookup(struct AccessItem *aconf) +{ + if (!aconf->dns_pending) + { + aconf->dns_pending = 1; + gethost_byname(conf_dns_callback, aconf, aconf->host); + } +} + +/* make_conf_item() + * + * inputs - type of item + * output - pointer to new conf entry + * side effects - none + */ +struct ConfItem * +make_conf_item(ConfType type) +{ + struct ConfItem *conf = NULL; + struct AccessItem *aconf = NULL; + struct ClassItem *aclass = NULL; + int status = 0; + + switch (type) + { + case DLINE_TYPE: + case EXEMPTDLINE_TYPE: + case GLINE_TYPE: + case KLINE_TYPE: + case CLIENT_TYPE: + case OPER_TYPE: + case SERVER_TYPE: + conf = MyMalloc(sizeof(struct ConfItem) + + sizeof(struct AccessItem)); + aconf = map_to_conf(conf); + aconf->aftype = AF_INET; + + /* Yes, sigh. switch on type again */ + switch (type) + { + case EXEMPTDLINE_TYPE: + status = CONF_EXEMPTDLINE; + break; + + case DLINE_TYPE: + status = CONF_DLINE; + break; + + case KLINE_TYPE: + status = CONF_KLINE; + break; + + case GLINE_TYPE: + status = CONF_GLINE; + break; + + case CLIENT_TYPE: + status = CONF_CLIENT; + break; + + case OPER_TYPE: + status = CONF_OPERATOR; + dlinkAdd(conf, &conf->node, &oconf_items); + break; + + case SERVER_TYPE: + status = CONF_SERVER; + dlinkAdd(conf, &conf->node, &server_items); + break; + + default: + break; + } + aconf->status = status; + break; + + case ULINE_TYPE: + conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) + + sizeof(struct MatchItem)); + dlinkAdd(conf, &conf->node, &uconf_items); + break; + + case XLINE_TYPE: + conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) + + sizeof(struct MatchItem)); + dlinkAdd(conf, &conf->node, &xconf_items); + break; +#ifdef HAVE_LIBPCRE + case RXLINE_TYPE: + conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) + + sizeof(struct MatchItem)); + dlinkAdd(conf, &conf->node, &rxconf_items); + break; + + case RKLINE_TYPE: + conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) + + sizeof(struct AccessItem)); + aconf = map_to_conf(conf); + aconf->status = CONF_KLINE; + dlinkAdd(conf, &conf->node, &rkconf_items); + break; +#endif + case CLUSTER_TYPE: + conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem)); + dlinkAdd(conf, &conf->node, &cluster_items); + break; + + case CRESV_TYPE: + conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) + + sizeof(struct ResvChannel)); + break; + + case NRESV_TYPE: + conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) + + sizeof(struct MatchItem)); + dlinkAdd(conf, &conf->node, &nresv_items); + break; + + case SERVICE_TYPE: + status = CONF_SERVICE; + conf = MyMalloc(sizeof(struct ConfItem)); + dlinkAdd(conf, &conf->node, &service_items); + break; + + case CLASS_TYPE: + conf = MyMalloc(sizeof(struct ConfItem) + + sizeof(struct ClassItem)); + dlinkAdd(conf, &conf->node, &class_items); + + aclass = map_to_conf(conf); + aclass->active = 1; + aclass->con_freq = DEFAULT_CONNECTFREQUENCY; + aclass->ping_freq = DEFAULT_PINGFREQUENCY; + aclass->max_total = MAXIMUM_LINKS_DEFAULT; + aclass->max_sendq = DEFAULT_SENDQ; + aclass->max_recvq = DEFAULT_RECVQ; + + break; + + default: + conf = NULL; + break; + } + + /* XXX Yes, this will core if default is hit. I want it to for now - db */ + conf->type = type; + + return conf; +} + +void +delete_conf_item(struct ConfItem *conf) +{ + dlink_node *m = NULL, *m_next = NULL; + struct MatchItem *match_item; + struct AccessItem *aconf; + ConfType type = conf->type; + + MyFree(conf->name); + conf->name = NULL; + + switch(type) + { + case DLINE_TYPE: + case EXEMPTDLINE_TYPE: + case GLINE_TYPE: + case KLINE_TYPE: + case CLIENT_TYPE: + case OPER_TYPE: + case SERVER_TYPE: + aconf = map_to_conf(conf); + + if (aconf->dns_pending) + delete_resolver_queries(aconf); + if (aconf->passwd != NULL) + memset(aconf->passwd, 0, strlen(aconf->passwd)); + if (aconf->spasswd != NULL) + memset(aconf->spasswd, 0, strlen(aconf->spasswd)); + aconf->class_ptr = NULL; + + MyFree(aconf->passwd); + MyFree(aconf->spasswd); + MyFree(aconf->reason); + MyFree(aconf->oper_reason); + MyFree(aconf->user); + MyFree(aconf->host); +#ifdef HAVE_LIBCRYPTO + MyFree(aconf->cipher_list); + + if (aconf->rsa_public_key) + RSA_free(aconf->rsa_public_key); + MyFree(aconf->rsa_public_key_file); +#endif + + /* Yes, sigh. switch on type again */ + switch(type) + { + case EXEMPTDLINE_TYPE: + case DLINE_TYPE: + case GLINE_TYPE: + case KLINE_TYPE: + case CLIENT_TYPE: + MyFree(conf); + break; + + case OPER_TYPE: + aconf = map_to_conf(conf); + if (!IsConfIllegal(aconf)) + dlinkDelete(&conf->node, &oconf_items); + MyFree(conf); + break; + + case SERVER_TYPE: + aconf = map_to_conf(conf); + + DLINK_FOREACH_SAFE(m, m_next, aconf->hub_list.head) + { + MyFree(m->data); + free_dlink_node(m); + } + + DLINK_FOREACH_SAFE(m, m_next, aconf->leaf_list.head) + { + MyFree(m->data); + free_dlink_node(m); + } + + if (!IsConfIllegal(aconf)) + dlinkDelete(&conf->node, &server_items); + MyFree(conf); + break; + + default: + break; + } + break; + + case ULINE_TYPE: + match_item = map_to_conf(conf); + MyFree(match_item->user); + MyFree(match_item->host); + MyFree(match_item->reason); + MyFree(match_item->oper_reason); + dlinkDelete(&conf->node, &uconf_items); + MyFree(conf); + break; + + case XLINE_TYPE: + match_item = map_to_conf(conf); + MyFree(match_item->user); + MyFree(match_item->host); + MyFree(match_item->reason); + MyFree(match_item->oper_reason); + dlinkDelete(&conf->node, &xconf_items); + MyFree(conf); + break; +#ifdef HAVE_LIBPCRE + case RKLINE_TYPE: + aconf = map_to_conf(conf); + MyFree(aconf->regexuser); + MyFree(aconf->regexhost); + MyFree(aconf->user); + MyFree(aconf->host); + MyFree(aconf->reason); + MyFree(aconf->oper_reason); + dlinkDelete(&conf->node, &rkconf_items); + MyFree(conf); + break; + + case RXLINE_TYPE: + MyFree(conf->regexpname); + match_item = map_to_conf(conf); + MyFree(match_item->user); + MyFree(match_item->host); + MyFree(match_item->reason); + MyFree(match_item->oper_reason); + dlinkDelete(&conf->node, &rxconf_items); + MyFree(conf); + break; +#endif + case NRESV_TYPE: + match_item = map_to_conf(conf); + MyFree(match_item->user); + MyFree(match_item->host); + MyFree(match_item->reason); + MyFree(match_item->oper_reason); + dlinkDelete(&conf->node, &nresv_items); + + if (conf->flags & CONF_FLAGS_TEMPORARY) + if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL) + free_dlink_node(m); + + MyFree(conf); + break; + + case CLUSTER_TYPE: + dlinkDelete(&conf->node, &cluster_items); + MyFree(conf); + break; + + case CRESV_TYPE: + if (conf->flags & CONF_FLAGS_TEMPORARY) + if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL) + free_dlink_node(m); + + MyFree(conf); + break; + + case CLASS_TYPE: + dlinkDelete(&conf->node, &class_items); + MyFree(conf); + break; + + case SERVICE_TYPE: + dlinkDelete(&conf->node, &service_items); + MyFree(conf); + break; + + default: + break; + } +} + +/* free_access_item() + * + * inputs - pointer to conf to free + * output - none + * side effects - crucial password fields are zeroed, conf is freed + */ +void +free_access_item(struct AccessItem *aconf) +{ + struct ConfItem *conf; + + if (aconf == NULL) + return; + conf = unmap_conf_item(aconf); + delete_conf_item(conf); +} + +static const unsigned int shared_bit_table[] = + { 'K', 'k', 'U', 'X', 'x', 'Y', 'Q', 'q', 'R', 'L', 0}; + +/* report_confitem_types() + * + * inputs - pointer to client requesting confitem report + * - ConfType to report + * output - none + * side effects - + */ +void +report_confitem_types(struct Client *source_p, ConfType type) +{ + dlink_node *ptr = NULL, *dptr = NULL; + struct ConfItem *conf = NULL; + struct AccessItem *aconf = NULL; + struct MatchItem *matchitem = NULL; + struct ClassItem *classitem = NULL; + char buf[12]; + char *p = NULL; + + switch (type) + { + case XLINE_TYPE: + DLINK_FOREACH(ptr, xconf_items.head) + { + conf = ptr->data; + matchitem = map_to_conf(conf); + + sendto_one(source_p, form_str(RPL_STATSXLINE), + me.name, source_p->name, + matchitem->hold ? "x": "X", matchitem->count, + conf->name, matchitem->reason); + } + break; + +#ifdef HAVE_LIBPCRE + case RXLINE_TYPE: + DLINK_FOREACH(ptr, rxconf_items.head) + { + conf = ptr->data; + matchitem = map_to_conf(conf); + + sendto_one(source_p, form_str(RPL_STATSXLINE), + me.name, source_p->name, + "XR", matchitem->count, + conf->name, matchitem->reason); + } + break; + + case RKLINE_TYPE: + DLINK_FOREACH(ptr, rkconf_items.head) + { + aconf = map_to_conf((conf = ptr->data)); + + sendto_one(source_p, form_str(RPL_STATSKLINE), me.name, + source_p->name, "KR", aconf->host, aconf->user, + aconf->reason, aconf->oper_reason ? aconf->oper_reason : ""); + } + break; +#endif + + case ULINE_TYPE: + DLINK_FOREACH(ptr, uconf_items.head) + { + conf = ptr->data; + matchitem = map_to_conf(conf); + + p = buf; + + /* some of these are redundant for the sake of + * consistency with cluster{} flags + */ + *p++ = 'c'; + flags_to_ascii(matchitem->action, shared_bit_table, p, 0); + + sendto_one(source_p, form_str(RPL_STATSULINE), + me.name, source_p->name, conf->name, + matchitem->user?matchitem->user: "*", + matchitem->host?matchitem->host: "*", buf); + } + + DLINK_FOREACH(ptr, cluster_items.head) + { + conf = ptr->data; + + p = buf; + + *p++ = 'C'; + flags_to_ascii(conf->flags, shared_bit_table, p, 0); + + sendto_one(source_p, form_str(RPL_STATSULINE), + me.name, source_p->name, conf->name, + "*", "*", buf); + } + + break; + + case OPER_TYPE: + DLINK_FOREACH(ptr, oconf_items.head) + { + conf = ptr->data; + aconf = map_to_conf(conf); + + /* Don't allow non opers to see oper privs */ + if (HasUMode(source_p, UMODE_OPER)) + sendto_one(source_p, form_str(RPL_STATSOLINE), + me.name, source_p->name, 'O', aconf->user, aconf->host, + conf->name, oper_privs_as_string(aconf->port), + aconf->class_ptr ? aconf->class_ptr->name : "<default>"); + else + sendto_one(source_p, form_str(RPL_STATSOLINE), + me.name, source_p->name, 'O', aconf->user, aconf->host, + conf->name, "0", + aconf->class_ptr ? aconf->class_ptr->name : "<default>"); + } + break; + + case CLASS_TYPE: + DLINK_FOREACH(ptr, class_items.head) + { + conf = ptr->data; + classitem = map_to_conf(conf); + sendto_one(source_p, form_str(RPL_STATSYLINE), + me.name, source_p->name, 'Y', + conf->name, classitem->ping_freq, + classitem->con_freq, + classitem->max_total, classitem->max_sendq, + classitem->max_recvq, + classitem->curr_user_count, + classitem->number_per_cidr, classitem->cidr_bitlen_ipv4, + classitem->number_per_cidr, classitem->cidr_bitlen_ipv6, + classitem->active ? "active" : "disabled"); + } + break; + + case CONF_TYPE: + case CLIENT_TYPE: + break; + + case SERVICE_TYPE: + DLINK_FOREACH(ptr, service_items.head) + { + conf = ptr->data; + sendto_one(source_p, form_str(RPL_STATSSERVICE), + me.name, source_p->name, 'S', "*", conf->name, 0, 0); + } + break; + + case SERVER_TYPE: + DLINK_FOREACH(ptr, server_items.head) + { + p = buf; + + conf = ptr->data; + aconf = map_to_conf(conf); + + buf[0] = '\0'; + + if (IsConfAllowAutoConn(aconf)) + *p++ = 'A'; + if (IsConfSSL(aconf)) + *p++ = 'S'; + if (buf[0] == '\0') + *p++ = '*'; + + *p = '\0'; + + /* + * Allow admins to see actual ips unless hide_server_ips is enabled + */ + if (!ConfigServerHide.hide_server_ips && HasUMode(source_p, UMODE_ADMIN)) + sendto_one(source_p, form_str(RPL_STATSCLINE), + me.name, source_p->name, 'C', aconf->host, + buf, conf->name, aconf->port, + aconf->class_ptr ? aconf->class_ptr->name : "<default>"); + else + sendto_one(source_p, form_str(RPL_STATSCLINE), + me.name, source_p->name, 'C', + "*@127.0.0.1", buf, conf->name, aconf->port, + aconf->class_ptr ? aconf->class_ptr->name : "<default>"); + } + break; + + case HUB_TYPE: + DLINK_FOREACH(ptr, server_items.head) + { + conf = ptr->data; + aconf = map_to_conf(conf); + + DLINK_FOREACH(dptr, aconf->hub_list.head) + sendto_one(source_p, form_str(RPL_STATSHLINE), me.name, + source_p->name, 'H', dptr->data, conf->name, 0, "*"); + } + break; + + case LEAF_TYPE: + DLINK_FOREACH(ptr, server_items.head) + { + conf = ptr->data; + aconf = map_to_conf(conf); + + DLINK_FOREACH(dptr, aconf->leaf_list.head) + sendto_one(source_p, form_str(RPL_STATSLLINE), me.name, + source_p->name, 'L', dptr->data, conf->name, 0, "*"); + } + break; + + case GLINE_TYPE: + case KLINE_TYPE: + case DLINE_TYPE: + case EXEMPTDLINE_TYPE: + case CRESV_TYPE: + case NRESV_TYPE: + case CLUSTER_TYPE: + default: + break; + } +} + +/* check_client() + * + * inputs - pointer to client + * output - 0 = Success + * NOT_AUTHORIZED (-1) = Access denied (no I line match) + * IRCD_SOCKET_ERROR (-2) = Bad socket. + * I_LINE_FULL (-3) = I-line is full + * TOO_MANY (-4) = Too many connections from hostname + * BANNED_CLIENT (-5) = K-lined + * side effects - Ordinary client access check. + * Look for conf lines which have the same + * status as the flags passed. + */ +static void * +check_client(va_list args) +{ + struct Client *source_p = va_arg(args, struct Client *); + const char *username = va_arg(args, const char *); + int i; + + /* I'm already in big trouble if source_p->localClient is NULL -db */ + if ((i = verify_access(source_p, username))) + ilog(LOG_TYPE_IRCD, "Access denied: %s[%s]", + source_p->name, source_p->sockhost); + + switch (i) + { + case TOO_MANY: + sendto_realops_flags(UMODE_FULL, L_ALL, + "Too many on IP for %s (%s).", + get_client_name(source_p, SHOW_IP), + source_p->sockhost); + ilog(LOG_TYPE_IRCD, "Too many connections on IP from %s.", + get_client_name(source_p, SHOW_IP)); + ++ServerStats.is_ref; + exit_client(source_p, &me, "No more connections allowed on that IP"); + break; + + case I_LINE_FULL: + sendto_realops_flags(UMODE_FULL, L_ALL, + "I-line is full for %s (%s).", + get_client_name(source_p, SHOW_IP), + source_p->sockhost); + ilog(LOG_TYPE_IRCD, "Too many connections from %s.", + get_client_name(source_p, SHOW_IP)); + ++ServerStats.is_ref; + exit_client(source_p, &me, + "No more connections allowed in your connection class"); + break; + + case NOT_AUTHORIZED: + ++ServerStats.is_ref; + /* jdc - lists server name & port connections are on */ + /* a purely cosmetical change */ + sendto_realops_flags(UMODE_UNAUTH, L_ALL, + "Unauthorized client connection from %s [%s] on [%s/%u].", + get_client_name(source_p, SHOW_IP), + source_p->sockhost, + source_p->localClient->listener->name, + source_p->localClient->listener->port); + ilog(LOG_TYPE_IRCD, + "Unauthorized client connection from %s on [%s/%u].", + get_client_name(source_p, SHOW_IP), + source_p->localClient->listener->name, + source_p->localClient->listener->port); + + exit_client(source_p, &me, "You are not authorized to use this server"); + break; + + case BANNED_CLIENT: + exit_client(source_p, &me, "Banned"); + ++ServerStats.is_ref; + break; + + case 0: + default: + break; + } + + return (i < 0 ? NULL : source_p); +} + +/* verify_access() + * + * inputs - pointer to client to verify + * - pointer to proposed username + * output - 0 if success -'ve if not + * side effect - find the first (best) I line to attach. + */ +static int +verify_access(struct Client *client_p, const char *username) +{ + struct AccessItem *aconf = NULL, *rkconf = NULL; + struct ConfItem *conf = NULL; + char non_ident[USERLEN + 1] = { '~', '\0' }; + const char *uhi[3]; + + if (IsGotId(client_p)) + { + aconf = find_address_conf(client_p->host, client_p->username, + &client_p->localClient->ip, + client_p->localClient->aftype, + client_p->localClient->passwd); + } + else + { + strlcpy(non_ident+1, username, sizeof(non_ident)-1); + aconf = find_address_conf(client_p->host,non_ident, + &client_p->localClient->ip, + client_p->localClient->aftype, + client_p->localClient->passwd); + } + + uhi[0] = IsGotId(client_p) ? client_p->username : non_ident; + uhi[1] = client_p->host; + uhi[2] = client_p->sockhost; + + rkconf = find_regexp_kline(uhi); + + if (aconf != NULL) + { + if (IsConfClient(aconf) && !rkconf) + { + conf = unmap_conf_item(aconf); + + if (IsConfRedir(aconf)) + { + sendto_one(client_p, form_str(RPL_REDIR), + me.name, client_p->name, + conf->name ? conf->name : "", + aconf->port); + return(NOT_AUTHORIZED); + } + + if (IsConfDoIdentd(aconf)) + SetNeedId(client_p); + + /* Thanks for spoof idea amm */ + if (IsConfDoSpoofIp(aconf)) + { + conf = unmap_conf_item(aconf); + + if (!ConfigFileEntry.hide_spoof_ips && IsConfSpoofNotice(aconf)) + sendto_realops_flags(UMODE_ALL, L_ADMIN, "%s spoofing: %s as %s", + client_p->name, client_p->host, conf->name); + strlcpy(client_p->host, conf->name, sizeof(client_p->host)); + SetIPSpoof(client_p); + } + + return(attach_iline(client_p, conf)); + } + else if (rkconf || IsConfKill(aconf) || (ConfigFileEntry.glines && IsConfGline(aconf))) + { + /* XXX */ + aconf = rkconf ? rkconf : aconf; + if (IsConfGline(aconf)) + sendto_one(client_p, ":%s NOTICE %s :*** G-lined", me.name, + client_p->name); + sendto_one(client_p, ":%s NOTICE %s :*** Banned: %s", + me.name, client_p->name, aconf->reason); + return(BANNED_CLIENT); + } + } + + return(NOT_AUTHORIZED); +} + +/* attach_iline() + * + * inputs - client pointer + * - conf pointer + * output - + * side effects - do actual attach + */ +static int +attach_iline(struct Client *client_p, struct ConfItem *conf) +{ + struct AccessItem *aconf; + struct ClassItem *aclass; + struct ip_entry *ip_found; + int a_limit_reached = 0; + int local = 0, global = 0, ident = 0; + + ip_found = find_or_add_ip(&client_p->localClient->ip); + ip_found->count++; + SetIpHash(client_p); + + aconf = map_to_conf(conf); + if (aconf->class_ptr == NULL) + return NOT_AUTHORIZED; /* If class is missing, this is best */ + + aclass = map_to_conf(aconf->class_ptr); + + count_user_host(client_p->username, client_p->host, + &global, &local, &ident); + + /* XXX blah. go down checking the various silly limits + * setting a_limit_reached if any limit is reached. + * - Dianora + */ + if (aclass->max_total != 0 && aclass->curr_user_count >= aclass->max_total) + a_limit_reached = 1; + else if (aclass->max_perip != 0 && ip_found->count > aclass->max_perip) + a_limit_reached = 1; + else if (aclass->max_local != 0 && local >= aclass->max_local) + a_limit_reached = 1; + else if (aclass->max_global != 0 && global >= aclass->max_global) + a_limit_reached = 1; + else if (aclass->max_ident != 0 && ident >= aclass->max_ident && + client_p->username[0] != '~') + a_limit_reached = 1; + + if (a_limit_reached) + { + if (!IsConfExemptLimits(aconf)) + return TOO_MANY; /* Already at maximum allowed */ + + sendto_one(client_p, + ":%s NOTICE %s :*** Your connection class is full, " + "but you have exceed_limit = yes;", me.name, client_p->name); + } + + return attach_conf(client_p, conf); +} + +/* init_ip_hash_table() + * + * inputs - NONE + * output - NONE + * side effects - allocate memory for ip_entry(s) + * - clear the ip hash table + */ +void +init_ip_hash_table(void) +{ + ip_entry_heap = BlockHeapCreate("ip", sizeof(struct ip_entry), + 2 * hard_fdlimit); + memset(ip_hash_table, 0, sizeof(ip_hash_table)); +} + +/* find_or_add_ip() + * + * inputs - pointer to struct irc_ssaddr + * output - pointer to a struct ip_entry + * side effects - + * + * If the ip # was not found, a new struct ip_entry is created, and the ip + * count set to 0. + */ +static struct ip_entry * +find_or_add_ip(struct irc_ssaddr *ip_in) +{ + struct ip_entry *ptr, *newptr; + int hash_index = hash_ip(ip_in), res; + struct sockaddr_in *v4 = (struct sockaddr_in *)ip_in, *ptr_v4; +#ifdef IPV6 + struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)ip_in, *ptr_v6; +#endif + + for (ptr = ip_hash_table[hash_index]; ptr; ptr = ptr->next) + { +#ifdef IPV6 + if (ptr->ip.ss.ss_family != ip_in->ss.ss_family) + continue; + if (ip_in->ss.ss_family == AF_INET6) + { + ptr_v6 = (struct sockaddr_in6 *)&ptr->ip; + res = memcmp(&v6->sin6_addr, &ptr_v6->sin6_addr, sizeof(struct in6_addr)); + } + else +#endif + { + ptr_v4 = (struct sockaddr_in *)&ptr->ip; + res = memcmp(&v4->sin_addr, &ptr_v4->sin_addr, sizeof(struct in_addr)); + } + if (res == 0) + { + /* Found entry already in hash, return it. */ + return ptr; + } + } + + if (ip_entries_count >= 2 * hard_fdlimit) + garbage_collect_ip_entries(); + + newptr = BlockHeapAlloc(ip_entry_heap); + ip_entries_count++; + memcpy(&newptr->ip, ip_in, sizeof(struct irc_ssaddr)); + + newptr->next = ip_hash_table[hash_index]; + ip_hash_table[hash_index] = newptr; + + return newptr; +} + +/* remove_one_ip() + * + * inputs - unsigned long IP address value + * output - NONE + * side effects - The ip address given, is looked up in ip hash table + * and number of ip#'s for that ip decremented. + * If ip # count reaches 0 and has expired, + * the struct ip_entry is returned to the ip_entry_heap + */ +void +remove_one_ip(struct irc_ssaddr *ip_in) +{ + struct ip_entry *ptr; + struct ip_entry *last_ptr = NULL; + int hash_index = hash_ip(ip_in), res; + struct sockaddr_in *v4 = (struct sockaddr_in *)ip_in, *ptr_v4; +#ifdef IPV6 + struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)ip_in, *ptr_v6; +#endif + + for (ptr = ip_hash_table[hash_index]; ptr; ptr = ptr->next) + { +#ifdef IPV6 + if (ptr->ip.ss.ss_family != ip_in->ss.ss_family) + continue; + if (ip_in->ss.ss_family == AF_INET6) + { + ptr_v6 = (struct sockaddr_in6 *)&ptr->ip; + res = memcmp(&v6->sin6_addr, &ptr_v6->sin6_addr, sizeof(struct in6_addr)); + } + else +#endif + { + ptr_v4 = (struct sockaddr_in *)&ptr->ip; + res = memcmp(&v4->sin_addr, &ptr_v4->sin_addr, sizeof(struct in_addr)); + } + if (res) + continue; + if (ptr->count > 0) + ptr->count--; + if (ptr->count == 0 && + (CurrentTime-ptr->last_attempt) >= ConfigFileEntry.throttle_time) + { + if (last_ptr != NULL) + last_ptr->next = ptr->next; + else + ip_hash_table[hash_index] = ptr->next; + + BlockHeapFree(ip_entry_heap, ptr); + ip_entries_count--; + return; + } + last_ptr = ptr; + } +} + +/* hash_ip() + * + * input - pointer to an irc_inaddr + * output - integer value used as index into hash table + * side effects - hopefully, none + */ +static int +hash_ip(struct irc_ssaddr *addr) +{ + if (addr->ss.ss_family == AF_INET) + { + struct sockaddr_in *v4 = (struct sockaddr_in *)addr; + int hash; + uint32_t ip; + + ip = ntohl(v4->sin_addr.s_addr); + hash = ((ip >> 12) + ip) & (IP_HASH_SIZE-1); + return hash; + } +#ifdef IPV6 + else + { + int hash; + struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr; + uint32_t *ip = (uint32_t *)&v6->sin6_addr.s6_addr; + + hash = ip[0] ^ ip[3]; + hash ^= hash >> 16; + hash ^= hash >> 8; + hash = hash & (IP_HASH_SIZE - 1); + return hash; + } +#else + return 0; +#endif +} + +/* count_ip_hash() + * + * inputs - pointer to counter of number of ips hashed + * - pointer to memory used for ip hash + * output - returned via pointers input + * side effects - NONE + * + * number of hashed ip #'s is counted up, plus the amount of memory + * used in the hash. + */ +void +count_ip_hash(unsigned int *number_ips_stored, uint64_t *mem_ips_stored) +{ + struct ip_entry *ptr; + int i; + + *number_ips_stored = 0; + *mem_ips_stored = 0; + + for (i = 0; i < IP_HASH_SIZE; i++) + { + for (ptr = ip_hash_table[i]; ptr; ptr = ptr->next) + { + *number_ips_stored += 1; + *mem_ips_stored += sizeof(struct ip_entry); + } + } +} + +/* garbage_collect_ip_entries() + * + * input - NONE + * output - NONE + * side effects - free up all ip entries with no connections + */ +static void +garbage_collect_ip_entries(void) +{ + struct ip_entry *ptr; + struct ip_entry *last_ptr; + struct ip_entry *next_ptr; + int i; + + for (i = 0; i < IP_HASH_SIZE; i++) + { + last_ptr = NULL; + + for (ptr = ip_hash_table[i]; ptr; ptr = next_ptr) + { + next_ptr = ptr->next; + + if (ptr->count == 0 && + (CurrentTime - ptr->last_attempt) >= ConfigFileEntry.throttle_time) + { + if (last_ptr != NULL) + last_ptr->next = ptr->next; + else + ip_hash_table[i] = ptr->next; + BlockHeapFree(ip_entry_heap, ptr); + ip_entries_count--; + } + else + last_ptr = ptr; + } + } +} + +/* detach_conf() + * + * inputs - pointer to client to detach + * - type of conf to detach + * output - 0 for success, -1 for failure + * side effects - Disassociate configuration from the client. + * Also removes a class from the list if marked for deleting. + */ +int +detach_conf(struct Client *client_p, ConfType type) +{ + dlink_node *ptr, *next_ptr; + struct ConfItem *conf; + struct ClassItem *aclass; + struct AccessItem *aconf; + struct ConfItem *aclass_conf; + + DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->confs.head) + { + conf = ptr->data; + + if (type == CONF_TYPE || conf->type == type) + { + dlinkDelete(ptr, &client_p->localClient->confs); + free_dlink_node(ptr); + + switch (conf->type) + { + case CLIENT_TYPE: + case OPER_TYPE: + case SERVER_TYPE: + aconf = map_to_conf(conf); + + assert(aconf->clients > 0); + + if ((aclass_conf = aconf->class_ptr) != NULL) + { + aclass = map_to_conf(aclass_conf); + + assert(aclass->curr_user_count > 0); + + if (conf->type == CLIENT_TYPE) + remove_from_cidr_check(&client_p->localClient->ip, aclass); + if (--aclass->curr_user_count == 0 && aclass->active == 0) + delete_conf_item(aclass_conf); + } + + if (--aconf->clients == 0 && IsConfIllegal(aconf)) + delete_conf_item(conf); + + break; + default: + break; + } + + if (type != CONF_TYPE) + return 0; + } + } + + return -1; +} + +/* attach_conf() + * + * inputs - client pointer + * - conf pointer + * output - + * side effects - Associate a specific configuration entry to a *local* + * client (this is the one which used in accepting the + * connection). Note, that this automatically changes the + * attachment if there was an old one... + */ +int +attach_conf(struct Client *client_p, struct ConfItem *conf) +{ + struct AccessItem *aconf = map_to_conf(conf); + struct ClassItem *aclass = map_to_conf(aconf->class_ptr); + + if (dlinkFind(&client_p->localClient->confs, conf) != NULL) + return 1; + + if (IsConfIllegal(aconf)) /* TBV: can't happen */ + return NOT_AUTHORIZED; + + if (conf->type == CLIENT_TYPE) + if (cidr_limit_reached(IsConfExemptLimits(aconf), + &client_p->localClient->ip, aclass)) + return TOO_MANY; /* Already at maximum allowed */ + + aclass->curr_user_count++; + aconf->clients++; + + dlinkAdd(conf, make_dlink_node(), &client_p->localClient->confs); + + return 0; +} + +/* attach_connect_block() + * + * inputs - pointer to server to attach + * - name of server + * - hostname of server + * output - true (1) if both are found, otherwise return false (0) + * side effects - find connect block and attach them to connecting client + */ +int +attach_connect_block(struct Client *client_p, const char *name, + const char *host) +{ + dlink_node *ptr; + struct ConfItem *conf; + struct AccessItem *aconf; + + assert(client_p != NULL); + assert(host != NULL); + + if (client_p == NULL || host == NULL) + return 0; + + DLINK_FOREACH(ptr, server_items.head) + { + conf = ptr->data; + aconf = map_to_conf(conf); + + if (match(conf->name, name) == 0 || match(aconf->host, host) == 0) + continue; + + attach_conf(client_p, conf); + return -1; + } + + return 0; +} + +/* find_conf_exact() + * + * inputs - type of ConfItem + * - pointer to name to find + * - pointer to username to find + * - pointer to host to find + * output - NULL or pointer to conf found + * side effects - find a conf entry which matches the hostname + * and has the same name. + */ +struct ConfItem * +find_conf_exact(ConfType type, const char *name, const char *user, + const char *host) +{ + dlink_node *ptr; + dlink_list *list_p; + struct ConfItem *conf = NULL; + struct AccessItem *aconf; + + /* Only valid for OPER_TYPE and ...? */ + list_p = map_to_list(type); + + DLINK_FOREACH(ptr, (*list_p).head) + { + conf = ptr->data; + + if (conf->name == NULL) + continue; + aconf = map_to_conf(conf); + if (aconf->host == NULL) + continue; + if (irccmp(conf->name, name) != 0) + continue; + + /* + ** Accept if the *real* hostname (usually sockethost) + ** socket host) matches *either* host or name field + ** of the configuration. + */ + if (!match(aconf->host, host) || !match(aconf->user, user)) + continue; + if (type == OPER_TYPE) + { + struct ClassItem *aclass = map_to_conf(aconf->class_ptr); + + if (aconf->clients >= aclass->max_total) + continue; + } + + return conf; + } + + return NULL; +} + +/* find_conf_name() + * + * inputs - pointer to conf link list to search + * - pointer to name to find + * - int mask of type of conf to find + * output - NULL or pointer to conf found + * side effects - find a conf entry which matches the name + * and has the given mask. + */ +struct ConfItem * +find_conf_name(dlink_list *list, const char *name, ConfType type) +{ + dlink_node *ptr; + struct ConfItem* conf; + + DLINK_FOREACH(ptr, list->head) + { + conf = ptr->data; + + if (conf->type == type) + { + if (conf->name && (irccmp(conf->name, name) == 0 || + match(conf->name, name))) + return conf; + } + } + + return NULL; +} + +/* map_to_list() + * + * inputs - ConfType conf + * output - pointer to dlink_list to use + * side effects - none + */ +static dlink_list * +map_to_list(ConfType type) +{ + switch(type) + { + case RXLINE_TYPE: + return(&rxconf_items); + break; + case XLINE_TYPE: + return(&xconf_items); + break; + case ULINE_TYPE: + return(&uconf_items); + break; + case NRESV_TYPE: + return(&nresv_items); + break; + case OPER_TYPE: + return(&oconf_items); + break; + case CLASS_TYPE: + return(&class_items); + break; + case SERVER_TYPE: + return(&server_items); + break; + case SERVICE_TYPE: + return(&service_items); + break; + case CLUSTER_TYPE: + return(&cluster_items); + break; + case CONF_TYPE: + case GLINE_TYPE: + case KLINE_TYPE: + case DLINE_TYPE: + case CRESV_TYPE: + default: + return NULL; + } +} + +/* find_matching_name_conf() + * + * inputs - type of link list to look in + * - pointer to name string to find + * - pointer to user + * - pointer to host + * - optional action to match on as well + * output - NULL or pointer to found struct MatchItem + * side effects - looks for a match on name field + */ +struct ConfItem * +find_matching_name_conf(ConfType type, const char *name, const char *user, + const char *host, int action) +{ + dlink_node *ptr=NULL; + struct ConfItem *conf=NULL; + struct AccessItem *aconf=NULL; + struct MatchItem *match_item=NULL; + dlink_list *list_p = map_to_list(type); + + switch (type) + { +#ifdef HAVE_LIBPCRE + case RXLINE_TYPE: + DLINK_FOREACH(ptr, list_p->head) + { + conf = ptr->data; + assert(conf->regexpname); + + if (!ircd_pcre_exec(conf->regexpname, name)) + return conf; + } + break; +#endif + case SERVICE_TYPE: + DLINK_FOREACH(ptr, list_p->head) + { + conf = ptr->data; + + if (EmptyString(conf->name)) + continue; + if ((name != NULL) && !irccmp(name, conf->name)) + return conf; + } + break; + + case XLINE_TYPE: + case ULINE_TYPE: + case NRESV_TYPE: + DLINK_FOREACH(ptr, list_p->head) + { + conf = ptr->data; + + match_item = map_to_conf(conf); + if (EmptyString(conf->name)) + continue; + if ((name != NULL) && match_esc(conf->name, name)) + { + if ((user == NULL && (host == NULL))) + return conf; + if ((match_item->action & action) != action) + continue; + if (EmptyString(match_item->user) || EmptyString(match_item->host)) + return conf; + if (match(match_item->user, user) && match(match_item->host, host)) + return conf; + } + } + break; + + case SERVER_TYPE: + DLINK_FOREACH(ptr, list_p->head) + { + conf = ptr->data; + aconf = map_to_conf(conf); + + if ((name != NULL) && match_esc(name, conf->name)) + return conf; + else if ((host != NULL) && match_esc(host, aconf->host)) + return conf; + } + break; + + default: + break; + } + return NULL; +} + +/* find_exact_name_conf() + * + * inputs - type of link list to look in + * - pointer to name string to find + * - pointer to user + * - pointer to host + * output - NULL or pointer to found struct MatchItem + * side effects - looks for an exact match on name field + */ +struct ConfItem * +find_exact_name_conf(ConfType type, const struct Client *who, const char *name, + const char *user, const char *host) +{ + dlink_node *ptr = NULL; + struct AccessItem *aconf; + struct ConfItem *conf; + struct MatchItem *match_item; + dlink_list *list_p; + + list_p = map_to_list(type); + + switch(type) + { + case RXLINE_TYPE: + case XLINE_TYPE: + case ULINE_TYPE: + case NRESV_TYPE: + + DLINK_FOREACH(ptr, list_p->head) + { + conf = ptr->data; + match_item = (struct MatchItem *)map_to_conf(conf); + if (EmptyString(conf->name)) + continue; + + if (irccmp(conf->name, name) == 0) + { + if ((user == NULL && (host == NULL))) + return (conf); + if (EmptyString(match_item->user) || EmptyString(match_item->host)) + return (conf); + if (match(match_item->user, user) && match(match_item->host, host)) + return (conf); + } + } + break; + + case OPER_TYPE: + DLINK_FOREACH(ptr, list_p->head) + { + conf = ptr->data; + aconf = map_to_conf(conf); + + if (EmptyString(conf->name)) + continue; + + if (!irccmp(conf->name, name)) + { + if (!who) + return conf; + if (EmptyString(aconf->user) || EmptyString(aconf->host)) + return conf; + if (match(aconf->user, who->username)) + { + switch (aconf->type) + { + case HM_HOST: + if (match(aconf->host, who->host) || match(aconf->host, who->sockhost)) + return conf; + break; + case HM_IPV4: + if (who->localClient->aftype == AF_INET) + if (match_ipv4(&who->localClient->ip, &aconf->addr, aconf->bits)) + return conf; + break; +#ifdef IPV6 + case HM_IPV6: + if (who->localClient->aftype == AF_INET6) + if (match_ipv6(&who->localClient->ip, &aconf->addr, aconf->bits)) + return conf; + break; +#endif + default: + assert(0); + } + } + } + } + + break; + + case SERVER_TYPE: + DLINK_FOREACH(ptr, list_p->head) + { + conf = ptr->data; + aconf = (struct AccessItem *)map_to_conf(conf); + if (EmptyString(conf->name)) + continue; + + if (name == NULL) + { + if (EmptyString(aconf->host)) + continue; + if (irccmp(aconf->host, host) == 0) + return(conf); + } + else if (irccmp(conf->name, name) == 0) + { + return (conf); + } + } + break; + + case CLASS_TYPE: + DLINK_FOREACH(ptr, list_p->head) + { + conf = ptr->data; + if (EmptyString(conf->name)) + continue; + + if (irccmp(conf->name, name) == 0) + return (conf); + } + break; + + default: + break; + } + return(NULL); +} + +/* rehash() + * + * Actual REHASH service routine. Called with sig == 0 if it has been called + * as a result of an operator issuing this command, else assume it has been + * called as a result of the server receiving a HUP signal. + */ +int +rehash(int sig) +{ + if (sig != 0) + sendto_realops_flags(UMODE_ALL, L_ALL, + "Got signal SIGHUP, reloading ircd.conf file"); + + restart_resolver(); + + /* don't close listeners until we know we can go ahead with the rehash */ + + /* Check to see if we magically got(or lost) IPv6 support */ + check_can_use_v6(); + + read_conf_files(0); + + if (ServerInfo.description != NULL) + strlcpy(me.info, ServerInfo.description, sizeof(me.info)); + + load_conf_modules(); + + flush_deleted_I_P(); + + rehashed_klines = 1; +/* XXX */ + if (ConfigLoggingEntry.use_logging) + log_close_all(); + + return(0); +} + +/* set_default_conf() + * + * inputs - NONE + * output - NONE + * side effects - Set default values here. + * This is called **PRIOR** to parsing the + * configuration file. If you want to do some validation + * of values later, put them in validate_conf(). + */ +static void +set_default_conf(void) +{ + /* verify init_class() ran, this should be an unnecessary check + * but its not much work. + */ + assert(class_default == (struct ConfItem *) class_items.tail->data); + +#ifdef HAVE_LIBCRYPTO + ServerInfo.rsa_private_key = NULL; + ServerInfo.rsa_private_key_file = NULL; +#endif + + /* ServerInfo.name is not rehashable */ + /* ServerInfo.name = ServerInfo.name; */ + ServerInfo.description = NULL; + DupString(ServerInfo.network_name, NETWORK_NAME_DEFAULT); + DupString(ServerInfo.network_desc, NETWORK_DESC_DEFAULT); + + memset(&ServerInfo.ip, 0, sizeof(ServerInfo.ip)); + ServerInfo.specific_ipv4_vhost = 0; + memset(&ServerInfo.ip6, 0, sizeof(ServerInfo.ip6)); + ServerInfo.specific_ipv6_vhost = 0; + + ServerInfo.max_clients = MAXCLIENTS_MAX; + + ServerInfo.hub = 0; + ServerInfo.dns_host.sin_addr.s_addr = 0; + ServerInfo.dns_host.sin_port = 0; + AdminInfo.name = NULL; + AdminInfo.email = NULL; + AdminInfo.description = NULL; + + log_close_all(); + + ConfigLoggingEntry.use_logging = 1; + + ConfigChannel.disable_fake_channels = 0; + ConfigChannel.restrict_channels = 0; + ConfigChannel.knock_delay = 300; + ConfigChannel.knock_delay_channel = 60; + ConfigChannel.max_chans_per_user = 25; + ConfigChannel.max_chans_per_oper = 50; + ConfigChannel.quiet_on_ban = 1; + ConfigChannel.max_bans = 25; + ConfigChannel.default_split_user_count = 0; + ConfigChannel.default_split_server_count = 0; + ConfigChannel.no_join_on_split = 0; + ConfigChannel.no_create_on_split = 0; + + ConfigServerHide.flatten_links = 0; + ConfigServerHide.links_delay = 300; + ConfigServerHide.hidden = 0; + ConfigServerHide.hide_servers = 0; + DupString(ConfigServerHide.hidden_name, NETWORK_NAME_DEFAULT); + ConfigServerHide.hide_server_ips = 0; + + + DupString(ConfigFileEntry.service_name, SERVICE_NAME_DEFAULT); + ConfigFileEntry.max_watch = WATCHSIZE_DEFAULT; + ConfigFileEntry.glines = 0; + ConfigFileEntry.gline_time = 12 * 3600; + ConfigFileEntry.gline_request_time = GLINE_REQUEST_EXPIRE_DEFAULT; + ConfigFileEntry.gline_min_cidr = 16; + ConfigFileEntry.gline_min_cidr6 = 48; + ConfigFileEntry.invisible_on_connect = 1; + ConfigFileEntry.tkline_expire_notices = 1; + ConfigFileEntry.hide_spoof_ips = 1; + ConfigFileEntry.ignore_bogus_ts = 0; + ConfigFileEntry.disable_auth = 0; + ConfigFileEntry.disable_remote = 0; + ConfigFileEntry.kill_chase_time_limit = 90; + ConfigFileEntry.default_floodcount = 8; + ConfigFileEntry.failed_oper_notice = 1; + ConfigFileEntry.dots_in_ident = 0; + ConfigFileEntry.min_nonwildcard = 4; + ConfigFileEntry.min_nonwildcard_simple = 3; + ConfigFileEntry.max_accept = 20; + ConfigFileEntry.anti_nick_flood = 0; + ConfigFileEntry.max_nick_time = 20; + ConfigFileEntry.max_nick_changes = 5; + ConfigFileEntry.anti_spam_exit_message_time = 0; + ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT; + ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT; + ConfigFileEntry.warn_no_nline = 1; + ConfigFileEntry.stats_o_oper_only = 0; + ConfigFileEntry.stats_k_oper_only = 1; /* masked */ + ConfigFileEntry.stats_i_oper_only = 1; /* masked */ + ConfigFileEntry.stats_P_oper_only = 0; + ConfigFileEntry.caller_id_wait = 60; + ConfigFileEntry.opers_bypass_callerid = 0; + ConfigFileEntry.pace_wait = 10; + ConfigFileEntry.pace_wait_simple = 1; + ConfigFileEntry.short_motd = 0; + ConfigFileEntry.ping_cookie = 0; + ConfigFileEntry.no_oper_flood = 0; + ConfigFileEntry.true_no_oper_flood = 0; + ConfigFileEntry.oper_pass_resv = 1; + ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT; + ConfigFileEntry.oper_only_umodes = UMODE_DEBUG; + ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE | + UMODE_OPERWALL | UMODE_WALLOP; + ConfigFileEntry.use_egd = 0; + ConfigFileEntry.egdpool_path = NULL; + ConfigFileEntry.throttle_time = 10; +} + +static void +validate_conf(void) +{ + if (ConfigFileEntry.ts_warn_delta < TS_WARN_DELTA_MIN) + ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT; + + if (ConfigFileEntry.ts_max_delta < TS_MAX_DELTA_MIN) + ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT; + + if (ServerInfo.network_name == NULL) + DupString(ServerInfo.network_name,NETWORK_NAME_DEFAULT); + + if (ServerInfo.network_desc == NULL) + DupString(ServerInfo.network_desc,NETWORK_DESC_DEFAULT); + + if (ConfigFileEntry.service_name == NULL) + DupString(ConfigFileEntry.service_name, SERVICE_NAME_DEFAULT); + + ConfigFileEntry.max_watch = IRCD_MAX(ConfigFileEntry.max_watch, WATCHSIZE_MIN); +} + +/* read_conf() + * + * inputs - file descriptor pointing to config file to use + * output - None + * side effects - Read configuration file. + */ +static void +read_conf(FILE *file) +{ + lineno = 0; + + set_default_conf(); /* Set default values prior to conf parsing */ + conf_parser_ctx.pass = 1; + yyparse(); /* pick up the classes first */ + + rewind(file); + + conf_parser_ctx.pass = 2; + yyparse(); /* Load the values from the conf */ + validate_conf(); /* Check to make sure some values are still okay. */ + /* Some global values are also loaded here. */ + check_class(); /* Make sure classes are valid */ +} + +/* lookup_confhost() + * + * start DNS lookups of all hostnames in the conf + * line and convert an IP addresses in a.b.c.d number for to IP#s. + */ +static void +lookup_confhost(struct ConfItem *conf) +{ + struct AccessItem *aconf; + struct addrinfo hints, *res; + + aconf = map_to_conf(conf); + + if (has_wildcards(aconf->host)) + { + ilog(LOG_TYPE_IRCD, "Host/server name error: (%s) (%s)", + aconf->host, conf->name); + return; + } + + /* Do name lookup now on hostnames given and store the + * ip numbers in conf structure. + */ + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + /* Get us ready for a bind() and don't bother doing dns lookup */ + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + + if (getaddrinfo(aconf->host, NULL, &hints, &res)) + { + conf_dns_lookup(aconf); + return; + } + + assert(res != NULL); + + memcpy(&aconf->addr, res->ai_addr, res->ai_addrlen); + aconf->addr.ss_len = res->ai_addrlen; + aconf->addr.ss.ss_family = res->ai_family; + freeaddrinfo(res); +} + +/* conf_connect_allowed() + * + * inputs - pointer to inaddr + * - int type ipv4 or ipv6 + * output - BANNED or accepted + * side effects - none + */ +int +conf_connect_allowed(struct irc_ssaddr *addr, int aftype) +{ + struct ip_entry *ip_found; + struct AccessItem *aconf = find_dline_conf(addr, aftype); + + /* DLINE exempt also gets you out of static limits/pacing... */ + if (aconf && (aconf->status & CONF_EXEMPTDLINE)) + return 0; + + if (aconf != NULL) + return BANNED_CLIENT; + + ip_found = find_or_add_ip(addr); + + if ((CurrentTime - ip_found->last_attempt) < + ConfigFileEntry.throttle_time) + { + ip_found->last_attempt = CurrentTime; + return TOO_FAST; + } + + ip_found->last_attempt = CurrentTime; + return 0; +} + +static struct AccessItem * +find_regexp_kline(const char *uhi[]) +{ +#ifdef HAVE_LIBPCRE + const dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, rkconf_items.head) + { + struct AccessItem *aptr = map_to_conf(ptr->data); + + assert(aptr->regexuser); + assert(aptr->regexhost); + + if (!ircd_pcre_exec(aptr->regexuser, uhi[0]) && + (!ircd_pcre_exec(aptr->regexhost, uhi[1]) || + !ircd_pcre_exec(aptr->regexhost, uhi[2]))) + return aptr; + } +#endif + return NULL; +} + +/* find_kill() + * + * inputs - pointer to client structure + * output - pointer to struct AccessItem if found + * side effects - See if this user is klined already, + * and if so, return struct AccessItem pointer + */ +struct AccessItem * +find_kill(struct Client *client_p) +{ + struct AccessItem *aconf = NULL; + const char *uhi[3]; + + uhi[0] = client_p->username; + uhi[1] = client_p->host; + uhi[2] = client_p->sockhost; + + assert(client_p != NULL); + + aconf = find_conf_by_address(client_p->host, &client_p->localClient->ip, + CONF_KLINE, client_p->localClient->aftype, + client_p->username, NULL, 1); + if (aconf == NULL) + aconf = find_regexp_kline(uhi); + + return aconf; +} + +struct AccessItem * +find_gline(struct Client *client_p) +{ + struct AccessItem *aconf; + + assert(client_p != NULL); + + aconf = find_conf_by_address(client_p->host, &client_p->localClient->ip, + CONF_GLINE, client_p->localClient->aftype, + client_p->username, NULL, 1); + return aconf; +} + +/* add_temp_line() + * + * inputs - pointer to struct ConfItem + * output - none + * Side effects - links in given struct ConfItem into + * temporary *line link list + */ +void +add_temp_line(struct ConfItem *conf) +{ + if (conf->type == XLINE_TYPE) + { + conf->flags |= CONF_FLAGS_TEMPORARY; + dlinkAdd(conf, make_dlink_node(), &temporary_xlines); + } + else if ((conf->type == NRESV_TYPE) || (conf->type == CRESV_TYPE)) + { + conf->flags |= CONF_FLAGS_TEMPORARY; + dlinkAdd(conf, make_dlink_node(), &temporary_resv); + } +} + +/* cleanup_tklines() + * + * inputs - NONE + * output - NONE + * side effects - call function to expire temporary k/d lines + * This is an event started off in ircd.c + */ +void +cleanup_tklines(void *notused) +{ + hostmask_expire_temporary(); + expire_tklines(&temporary_xlines); + expire_tklines(&temporary_resv); +} + +/* expire_tklines() + * + * inputs - tkline list pointer + * output - NONE + * side effects - expire tklines + */ +static void +expire_tklines(dlink_list *tklist) +{ + dlink_node *ptr; + dlink_node *next_ptr; + struct ConfItem *conf; + struct MatchItem *xconf; + struct MatchItem *nconf; + struct ResvChannel *cconf; + + DLINK_FOREACH_SAFE(ptr, next_ptr, tklist->head) + { + conf = ptr->data; + + if (conf->type == XLINE_TYPE) + { + xconf = (struct MatchItem *)map_to_conf(conf); + if (xconf->hold <= CurrentTime) + { + if (ConfigFileEntry.tkline_expire_notices) + sendto_realops_flags(UMODE_ALL, L_ALL, + "Temporary X-line for [%s] sexpired", conf->name); + dlinkDelete(ptr, tklist); + free_dlink_node(ptr); + delete_conf_item(conf); + } + } + else if (conf->type == NRESV_TYPE) + { + nconf = (struct MatchItem *)map_to_conf(conf); + if (nconf->hold <= CurrentTime) + { + if (ConfigFileEntry.tkline_expire_notices) + sendto_realops_flags(UMODE_ALL, L_ALL, + "Temporary RESV for [%s] expired", conf->name); + dlinkDelete(ptr, tklist); + free_dlink_node(ptr); + delete_conf_item(conf); + } + } + else if (conf->type == CRESV_TYPE) + { + cconf = (struct ResvChannel *)map_to_conf(conf); + if (cconf->hold <= CurrentTime) + { + if (ConfigFileEntry.tkline_expire_notices) + sendto_realops_flags(UMODE_ALL, L_ALL, + "Temporary RESV for [%s] expired", cconf->name); + delete_channel_resv(cconf); + } + } + } +} + +/* oper_privs_as_string() + * + * inputs - pointer to client_p + * output - pointer to static string showing oper privs + * side effects - return as string, the oper privs as derived from port + */ +static const struct oper_privs +{ + const unsigned int oprivs; + const unsigned char c; +} flag_list[] = { + { OPER_FLAG_ADMIN, 'A' }, + { OPER_FLAG_REMOTEBAN, 'B' }, + { OPER_FLAG_DIE, 'D' }, + { OPER_FLAG_GLINE, 'G' }, + { OPER_FLAG_REHASH, 'H' }, + { OPER_FLAG_K, 'K' }, + { OPER_FLAG_OPERWALL, 'L' }, + { OPER_FLAG_N, 'N' }, + { OPER_FLAG_GLOBAL_KILL, 'O' }, + { OPER_FLAG_REMOTE, 'R' }, + { OPER_FLAG_OPER_SPY, 'S' }, + { OPER_FLAG_UNKLINE, 'U' }, + { OPER_FLAG_X, 'X' }, + { 0, '\0' } +}; + +char * +oper_privs_as_string(const unsigned int port) +{ + static char privs_out[16]; + char *privs_ptr = privs_out; + unsigned int i = 0; + + for (; flag_list[i].oprivs; ++i) + { + if (port & flag_list[i].oprivs) + *privs_ptr++ = flag_list[i].c; + else + *privs_ptr++ = ToLowerTab[flag_list[i].c]; + } + + *privs_ptr = '\0'; + + return privs_out; +} + +/* + * Input: A client to find the active oper{} name for. + * Output: The nick!user@host{oper} of the oper. + * "oper" is server name for remote opers + * Side effects: None. + */ +const char * +get_oper_name(const struct Client *client_p) +{ + dlink_node *cnode = NULL; + /* +5 for !,@,{,} and null */ + static char buffer[NICKLEN + USERLEN + HOSTLEN + HOSTLEN + 5]; + + if (MyConnect(client_p)) + { + if ((cnode = client_p->localClient->confs.head)) + { + struct ConfItem *conf = cnode->data; + const struct AccessItem *aconf = map_to_conf(conf); + + if (IsConfOperator(aconf)) + { + snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name, + client_p->username, client_p->host, conf->name); + return buffer; + } + } + + /* Probably should assert here for now. If there is an oper out there + * with no oper{} conf attached, it would be good for us to know... + */ + assert(0); /* Oper without oper conf! */ + } + + snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name, + client_p->username, client_p->host, client_p->servptr->name); + return buffer; +} + +/* read_conf_files() + * + * inputs - cold start YES or NO + * output - none + * side effects - read all conf files needed, ircd.conf kline.conf etc. + */ +void +read_conf_files(int cold) +{ + const char *filename; + char chanmodes[32]; + char chanlimit[32]; + + conf_parser_ctx.boot = cold; + filename = get_conf_name(CONF_TYPE); + + /* We need to know the initial filename for the yyerror() to report + FIXME: The full path is in conffilenamebuf first time since we + dont know anything else + + - Gozem 2002-07-21 + */ + strlcpy(conffilebuf, filename, sizeof(conffilebuf)); + + if ((conf_parser_ctx.conf_file = fopen(filename, "r")) == NULL) + { + if (cold) + { + ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s", + filename, strerror(errno)); + exit(-1); + } + else + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "Unable to read configuration file '%s': %s", + filename, strerror(errno)); + return; + } + } + + if (!cold) + clear_out_old_conf(); + + read_conf(conf_parser_ctx.conf_file); + fclose(conf_parser_ctx.conf_file); + + add_isupport("NETWORK", ServerInfo.network_name, -1); + snprintf(chanmodes, sizeof(chanmodes), "beI:%d", + ConfigChannel.max_bans); + add_isupport("MAXLIST", chanmodes, -1); + add_isupport("MAXTARGETS", NULL, ConfigFileEntry.max_targets); + + add_isupport("CHANTYPES", "#", -1); + + snprintf(chanlimit, sizeof(chanlimit), "#:%d", + ConfigChannel.max_chans_per_user); + add_isupport("CHANLIMIT", chanlimit, -1); + snprintf(chanmodes, sizeof(chanmodes), "%s", + "beI,k,l,imnprstORS"); + add_isupport("CHANNELLEN", NULL, LOCAL_CHANNELLEN); + + add_isupport("EXCEPTS", "e", -1); + add_isupport("INVEX", "I", -1); + add_isupport("CHANMODES", chanmodes, -1); + + /* + * message_locale may have changed. rebuild isupport since it relies + * on strlen(form_str(RPL_ISUPPORT)) + */ + rebuild_isupport_message_line(); + + parse_conf_file(KLINE_TYPE, cold); + parse_conf_file(DLINE_TYPE, cold); + parse_conf_file(XLINE_TYPE, cold); + parse_conf_file(NRESV_TYPE, cold); + parse_conf_file(CRESV_TYPE, cold); +} + +/* parse_conf_file() + * + * inputs - type of conf file to parse + * output - none + * side effects - conf file for givenconf type is opened and read then parsed + */ +static void +parse_conf_file(int type, int cold) +{ + FILE *file = NULL; + const char *filename = get_conf_name(type); + + if ((file = fopen(filename, "r")) == NULL) + { + if (cold) + ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s", + filename, strerror(errno)); + else + sendto_realops_flags(UMODE_ALL, L_ALL, + "Unable to read configuration file '%s': %s", + filename, strerror(errno)); + } + else + { + parse_csv_file(file, type); + fclose(file); + } +} + +/* clear_out_old_conf() + * + * inputs - none + * output - none + * side effects - Clear out the old configuration + */ +static void +clear_out_old_conf(void) +{ + dlink_node *ptr = NULL, *next_ptr = NULL; + struct ConfItem *conf; + struct AccessItem *aconf; + struct ClassItem *cltmp; + dlink_list *free_items [] = { + &server_items, &oconf_items, + &uconf_items, &xconf_items, &rxconf_items, &rkconf_items, + &nresv_items, &cluster_items, &service_items, NULL + }; + + dlink_list ** iterator = free_items; /* C is dumb */ + + /* We only need to free anything allocated by yyparse() here. + * Resetting structs, etc, is taken care of by set_default_conf(). + */ + + for (; *iterator != NULL; iterator++) + { + DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head) + { + conf = ptr->data; + /* XXX This is less than pretty */ + if (conf->type == SERVER_TYPE) + { + aconf = map_to_conf(conf); + + if (aconf->clients != 0) + { + SetConfIllegal(aconf); + dlinkDelete(&conf->node, &server_items); + } + else + { + delete_conf_item(conf); + } + } + else if (conf->type == OPER_TYPE) + { + aconf = map_to_conf(conf); + + if (aconf->clients != 0) + { + SetConfIllegal(aconf); + dlinkDelete(&conf->node, &oconf_items); + } + else + { + delete_conf_item(conf); + } + } + else if (conf->type == XLINE_TYPE || + conf->type == RXLINE_TYPE || + conf->type == RKLINE_TYPE) + { + /* temporary (r)xlines are also on + * the (r)xconf items list */ + if (conf->flags & CONF_FLAGS_TEMPORARY) + continue; + + delete_conf_item(conf); + } + else + { + delete_conf_item(conf); + } + } + } + + /* + * don't delete the class table, rather mark all entries + * for deletion. The table is cleaned up by check_class. - avalon + */ + DLINK_FOREACH(ptr, class_items.head) + { + cltmp = map_to_conf(ptr->data); + + if (ptr != class_items.tail) /* never mark the "default" class */ + cltmp->active = 0; + } + + clear_out_address_conf(); + + /* clean out module paths */ + mod_clear_paths(); + + /* clean out ServerInfo */ + MyFree(ServerInfo.description); + ServerInfo.description = NULL; + MyFree(ServerInfo.network_name); + ServerInfo.network_name = NULL; + MyFree(ServerInfo.network_desc); + ServerInfo.network_desc = NULL; + MyFree(ConfigFileEntry.egdpool_path); + ConfigFileEntry.egdpool_path = NULL; +#ifdef HAVE_LIBCRYPTO + if (ServerInfo.rsa_private_key != NULL) + { + RSA_free(ServerInfo.rsa_private_key); + ServerInfo.rsa_private_key = NULL; + } + + MyFree(ServerInfo.rsa_private_key_file); + ServerInfo.rsa_private_key_file = NULL; + + if (ServerInfo.server_ctx) + SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv2| + SSL_OP_NO_SSLv3| + SSL_OP_NO_TLSv1); + if (ServerInfo.client_ctx) + SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv2| + SSL_OP_NO_SSLv3| + SSL_OP_NO_TLSv1); +#endif + + /* clean out old resvs from the conf */ + clear_conf_resv(); + + /* clean out AdminInfo */ + MyFree(AdminInfo.name); + AdminInfo.name = NULL; + MyFree(AdminInfo.email); + AdminInfo.email = NULL; + MyFree(AdminInfo.description); + AdminInfo.description = NULL; + + /* operator{} and class{} blocks are freed above */ + /* clean out listeners */ + close_listeners(); + + /* auth{}, quarantine{}, shared{}, connect{}, kill{}, deny{}, + * exempt{} and gecos{} blocks are freed above too + */ + + /* clean out general */ + MyFree(ConfigFileEntry.service_name); + ConfigFileEntry.service_name = NULL; + + delete_isupport("INVEX"); + delete_isupport("EXCEPTS"); +} + +/* flush_deleted_I_P() + * + * inputs - none + * output - none + * side effects - This function removes I/P conf items + */ +static void +flush_deleted_I_P(void) +{ + dlink_node *ptr; + dlink_node *next_ptr; + struct ConfItem *conf; + struct AccessItem *aconf; + dlink_list * free_items [] = { + &server_items, &oconf_items, NULL + }; + dlink_list ** iterator = free_items; /* C is dumb */ + + /* flush out deleted I and P lines + * although still in use. + */ + for (; *iterator != NULL; iterator++) + { + DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head) + { + conf = ptr->data; + aconf = (struct AccessItem *)map_to_conf(conf); + + if (IsConfIllegal(aconf)) + { + dlinkDelete(ptr, *iterator); + + if (aconf->clients == 0) + delete_conf_item(conf); + } + } + } +} + +/* get_conf_name() + * + * inputs - type of conf file to return name of file for + * output - pointer to filename for type of conf + * side effects - none + */ +const char * +get_conf_name(ConfType type) +{ + switch (type) + { + case CONF_TYPE: + return ConfigFileEntry.configfile; + break; + case KLINE_TYPE: + return ConfigFileEntry.klinefile; + break; + case DLINE_TYPE: + return ConfigFileEntry.dlinefile; + break; + case XLINE_TYPE: + return ConfigFileEntry.xlinefile; + break; + case CRESV_TYPE: + return ConfigFileEntry.cresvfile; + break; + case NRESV_TYPE: + return ConfigFileEntry.nresvfile; + break; + default: + return NULL; /* This should NEVER HAPPEN since we call this function + only with the above values, this will cause us to core + at some point if this happens so we know where it was */ + } +} + +#define BAD_PING (-1) + +/* get_conf_ping() + * + * inputs - pointer to struct AccessItem + * - pointer to a variable that receives ping warning time + * output - ping frequency + * side effects - NONE + */ +static int +get_conf_ping(struct ConfItem *conf, int *pingwarn) +{ + struct ClassItem *aclass; + struct AccessItem *aconf; + + if (conf != NULL) + { + aconf = (struct AccessItem *)map_to_conf(conf); + if (aconf->class_ptr != NULL) + { + aclass = (struct ClassItem *)map_to_conf(aconf->class_ptr); + *pingwarn = aclass->ping_warning; + return aclass->ping_freq; + } + } + + return BAD_PING; +} + +/* get_client_class() + * + * inputs - pointer to client struct + * output - pointer to name of class + * side effects - NONE + */ +const char * +get_client_class(struct Client *target_p) +{ + dlink_node *cnode = NULL; + struct AccessItem *aconf = NULL; + + assert(!IsMe(target_p)); + + if ((cnode = target_p->localClient->confs.head)) + { + struct ConfItem *conf = cnode->data; + + assert((conf->type == CLIENT_TYPE) || (conf->type == SERVER_TYPE) || + (conf->type == OPER_TYPE)); + + aconf = map_to_conf(conf); + if (aconf->class_ptr != NULL) + return aconf->class_ptr->name; + } + + return "default"; +} + +/* get_client_ping() + * + * inputs - pointer to client struct + * - pointer to a variable that receives ping warning time + * output - ping frequency + * side effects - NONE + */ +int +get_client_ping(struct Client *target_p, int *pingwarn) +{ + int ping = 0; + dlink_node *cnode = NULL; + + if ((cnode = target_p->localClient->confs.head)) + { + struct ConfItem *conf = cnode->data; + + assert((conf->type == CLIENT_TYPE) || (conf->type == SERVER_TYPE) || + (conf->type == OPER_TYPE)); + + ping = get_conf_ping(conf, pingwarn); + if (ping > 0) + return ping; + } + + *pingwarn = 0; + return DEFAULT_PINGFREQUENCY; +} + +/* find_class() + * + * inputs - string name of class + * output - corresponding Class pointer + * side effects - NONE + */ +struct ConfItem * +find_class(const char *classname) +{ + struct ConfItem *conf; + + if ((conf = find_exact_name_conf(CLASS_TYPE, NULL, classname, NULL, NULL)) != NULL) + return conf; + + return class_default; +} + +/* check_class() + * + * inputs - NONE + * output - NONE + * side effects - + */ +void +check_class(void) +{ + dlink_node *ptr = NULL, *next_ptr = NULL; + + DLINK_FOREACH_SAFE(ptr, next_ptr, class_items.head) + { + struct ClassItem *aclass = map_to_conf(ptr->data); + + if (!aclass->active && !aclass->curr_user_count) + { + destroy_cidr_class(aclass); + delete_conf_item(ptr->data); + } + } +} + +/* init_class() + * + * inputs - NONE + * output - NONE + * side effects - + */ +void +init_class(void) +{ + struct ClassItem *aclass; + + class_default = make_conf_item(CLASS_TYPE); + + aclass = map_to_conf(class_default); + aclass->active = 1; + DupString(class_default->name, "default"); + aclass->con_freq = DEFAULT_CONNECTFREQUENCY; + aclass->ping_freq = DEFAULT_PINGFREQUENCY; + aclass->max_total = MAXIMUM_LINKS_DEFAULT; + aclass->max_sendq = DEFAULT_SENDQ; + aclass->max_recvq = DEFAULT_RECVQ; + + client_check_cb = register_callback("check_client", check_client); +} + +/* get_sendq() + * + * inputs - pointer to client + * output - sendq for this client as found from its class + * side effects - NONE + */ +unsigned int +get_sendq(struct Client *client_p) +{ + unsigned int sendq = DEFAULT_SENDQ; + dlink_node *cnode; + struct ConfItem *class_conf; + struct ClassItem *aclass; + struct AccessItem *aconf; + + assert(!IsMe(client_p)); + + if ((cnode = client_p->localClient->confs.head)) + { + struct ConfItem *conf = cnode->data; + + assert((conf->type == CLIENT_TYPE) || (conf->type == SERVER_TYPE) || + (conf->type == OPER_TYPE)); + + aconf = map_to_conf(conf); + + if ((class_conf = aconf->class_ptr) == NULL) + return DEFAULT_SENDQ; /* TBV: shouldn't be possible at all */ + + aclass = map_to_conf(class_conf); + sendq = aclass->max_sendq; + return sendq; + } + + /* XXX return a default? + * if here, then there wasn't an attached conf with a sendq + * that is very bad -Dianora + */ + return DEFAULT_SENDQ; +} + +unsigned int +get_recvq(struct Client *client_p) +{ + unsigned int recvq = DEFAULT_RECVQ; + dlink_node *cnode; + struct ConfItem *class_conf; + struct ClassItem *aclass; + struct AccessItem *aconf; + + assert(!IsMe(client_p)); + + if ((cnode = client_p->localClient->confs.head)) + { + struct ConfItem *conf = cnode->data; + + assert((conf->type == CLIENT_TYPE) || (conf->type == SERVER_TYPE) || + (conf->type == OPER_TYPE)); + + aconf = map_to_conf(conf); + + if ((class_conf = aconf->class_ptr) == NULL) + return DEFAULT_RECVQ; /* TBV: shouldn't be possible at all */ + + aclass = map_to_conf(class_conf); + recvq = aclass->max_recvq; + return recvq; + } + + /* XXX return a default? + * if here, then there wasn't an attached conf with a recvq + * that is very bad -Dianora + */ + return DEFAULT_RECVQ; +} + +/* conf_add_class_to_conf() + * + * inputs - pointer to config item + * output - NONE + * side effects - Add a class pointer to a conf + */ +void +conf_add_class_to_conf(struct ConfItem *conf, const char *class_name) +{ + struct AccessItem *aconf = map_to_conf(conf); + struct ClassItem *class = NULL; + + if (class_name == NULL) + { + aconf->class_ptr = class_default; + + if (conf->type == CLIENT_TYPE) + sendto_realops_flags(UMODE_ALL, L_ALL, + "Warning *** Defaulting to default class for %s@%s", + aconf->user, aconf->host); + else + sendto_realops_flags(UMODE_ALL, L_ALL, + "Warning *** Defaulting to default class for %s", + conf->name); + } + else + aconf->class_ptr = find_class(class_name); + + if (aconf->class_ptr) + class = map_to_conf(aconf->class_ptr); + + if (aconf->class_ptr == NULL || !class->active) + { + if (conf->type == CLIENT_TYPE) + sendto_realops_flags(UMODE_ALL, L_ALL, + "Warning *** Defaulting to default class for %s@%s", + aconf->user, aconf->host); + else + sendto_realops_flags(UMODE_ALL, L_ALL, + "Warning *** Defaulting to default class for %s", + conf->name); + aconf->class_ptr = class_default; + } +} + +/* conf_add_server() + * + * inputs - pointer to config item + * - pointer to link count already on this conf + * output - NONE + * side effects - Add a connect block + */ +int +conf_add_server(struct ConfItem *conf, const char *class_name) +{ + struct AccessItem *aconf = map_to_conf(conf); + + conf_add_class_to_conf(conf, class_name); + + if (!aconf->host || !conf->name) + { + sendto_realops_flags(UMODE_ALL, L_ALL, "Bad connect block"); + ilog(LOG_TYPE_IRCD, "Bad connect block"); + return -1; + } + + if (EmptyString(aconf->passwd)) + { + sendto_realops_flags(UMODE_ALL, L_ALL, "Bad connect block, name %s", + conf->name); + ilog(LOG_TYPE_IRCD, "Bad connect block, host %s", conf->name); + return -1; + } + + lookup_confhost(conf); + + return 0; +} + +/* yyerror() + * + * inputs - message from parser + * output - NONE + * side effects - message to opers and log file entry is made + */ +void +yyerror(const char *msg) +{ + char newlinebuf[IRCD_BUFSIZE]; + + if (conf_parser_ctx.pass != 1) + return; + + strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf)); + sendto_realops_flags(UMODE_ALL, L_ALL, "\"%s\", line %u: %s: %s", + conffilebuf, lineno + 1, msg, newlinebuf); + ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s", + conffilebuf, lineno + 1, msg, newlinebuf); +} + +/* + * valid_tkline() + * + * inputs - pointer to ascii string to check + * - whether the specified time is in seconds or minutes + * output - -1 not enough parameters + * - 0 if not an integer number, else the number + * side effects - none + * Originally written by Dianora (Diane, db@db.net) + */ +time_t +valid_tkline(const char *p, int minutes) +{ + time_t result = 0; + + for (; *p; ++p) + { + if (!IsDigit(*p)) + return 0; + + result *= 10; + result += ((*p) & 0xF); + } + + /* + * In the degenerate case where oper does a /quote kline 0 user@host :reason + * i.e. they specifically use 0, I am going to return 1 instead + * as a return value of non-zero is used to flag it as a temporary kline + */ + if (result == 0) + result = 1; + + /* + * If the incoming time is in seconds convert it to minutes for the purpose + * of this calculation + */ + if (!minutes) + result = result / (time_t)60; + + if (result > MAX_TDKLINE_TIME) + result = MAX_TDKLINE_TIME; + + result = result * (time_t)60; /* turn it into seconds */ + + return result; +} + +/* valid_wild_card() + * + * input - pointer to client + * - int flag, 0 for no warning oper 1 for warning oper + * - count of following varargs to check + * output - 0 if not valid, 1 if valid + * side effects - NOTICE is given to source_p if warn is 1 + */ +int +valid_wild_card(struct Client *source_p, int warn, int count, ...) +{ + char *p; + char tmpch; + int nonwild = 0; + va_list args; + + /* + * Now we must check the user and host to make sure there + * are at least NONWILDCHARS non-wildcard characters in + * them, otherwise assume they are attempting to kline + * *@* or some variant of that. This code will also catch + * people attempting to kline *@*.tld, as long as NONWILDCHARS + * is greater than 3. In that case, there are only 3 non-wild + * characters (tld), so if NONWILDCHARS is 4, the kline will + * be disallowed. + * -wnder + */ + + va_start(args, count); + + while (count--) + { + p = va_arg(args, char *); + if (p == NULL) + continue; + + while ((tmpch = *p++)) + { + if (!IsKWildChar(tmpch)) + { + /* + * If we find enough non-wild characters, we can + * break - no point in searching further. + */ + if (++nonwild >= ConfigFileEntry.min_nonwildcard) + return 1; + } + } + } + + if (warn) + sendto_one(source_p, ":%s NOTICE %s :Please include at least %d non-wildcard characters with the mask", + me.name, source_p->name, ConfigFileEntry.min_nonwildcard); + return 0; +} + +/* XXX should this go into a separate file ? -Dianora */ +/* parse_aline + * + * input - pointer to cmd name being used + * - pointer to client using cmd + * - parc parameter count + * - parv[] list of parameters to parse + * - parse_flags bit map of things to test + * - pointer to user or string to parse into + * - pointer to host or NULL to parse into if non NULL + * - pointer to optional tkline time or NULL + * - pointer to target_server to parse into if non NULL + * - pointer to reason to parse into + * + * output - 1 if valid, -1 if not valid + * side effects - A generalised k/d/x etc. line parser, + * "ALINE [time] user@host|string [ON] target :reason" + * will parse returning a parsed user, host if + * h_p pointer is non NULL, string otherwise. + * if tkline_time pointer is non NULL a tk line will be set + * to non zero if found. + * if tkline_time pointer is NULL and tk line is found, + * error is reported. + * if target_server is NULL and an "ON" is found error + * is reported. + * if reason pointer is NULL ignore pointer, + * this allows use of parse_a_line in unkline etc. + * + * - Dianora + */ +int +parse_aline(const char *cmd, struct Client *source_p, + int parc, char **parv, + int parse_flags, char **up_p, char **h_p, time_t *tkline_time, + char **target_server, char **reason) +{ + int found_tkline_time=0; + static char def_reason[] = "No Reason"; + static char user[USERLEN*4+1]; + static char host[HOSTLEN*4+1]; + + parv++; + parc--; + + found_tkline_time = valid_tkline(*parv, TK_MINUTES); + + if (found_tkline_time != 0) + { + parv++; + parc--; + + if (tkline_time != NULL) + *tkline_time = found_tkline_time; + else + { + sendto_one(source_p, ":%s NOTICE %s :temp_line not supported by %s", + me.name, source_p->name, cmd); + return -1; + } + } + + if (parc == 0) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, cmd); + return -1; + } + + if (h_p == NULL) + *up_p = *parv; + else + { + if (find_user_host(source_p, *parv, user, host, parse_flags) == 0) + return -1; + + *up_p = user; + *h_p = host; + } + + parc--; + parv++; + + if (parc != 0) + { + if (irccmp(*parv, "ON") == 0) + { + parc--; + parv++; + + if (target_server == NULL) + { + sendto_one(source_p, ":%s NOTICE %s :ON server not supported by %s", + me.name, source_p->name, cmd); + return -1; + } + + if (!HasOFlag(source_p, OPER_FLAG_REMOTEBAN)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "remoteban"); + return -1; + } + + if (parc == 0 || EmptyString(*parv)) + { + sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), + me.name, source_p->name, cmd); + return -1; + } + + *target_server = *parv; + parc--; + parv++; + } + else + { + /* Make sure target_server *is* NULL if no ON server found + * caller probably NULL'd it first, but no harm to do it again -db + */ + if (target_server != NULL) + *target_server = NULL; + } + } + + if (h_p != NULL) + { + if (strchr(user, '!') != NULL) + { + sendto_one(source_p, ":%s NOTICE %s :Invalid character '!' in kline", + me.name, source_p->name); + return -1; + } + + if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 2, *up_p, *h_p)) + return -1; + } + else + if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 1, *up_p)) + return -1; + + if (reason != NULL) + { + if (parc != 0 && !EmptyString(*parv)) + { + *reason = *parv; + if (!valid_comment(source_p, *reason, 1)) + return -1; + } + else + *reason = def_reason; + } + + return 1; +} + +/* find_user_host() + * + * inputs - pointer to client placing kline + * - pointer to user_host_or_nick + * - pointer to user buffer + * - pointer to host buffer + * output - 0 if not ok to kline, 1 to kline i.e. if valid user host + * side effects - + */ +static int +find_user_host(struct Client *source_p, char *user_host_or_nick, + char *luser, char *lhost, unsigned int flags) +{ + struct Client *target_p = NULL; + char *hostp = NULL; + + if (lhost == NULL) + { + strlcpy(luser, user_host_or_nick, USERLEN*4 + 1); + return 1; + } + + if ((hostp = strchr(user_host_or_nick, '@')) || *user_host_or_nick == '*') + { + /* Explicit user@host mask given */ + + if (hostp != NULL) /* I'm a little user@host */ + { + *(hostp++) = '\0'; /* short and squat */ + if (*user_host_or_nick) + strlcpy(luser, user_host_or_nick, USERLEN*4 + 1); /* here is my user */ + else + strcpy(luser, "*"); + if (*hostp) + strlcpy(lhost, hostp, HOSTLEN + 1); /* here is my host */ + else + strcpy(lhost, "*"); + } + else + { + luser[0] = '*'; /* no @ found, assume its *@somehost */ + luser[1] = '\0'; + strlcpy(lhost, user_host_or_nick, HOSTLEN*4 + 1); + } + + return 1; + } + else + { + /* Try to find user@host mask from nick */ + /* Okay to use source_p as the first param, because source_p == client_p */ + if ((target_p = + find_chasing(source_p, source_p, user_host_or_nick, NULL)) == NULL) + return 0; + + if (IsExemptKline(target_p)) + { + if (!IsServer(source_p)) + sendto_one(source_p, + ":%s NOTICE %s :%s is E-lined", + me.name, source_p->name, target_p->name); + return 0; + } + + /* + * turn the "user" bit into "*user", blow away '~' + * if found in original user name (non-idented) + */ + strlcpy(luser, target_p->username, USERLEN*4 + 1); + + if (target_p->username[0] == '~') + luser[0] = '*'; + + if (target_p->sockhost[0] == '\0' || + (target_p->sockhost[0] == '0' && target_p->sockhost[1] == '\0')) + strlcpy(lhost, target_p->host, HOSTLEN*4 + 1); + else + strlcpy(lhost, target_p->sockhost, HOSTLEN*4 + 1); + return 1; + } + + return 0; +} + +/* valid_comment() + * + * inputs - pointer to client + * - pointer to comment + * output - 0 if no valid comment, + * - 1 if valid + * side effects - truncates reason where necessary + */ +int +valid_comment(struct Client *source_p, char *comment, int warn) +{ + if (strchr(comment, '"')) + { + if (warn) + sendto_one(source_p, ":%s NOTICE %s :Invalid character '\"' in comment", + me.name, source_p->name); + return 0; + } + + if (strlen(comment) > REASONLEN) + comment[REASONLEN-1] = '\0'; + + return 1; +} + +/* match_conf_password() + * + * inputs - pointer to given password + * - pointer to Conf + * output - 1 or 0 if match + * side effects - none + */ +int +match_conf_password(const char *password, const struct AccessItem *aconf) +{ + const char *encr = NULL; + + if (EmptyString(password) || EmptyString(aconf->passwd)) + return 0; + + if (aconf->flags & CONF_FLAGS_ENCRYPTED) + encr = crypt(password, aconf->passwd); + else + encr = password; + + return !strcmp(encr, aconf->passwd); +} + +/* + * cluster_a_line + * + * inputs - client sending the cluster + * - command name "KLINE" "XLINE" etc. + * - capab -- CAP_KLN etc. from s_serv.h + * - cluster type -- CLUSTER_KLINE etc. from conf.h + * - pattern and args to send along + * output - none + * side effects - Take source_p send the pattern with args given + * along to all servers that match capab and cluster type +*/ +void +cluster_a_line(struct Client *source_p, const char *command, + int capab, int cluster_type, const char *pattern, ...) +{ + va_list args; + char buffer[IRCD_BUFSIZE]; + const dlink_node *ptr = NULL; + + va_start(args, pattern); + vsnprintf(buffer, sizeof(buffer), pattern, args); + va_end(args); + + DLINK_FOREACH(ptr, cluster_items.head) + { + const struct ConfItem *conf = ptr->data; + + if (conf->flags & cluster_type) + sendto_match_servs(source_p, conf->name, CAP_CLUSTER|capab, + "%s %s %s", command, conf->name, buffer); + } +} + +/* + * split_nuh + * + * inputs - pointer to original mask (modified in place) + * - pointer to pointer where nick should go + * - pointer to pointer where user should go + * - pointer to pointer where host should go + * output - NONE + * side effects - mask is modified in place + * If nick pointer is NULL, ignore writing to it + * this allows us to use this function elsewhere. + * + * mask nick user host + * ---------------------- ------- ------- ------ + * Dianora!db@db.net Dianora db db.net + * Dianora Dianora * * + * db.net * * db.net + * OR if nick pointer is NULL + * Dianora - * Dianora + * Dianora! Dianora * * + * Dianora!@ Dianora * * + * Dianora!db Dianora db * + * Dianora!@db.net Dianora * db.net + * db@db.net * db db.net + * !@ * * * + * @ * * * + * ! * * * + */ +void +split_nuh(struct split_nuh_item *const iptr) +{ + char *p = NULL, *q = NULL; + + if (iptr->nickptr) + strlcpy(iptr->nickptr, "*", iptr->nicksize); + if (iptr->userptr) + strlcpy(iptr->userptr, "*", iptr->usersize); + if (iptr->hostptr) + strlcpy(iptr->hostptr, "*", iptr->hostsize); + + if ((p = strchr(iptr->nuhmask, '!'))) + { + *p = '\0'; + + if (iptr->nickptr && *iptr->nuhmask != '\0') + strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize); + + if ((q = strchr(++p, '@'))) { + *q++ = '\0'; + + if (*p != '\0') + strlcpy(iptr->userptr, p, iptr->usersize); + + if (*q != '\0') + strlcpy(iptr->hostptr, q, iptr->hostsize); + } + else + { + if (*p != '\0') + strlcpy(iptr->userptr, p, iptr->usersize); + } + } + else + { + /* No ! found so lets look for a user@host */ + if ((p = strchr(iptr->nuhmask, '@'))) + { + /* if found a @ */ + *p++ = '\0'; + + if (*iptr->nuhmask != '\0') + strlcpy(iptr->userptr, iptr->nuhmask, iptr->usersize); + + if (*p != '\0') + strlcpy(iptr->hostptr, p, iptr->hostsize); + } + else + { + /* no @ found */ + if (!iptr->nickptr || strpbrk(iptr->nuhmask, ".:")) + strlcpy(iptr->hostptr, iptr->nuhmask, iptr->hostsize); + else + strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize); + } + } +} + +/* + * flags_to_ascii + * + * inputs - flags is a bitmask + * - pointer to table of ascii letters corresponding + * to each bit + * - flag 1 for convert ToLower if bit missing + * 0 if ignore. + * output - none + * side effects - string pointed to by p has bitmap chars written to it + */ +static void +flags_to_ascii(unsigned int flags, const unsigned int bit_table[], char *p, + int lowerit) +{ + unsigned int mask = 1; + int i = 0; + + for (mask = 1; (mask != 0) && (bit_table[i] != 0); mask <<= 1, i++) + { + if (flags & mask) + *p++ = bit_table[i]; + else if (lowerit) + *p++ = ToLower(bit_table[i]); + } + *p = '\0'; +} + +/* + * cidr_limit_reached + * + * inputs - int flag allowing over_rule of limits + * - pointer to the ip to be added + * - pointer to the class + * output - non zero if limit reached + * 0 if limit not reached + * side effects - + */ +static int +cidr_limit_reached(int over_rule, + struct irc_ssaddr *ip, struct ClassItem *aclass) +{ + dlink_node *ptr = NULL; + struct CidrItem *cidr; + + if (aclass->number_per_cidr <= 0) + return 0; + + if (ip->ss.ss_family == AF_INET) + { + if (aclass->cidr_bitlen_ipv4 <= 0) + return 0; + + DLINK_FOREACH(ptr, aclass->list_ipv4.head) + { + cidr = ptr->data; + if (match_ipv4(ip, &cidr->mask, aclass->cidr_bitlen_ipv4)) + { + if (!over_rule && (cidr->number_on_this_cidr >= aclass->number_per_cidr)) + return -1; + cidr->number_on_this_cidr++; + return 0; + } + } + cidr = MyMalloc(sizeof(struct CidrItem)); + cidr->number_on_this_cidr = 1; + cidr->mask = *ip; + mask_addr(&cidr->mask, aclass->cidr_bitlen_ipv4); + dlinkAdd(cidr, &cidr->node, &aclass->list_ipv4); + } +#ifdef IPV6 + else if (aclass->cidr_bitlen_ipv6 > 0) + { + DLINK_FOREACH(ptr, aclass->list_ipv6.head) + { + cidr = ptr->data; + if (match_ipv6(ip, &cidr->mask, aclass->cidr_bitlen_ipv6)) + { + if (!over_rule && (cidr->number_on_this_cidr >= aclass->number_per_cidr)) + return -1; + cidr->number_on_this_cidr++; + return 0; + } + } + cidr = MyMalloc(sizeof(struct CidrItem)); + cidr->number_on_this_cidr = 1; + cidr->mask = *ip; + mask_addr(&cidr->mask, aclass->cidr_bitlen_ipv6); + dlinkAdd(cidr, &cidr->node, &aclass->list_ipv6); + } +#endif + return 0; +} + +/* + * remove_from_cidr_check + * + * inputs - pointer to the ip to be removed + * - pointer to the class + * output - NONE + * side effects - + */ +static void +remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass) +{ + dlink_node *ptr = NULL; + dlink_node *next_ptr = NULL; + struct CidrItem *cidr; + + if (aclass->number_per_cidr == 0) + return; + + if (ip->ss.ss_family == AF_INET) + { + if (aclass->cidr_bitlen_ipv4 <= 0) + return; + + DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv4.head) + { + cidr = ptr->data; + if (match_ipv4(ip, &cidr->mask, aclass->cidr_bitlen_ipv4)) + { + cidr->number_on_this_cidr--; + if (cidr->number_on_this_cidr == 0) + { + dlinkDelete(ptr, &aclass->list_ipv4); + MyFree(cidr); + return; + } + } + } + } +#ifdef IPV6 + else if (aclass->cidr_bitlen_ipv6 > 0) + { + DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv6.head) + { + cidr = ptr->data; + if (match_ipv6(ip, &cidr->mask, aclass->cidr_bitlen_ipv6)) + { + cidr->number_on_this_cidr--; + if (cidr->number_on_this_cidr == 0) + { + dlinkDelete(ptr, &aclass->list_ipv6); + MyFree(cidr); + return; + } + } + } + } +#endif +} + +static void +rebuild_cidr_list(int aftype, struct ConfItem *oldcl, struct ClassItem *newcl, + dlink_list *old_list, dlink_list *new_list, int changed) +{ + dlink_node *ptr; + struct Client *client_p; + struct ConfItem *conf; + struct AccessItem *aconf; + + if (!changed) + { + *new_list = *old_list; + old_list->head = old_list->tail = NULL; + old_list->length = 0; + return; + } + + DLINK_FOREACH(ptr, local_client_list.head) + { + client_p = ptr->data; + if (client_p->localClient->aftype != aftype) + continue; + if (dlink_list_length(&client_p->localClient->confs) == 0) + continue; + + conf = client_p->localClient->confs.tail->data; + if (conf->type == CLIENT_TYPE) + { + aconf = map_to_conf(conf); + if (aconf->class_ptr == oldcl) + cidr_limit_reached(1, &client_p->localClient->ip, newcl); + } + } +} + +/* + * rebuild_cidr_class + * + * inputs - pointer to old conf + * - pointer to new_class + * output - none + * side effects - rebuilds the class link list of cidr blocks + */ +void +rebuild_cidr_class(struct ConfItem *conf, struct ClassItem *new_class) +{ + struct ClassItem *old_class = map_to_conf(conf); + + if (old_class->number_per_cidr > 0 && new_class->number_per_cidr > 0) + { + if (old_class->cidr_bitlen_ipv4 > 0 && new_class->cidr_bitlen_ipv4 > 0) + rebuild_cidr_list(AF_INET, conf, new_class, + &old_class->list_ipv4, &new_class->list_ipv4, + old_class->cidr_bitlen_ipv4 != new_class->cidr_bitlen_ipv4); + +#ifdef IPV6 + if (old_class->cidr_bitlen_ipv6 > 0 && new_class->cidr_bitlen_ipv6 > 0) + rebuild_cidr_list(AF_INET6, conf, new_class, + &old_class->list_ipv6, &new_class->list_ipv6, + old_class->cidr_bitlen_ipv6 != new_class->cidr_bitlen_ipv6); +#endif + } + + destroy_cidr_class(old_class); +} + +/* + * destroy_cidr_list + * + * inputs - pointer to class dlink list of cidr blocks + * output - none + * side effects - completely destroys the class link list of cidr blocks + */ +static void +destroy_cidr_list(dlink_list *list) +{ + dlink_node *ptr = NULL, *next_ptr = NULL; + + DLINK_FOREACH_SAFE(ptr, next_ptr, list->head) + { + dlinkDelete(ptr, list); + MyFree(ptr->data); + } +} + +/* + * destroy_cidr_class + * + * inputs - pointer to class + * output - none + * side effects - completely destroys the class link list of cidr blocks + */ +static void +destroy_cidr_class(struct ClassItem *aclass) +{ + destroy_cidr_list(&aclass->list_ipv4); + destroy_cidr_list(&aclass->list_ipv6); +} diff --git a/src/conf_lexer.c b/src/conf_lexer.c new file mode 100644 index 0000000..e9d42bb --- /dev/null +++ b/src/conf_lexer.c @@ -0,0 +1,4278 @@ + +#line 3 "conf_lexer.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 37 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); + +static void yyensure_buffer_stack (void ); +static void yy_load_buffer_state (void ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap() 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + +typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + (yytext_ptr) -= (yy_more_len); \ + yyleng = (size_t) (yy_cp - (yytext_ptr)); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 238 +#define YY_END_OF_BUFFER 239 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[1546] = + { 0, + 4, 4, 239, 237, 4, 3, 237, 5, 237, 237, + 6, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 4, 3, 0, 7, + 5, 236, 0, 2, 5, 6, 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, 68, 0, 230, 0, 0, 0, 0, 0, 0, + 0, 235, 0, 0, 0, 0, 0, 0, 0, 96, + + 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, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 217, 0, 0, + 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 79, 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, 203, 0, 0, 0, + 0, 0, 0, 143, 0, 0, 146, 0, 0, 0, + 0, 205, 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 164, 0, 0, 0, 0, 0, 13, + 0, 195, 225, 0, 0, 0, 0, 0, 0, 0, + 0, 216, 198, 0, 0, 28, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, + 200, 0, 0, 0, 0, 0, 0, 0, 63, 219, + + 0, 0, 0, 69, 70, 0, 0, 73, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 90, 0, 0, 0, 94, 0, 0, + 0, 0, 0, 103, 0, 0, 189, 0, 111, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, + 0, 0, 0, 0, 0, 147, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 151, 0, + 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, + 0, 215, 0, 0, 0, 9, 0, 0, 0, 224, + 0, 0, 196, 0, 0, 21, 0, 0, 199, 0, + + 0, 0, 34, 0, 0, 37, 0, 0, 0, 0, + 0, 42, 0, 44, 0, 46, 0, 0, 0, 0, + 0, 0, 218, 0, 0, 0, 0, 229, 0, 0, + 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 115, 0, 118, 0, 0, 0, 0, 0, 0, + 0, 137, 0, 0, 0, 0, 0, 0, 201, 0, + 148, 134, 0, 0, 0, 0, 0, 0, 135, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 161, 0, 0, 214, 163, 0, 0, 0, 11, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, + 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 78, 213, 80, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 233, 0, 0, 221, 0, 188, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 106, 0, 0, + + 0, 0, 0, 0, 114, 0, 0, 119, 120, 0, + 0, 0, 0, 0, 223, 0, 138, 0, 0, 144, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 153, 204, 0, 0, 0, 192, + 0, 0, 0, 162, 210, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 18, 0, 22, 23, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 0, 0, 53, 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, 220, 0, 187, 202, 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, 122, 0, 0, 0, 0, 222, + 0, 0, 0, 141, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 155, 154, 0, 191, 157, 0, 0, + 0, 0, 0, 0, 0, 14, 211, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 65, 0, 0, 0, 0, 227, 0, + 0, 0, 0, 0, 186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 100, 0, 105, 0, 207, 0, + 0, 0, 0, 107, 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, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 209, 0, + 0, 226, 0, 0, 77, 0, 0, 0, 0, 0, + 82, 83, 0, 0, 0, 86, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 182, 0, 109, 0, 0, 0, 116, 117, + 121, 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, 156, 0, + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + + 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 166, 0, 0, 84, 0, 0, 85, 0, + 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, + 0, 0, 0, 0, 0, 139, 140, 0, 208, 145, + 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, 24, 0, 0, 29, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 59, 0, 0, 0, 0, 0, + 0, 0, 184, 175, 0, 81, 0, 0, 190, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 194, 0, 108, 0, 0, 0, 125, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 31, 0, 0, 0, 36, 39, 0, 0, 0, 47, + 48, 0, 0, 0, 61, 0, 0, 0, 0, 0, + + 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, + 92, 93, 95, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 110, 113, 0, 0, 0, 0, 0, 212, + 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 173, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 0, 43, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 170, 0, 0, 91, 0, 0, + 99, 0, 102, 0, 0, 0, 0, 0, 0, 0, + 136, 142, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 159, 0, 0, 174, 176, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 49, 51, 0, + 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, + 0, 87, 0, 0, 0, 0, 0, 0, 104, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8, 171, 0, 0, 0, + 0, 0, 0, 0, 0, 52, 0, 0, 60, 66, + 0, 0, 72, 0, 0, 0, 0, 0, 88, 0, + 0, 101, 0, 0, 0, 0, 0, 0, 0, 133, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 19, 20, 0, 0, 0, 0, 0, 0, 0, + 57, 0, 71, 0, 0, 0, 0, 167, 0, 0, + 98, 0, 193, 183, 0, 0, 0, 0, 0, 0, + 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 123, 0, 0, 0, 130, 132, + 131, 180, 179, 178, 181, 0, 0, 0, 25, 0, + 0, 0, 0, 165, 0, 0, 0, 0, 168, 169, + 0, 97, 0, 0, 0, 0, 0, 152, 0, 0, + 0, 0, 0, 0, 0, 0, 185, 0, 0, 0, + + 127, 0, 0, 0, 0, 0, 0, 0, 0, 67, + 0, 0, 0, 126, 129, 0, 0, 0, 0, 32, + 0, 0, 74, 0, 17, 150, 0, 0, 0, 0, + 50, 89, 0, 0, 0, 33, 0, 0, 27, 0, + 0, 0, 26, 172, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 4, 5, 1, 1, 1, 1, 1, + 1, 6, 1, 1, 1, 7, 8, 9, 10, 9, + 11, 12, 9, 13, 9, 9, 9, 1, 1, 14, + 1, 15, 1, 1, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 1, 1, 1, 1, 42, 1, 43, 44, 45, 46, + + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[69] = + { 0, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[1551] = + { 0, + 0, 0, 2962, 2963, 2959, 0, 66, 0, 64, 66, + 66, 98, 43, 146, 75, 58, 85, 76, 117, 109, + 51, 154, 155, 197, 239, 53, 177, 57, 125, 283, + 323, 190, 127, 168, 128, 143, 2958, 0, 86, 2963, + 0, 2963, 166, 2963, 0, 220, 181, 181, 181, 196, + 190, 200, 202, 203, 220, 209, 237, 237, 242, 231, + 221, 326, 247, 244, 235, 252, 256, 255, 292, 253, + 262, 276, 266, 303, 301, 264, 292, 290, 318, 332, + 327, 328, 342, 327, 341, 347, 342, 359, 351, 378, + 347, 338, 367, 350, 378, 375, 381, 390, 391, 2917, + + 383, 394, 399, 386, 385, 405, 446, 403, 422, 433, + 413, 396, 405, 443, 412, 427, 417, 431, 438, 439, + 2916, 448, 456, 498, 468, 463, 476, 474, 481, 474, + 493, 492, 492, 478, 2963, 495, 499, 489, 506, 500, + 2915, 499, 504, 501, 506, 508, 518, 514, 536, 523, + 546, 523, 547, 2963, 550, 539, 536, 540, 548, 540, + 556, 549, 558, 552, 560, 559, 555, 553, 565, 558, + 571, 571, 582, 561, 578, 2914, 583, 592, 144, 588, + 584, 595, 591, 606, 605, 601, 595, 601, 2963, 606, + 2913, 598, 618, 601, 600, 601, 619, 625, 626, 610, + + 624, 649, 638, 623, 645, 635, 647, 649, 638, 643, + 658, 646, 644, 661, 666, 671, 2963, 658, 654, 2912, + 660, 674, 658, 2963, 666, 669, 2963, 684, 682, 675, + 689, 2963, 686, 686, 694, 701, 690, 710, 704, 713, + 715, 699, 711, 712, 716, 721, 716, 711, 711, 720, + 720, 729, 727, 2963, 731, 732, 735, 742, 2911, 2963, + 757, 2963, 743, 758, 758, 751, 752, 2910, 750, 751, + 767, 2963, 2963, 766, 753, 2963, 759, 776, 774, 2909, + 765, 769, 757, 778, 768, 768, 783, 2963, 775, 775, + 2963, 778, 784, 798, 811, 800, 811, 2908, 2963, 798, + + 805, 801, 801, 2963, 2963, 2907, 818, 2906, 823, 823, + 820, 2905, 813, 828, 818, 830, 862, 835, 846, 850, + 834, 842, 845, 2963, 852, 2904, 853, 2903, 852, 857, + 857, 868, 874, 888, 2902, 863, 2963, 2901, 2963, 886, + 874, 887, 888, 890, 886, 898, 898, 918, 2900, 904, + 908, 906, 934, 919, 905, 2963, 914, 924, 922, 2930, + 937, 911, 911, 928, 2930, 2897, 958, 959, 2963, 956, + 942, 955, 956, 958, 953, 964, 2963, 969, 956, 962, + 2896, 959, 974, 959, 962, 975, 980, 976, 978, 2963, + 976, 984, 2895, 992, 1000, 2963, 1005, 1010, 2963, 1002, + + 1006, 1004, 2963, 1009, 1004, 2963, 1009, 1022, 1007, 1014, + 1026, 2963, 1026, 2963, 1031, 2894, 1021, 1018, 1015, 1027, + 1024, 1020, 2963, 1043, 1042, 1039, 1043, 1031, 1048, 1031, + 2893, 2892, 1051, 2891, 1053, 1049, 1065, 1067, 1071, 1072, + 1061, 1075, 1066, 1077, 1081, 1084, 1068, 1063, 1082, 1085, + 1077, 1088, 1094, 1094, 1084, 1101, 1100, 1109, 1116, 1110, + 1105, 1104, 2890, 1125, 1118, 1104, 1131, 1135, 1122, 2889, + 1126, 2963, 1125, 2963, 1134, 1138, 1129, 1143, 1151, 1154, + 1153, 2963, 1143, 1146, 1173, 1162, 1174, 2888, 2963, 1179, + 2887, 2963, 1183, 1173, 1182, 2886, 1169, 1185, 2963, 1179, + + 1170, 1178, 1178, 1190, 1186, 1187, 1197, 1187, 1196, 1204, + 1197, 2914, 1197, 1204, 2963, 2963, 1222, 2884, 1210, 2963, + 1221, 1215, 1218, 1225, 1220, 1235, 1230, 1234, 1226, 1226, + 1227, 1232, 1244, 1236, 1239, 1234, 2883, 2963, 1254, 2882, + 1246, 1251, 1275, 2881, 1245, 2880, 1261, 2879, 1267, 1248, + 2878, 1282, 1273, 2963, 1278, 1269, 1290, 1292, 1296, 1294, + 2963, 2963, 2963, 1297, 1287, 1301, 1294, 1289, 1300, 1305, + 1306, 1301, 1299, 1298, 2963, 1299, 1316, 1307, 1319, 1315, + 1332, 1334, 1338, 1329, 1334, 1342, 1333, 1331, 1346, 2877, + 1336, 1350, 1342, 1341, 1355, 1344, 1357, 2963, 1341, 1347, + + 1354, 1367, 1351, 1357, 2963, 1358, 1370, 2963, 1378, 1367, + 1385, 1367, 1383, 1391, 1375, 1395, 1395, 1392, 1381, 2963, + 1392, 1394, 1394, 1391, 1394, 1402, 2876, 1394, 1435, 1404, + 2875, 1407, 2874, 1411, 2963, 2963, 1421, 1422, 1409, 2963, + 1429, 1437, 1435, 2963, 2963, 1430, 1442, 1432, 1435, 1454, + 1457, 1445, 1456, 1453, 1448, 1443, 2963, 1445, 2963, 1460, + 2873, 1450, 2872, 2871, 2870, 1471, 1467, 1468, 1466, 2869, + 2963, 1462, 1474, 1485, 1490, 1485, 2963, 1481, 1495, 1487, + 1484, 1489, 1494, 1507, 1499, 1497, 1512, 1509, 1492, 1512, + 1499, 1514, 1515, 1505, 1516, 1528, 1532, 1521, 1536, 1531, + + 1546, 1542, 1547, 1547, 2868, 2963, 1530, 2963, 2963, 1549, + 1536, 2867, 1555, 1538, 2866, 2865, 1554, 1547, 1547, 1541, + 1555, 1556, 1551, 1556, 1563, 1569, 1559, 1565, 1566, 1578, + 1574, 1571, 1573, 1595, 2963, 1582, 1598, 1582, 1594, 2963, + 1588, 1599, 1595, 1591, 1603, 1598, 1605, 1604, 1600, 1613, + 1617, 1608, 1603, 2864, 2863, 2862, 2861, 2860, 1621, 1622, + 2859, 1624, 2858, 2963, 2963, 1627, 2963, 2963, 1631, 2857, + 90, 1640, 1624, 1632, 1632, 2963, 2963, 1646, 1652, 1645, + 1646, 1642, 1655, 1653, 1672, 1655, 1650, 1663, 1662, 2963, + 1659, 1664, 1661, 1679, 1676, 1668, 1669, 1683, 1690, 1682, + + 1696, 1677, 1689, 2963, 1695, 1706, 1697, 1695, 1696, 1711, + 1706, 1709, 1709, 1709, 2963, 1708, 1714, 1728, 1710, 1720, + 2856, 1728, 1729, 1727, 1717, 1728, 1735, 1732, 1730, 1754, + 1736, 1746, 1738, 1758, 2963, 1760, 2963, 1750, 2963, 1744, + 1751, 1768, 1754, 2963, 1764, 1774, 1767, 1768, 2855, 1763, + 1762, 1772, 2854, 1774, 1787, 1780, 1771, 1790, 1792, 2853, + 1797, 1783, 1799, 1785, 1798, 1807, 1804, 1818, 1815, 1818, + 1808, 1809, 1811, 1813, 2852, 1805, 1818, 1830, 1832, 1833, + 1829, 1826, 190, 2889, 2877, 1822, 1841, 2849, 2848, 2847, + 2963, 1831, 1839, 1843, 1840, 1838, 1842, 1837, 1858, 1856, + + 1862, 1871, 2963, 1860, 1869, 1867, 1876, 1876, 1867, 2846, + 1861, 1871, 1886, 1869, 1877, 1886, 1886, 1887, 2845, 1891, + 1891, 2963, 1884, 1897, 2963, 1901, 1886, 2844, 1888, 1899, + 2963, 2963, 1910, 1894, 1895, 2963, 2963, 1905, 1914, 1907, + 1905, 1926, 1931, 1927, 2843, 1922, 1925, 1923, 1942, 2842, + 2841, 1939, 2840, 1936, 2963, 1937, 1943, 1947, 2963, 2963, + 2963, 1947, 1935, 1932, 1953, 1937, 1957, 1950, 1952, 1962, + 1965, 1956, 1971, 1975, 1964, 1964, 1967, 1968, 1979, 1974, + 1975, 1979, 1981, 1978, 1983, 1984, 1990, 1998, 2963, 1990, + 1993, 2877, 2876, 2864, 2863, 1987, 1990, 2008, 2011, 1996, + + 2963, 2006, 2004, 2008, 2016, 2020, 2015, 2025, 2025, 2034, + 2020, 2033, 2026, 2031, 2029, 2039, 2036, 2050, 2049, 2044, + 2053, 2963, 2053, 2041, 2832, 2039, 2049, 2828, 2827, 2052, + 2045, 2048, 2963, 2058, 2056, 2963, 2069, 2073, 2963, 2069, + 2086, 2086, 2963, 2077, 2074, 2081, 2091, 2083, 2825, 2084, + 2823, 2084, 2084, 2088, 2088, 2089, 2105, 2097, 2963, 2111, + 2105, 2094, 2113, 2822, 2107, 2963, 2963, 2123, 2963, 2963, + 2118, 2125, 2120, 2821, 2819, 2130, 2818, 2117, 2137, 2138, + 2139, 2141, 2138, 2139, 2145, 2132, 2141, 2150, 2150, 2137, + 2146, 2150, 2140, 2164, 2817, 2963, 2151, 2158, 2963, 2160, + + 2167, 2161, 2164, 2173, 2162, 2811, 2172, 2176, 2185, 2176, + 2188, 2179, 2963, 2808, 2963, 2187, 2191, 2182, 2188, 2201, + 2187, 2191, 1636, 2963, 2208, 2963, 2214, 2203, 2963, 2217, + 2216, 2202, 2219, 2221, 2211, 2218, 2216, 2221, 2241, 2218, + 2226, 2236, 2963, 2242, 2963, 2245, 2240, 2254, 2963, 1390, + 2245, 2240, 2247, 2257, 2260, 2264, 2257, 2257, 2259, 2260, + 2273, 2257, 2258, 2262, 2266, 2273, 2271, 2272, 2290, 2273, + 2963, 2281, 2283, 2286, 2290, 2297, 2299, 2300, 2306, 2292, + 2963, 1386, 2294, 2295, 2963, 2963, 2305, 2302, 2308, 2963, + 2963, 2320, 2306, 2324, 2963, 2319, 2313, 1239, 861, 2315, + + 2325, 2329, 2963, 2337, 2325, 2330, 2340, 2335, 2348, 2348, + 2963, 2963, 2963, 853, 2342, 2355, 2351, 2346, 822, 2348, + 2345, 2353, 2963, 2963, 2354, 2358, 2368, 2371, 2372, 2963, + 2963, 2377, 2371, 2376, 815, 2377, 2381, 811, 810, 809, + 462, 2379, 2383, 455, 2963, 2391, 2389, 2379, 2963, 2383, + 2379, 2381, 2387, 2403, 445, 2409, 2408, 2963, 2399, 2963, + 2402, 2399, 393, 2403, 2404, 2403, 2403, 2424, 2408, 2418, + 2419, 2426, 380, 2428, 2963, 2431, 2419, 2963, 2419, 2430, + 2963, 2442, 2963, 2445, 2447, 2430, 2437, 2441, 2452, 2435, + 2963, 2963, 2446, 2448, 2448, 2464, 2451, 2460, 2459, 2461, + + 2462, 2466, 2963, 287, 2477, 2963, 2963, 2481, 2482, 273, + 2963, 2466, 2474, 2471, 2483, 249, 2476, 2963, 266, 2496, + 2488, 2486, 2963, 2487, 2492, 2495, 2506, 2509, 2519, 2507, + 2516, 2963, 2520, 2509, 2517, 2512, 2530, 2530, 2963, 2525, + 2534, 2515, 200, 2537, 2523, 2536, 2536, 2538, 2545, 2540, + 2542, 2545, 2546, 2547, 2551, 2963, 2963, 2552, 310, 2547, + 2569, 2556, 2575, 2575, 2570, 2963, 2559, 2576, 2963, 2963, + 2570, 2565, 2963, 145, 2575, 2575, 2574, 2575, 124, 2584, + 2577, 2963, 2586, 2580, 2595, 2592, 109, 2602, 107, 2963, + 2595, 2601, 2599, 2611, 2605, 2607, 2610, 2616, 2614, 2615, + + 2627, 2963, 2963, 2619, 2616, 2631, 2624, 2624, 2640, 2627, + 2963, 2633, 2963, 2636, 2636, 2646, 2647, 2963, 2634, 2645, + 2963, 2646, 2963, 2963, 2643, 2658, 2658, 2662, 2665, 2666, + 2669, 2963, 2651, 2657, 2658, 2659, 2666, 2672, 2669, 2670, + 2670, 2675, 2683, 2686, 2696, 2701, 2699, 2696, 2701, 2689, + 2690, 2703, 2696, 2713, 2963, 2712, 2710, 2714, 2963, 2963, + 2963, 2963, 2963, 2963, 2963, 2716, 2723, 2711, 2963, 2731, + 100, 2732, 2725, 2963, 2720, 2738, 2729, 2732, 2963, 2963, + 2733, 2963, 2729, 2739, 2748, 2743, 2753, 2963, 2757, 2741, + 2757, 2749, 2761, 2757, 2750, 2763, 2963, 2759, 2767, 2772, + + 2963, 2774, 2776, 2777, 95, 2775, 2772, 2778, 2779, 2963, + 2775, 2784, 2794, 2963, 2963, 2781, 2796, 2802, 2786, 2963, + 2805, 2796, 2963, 2807, 2963, 2963, 93, 2798, 2800, 2796, + 2963, 2963, 2796, 2799, 2804, 2963, 2817, 2815, 2963, 2817, + 2811, 2828, 2963, 2963, 2963, 105, 2875, 97, 84, 81 + } ; + +static yyconst flex_int16_t yy_def[1551] = + { 0, + 1545, 1, 1545, 1545, 1545, 1546, 1547, 1548, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1546, 1547, 1545, + 1548, 1545, 1545, 1545, 1548, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1549, 1550, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1549, 1549, 1550, 1550, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 0, 1545, 1545, 1545, 1545, 1545 + } ; + +static yyconst flex_int16_t yy_nxt[3032] = + { 0, + 4, 5, 6, 7, 8, 4, 9, 10, 11, 11, + 11, 11, 11, 4, 4, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 4, 4, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 4, 40, 40, + 42, 44, 53, 45, 46, 46, 46, 46, 46, 66, + 83, 994, 54, 102, 992, 67, 68, 43, 40, 40, + 61, 883, 106, 884, 62, 74, 69, 41, 63, 53, + + 70, 64, 75, 885, 65, 38, 66, 83, 71, 54, + 102, 72, 67, 68, 43, 47, 48, 61, 49, 106, + 73, 62, 74, 69, 50, 63, 51, 70, 64, 75, + 80, 65, 76, 52, 1533, 71, 1518, 81, 72, 82, + 77, 1491, 47, 48, 107, 49, 78, 73, 1428, 126, + 1426, 50, 79, 51, 129, 304, 305, 80, 108, 76, + 52, 55, 130, 56, 81, 1419, 82, 77, 57, 58, + 84, 107, 59, 78, 88, 60, 126, 85, 89, 79, + 86, 129, 87, 127, 90, 108, 1414, 128, 55, 130, + 56, 883, 103, 884, 131, 57, 58, 84, 132, 59, + + 104, 88, 60, 885, 85, 89, 105, 86, 133, 87, + 127, 90, 91, 92, 128, 134, 93, 123, 124, 103, + 94, 131, 135, 125, 136, 132, 95, 104, 46, 46, + 46, 46, 46, 105, 137, 133, 138, 139, 142, 91, + 92, 1388, 134, 93, 123, 124, 140, 94, 141, 135, + 125, 136, 143, 95, 96, 144, 97, 145, 98, 147, + 148, 137, 99, 138, 139, 142, 154, 156, 100, 157, + 158, 159, 160, 140, 101, 141, 164, 146, 1366, 143, + 155, 96, 144, 97, 145, 98, 147, 148, 165, 99, + 1364, 166, 167, 154, 156, 100, 157, 158, 159, 160, + + 172, 101, 109, 164, 146, 110, 111, 155, 112, 161, + 173, 162, 113, 114, 1358, 165, 115, 116, 166, 167, + 168, 1402, 1403, 174, 170, 175, 163, 172, 1354, 109, + 171, 169, 110, 111, 176, 112, 161, 173, 162, 113, + 114, 149, 150, 115, 116, 117, 151, 168, 118, 119, + 174, 170, 175, 163, 152, 120, 121, 171, 169, 153, + 177, 176, 122, 178, 179, 180, 181, 182, 149, 150, + 183, 184, 117, 151, 185, 118, 119, 192, 195, 186, + 190, 152, 120, 121, 187, 191, 153, 177, 193, 122, + 178, 179, 180, 181, 182, 188, 196, 183, 184, 189, + + 194, 185, 197, 198, 192, 195, 186, 190, 201, 199, + 203, 187, 191, 204, 208, 193, 205, 209, 220, 229, + 210, 1330, 188, 196, 200, 230, 189, 194, 211, 197, + 198, 227, 206, 207, 1320, 201, 199, 203, 233, 221, + 204, 208, 234, 205, 209, 220, 229, 210, 225, 235, + 222, 200, 230, 228, 223, 211, 224, 236, 227, 206, + 207, 212, 226, 213, 214, 233, 221, 215, 216, 234, + 217, 237, 231, 218, 238, 225, 235, 222, 240, 219, + 228, 223, 232, 224, 236, 241, 1314, 248, 212, 226, + 213, 214, 249, 252, 215, 216, 1305, 217, 237, 231, + + 218, 238, 250, 1302, 253, 240, 219, 254, 251, 232, + 255, 256, 241, 242, 248, 257, 243, 258, 259, 249, + 252, 260, 262, 244, 245, 263, 264, 266, 261, 250, + 246, 253, 267, 268, 254, 251, 247, 255, 256, 269, + 242, 270, 257, 243, 258, 259, 271, 272, 260, 262, + 244, 245, 263, 264, 266, 261, 273, 246, 274, 267, + 268, 275, 276, 247, 277, 278, 269, 279, 270, 280, + 281, 282, 283, 271, 272, 284, 285, 286, 287, 288, + 289, 291, 292, 273, 293, 274, 294, 295, 275, 276, + 296, 277, 278, 290, 279, 299, 280, 281, 282, 283, + + 297, 298, 284, 285, 286, 287, 288, 289, 291, 292, + 300, 293, 302, 294, 295, 303, 306, 296, 307, 310, + 290, 308, 299, 311, 309, 312, 313, 297, 298, 314, + 315, 316, 318, 319, 320, 321, 323, 300, 324, 302, + 325, 322, 303, 306, 326, 307, 310, 327, 308, 328, + 311, 309, 312, 313, 333, 334, 314, 315, 316, 318, + 319, 320, 321, 323, 335, 324, 329, 325, 336, 337, + 338, 326, 339, 330, 327, 340, 328, 341, 331, 342, + 343, 333, 334, 332, 344, 345, 346, 347, 348, 351, + 349, 335, 352, 329, 353, 336, 337, 338, 354, 339, + + 330, 355, 340, 356, 341, 331, 342, 343, 357, 358, + 332, 344, 345, 346, 347, 348, 351, 349, 359, 352, + 362, 353, 360, 363, 364, 354, 365, 361, 355, 366, + 356, 367, 369, 370, 371, 357, 358, 372, 373, 374, + 375, 368, 376, 377, 379, 359, 380, 362, 381, 360, + 363, 364, 378, 365, 382, 383, 366, 384, 367, 369, + 370, 371, 385, 386, 372, 373, 374, 375, 368, 376, + 377, 379, 387, 380, 389, 381, 390, 391, 392, 393, + 394, 382, 383, 396, 384, 397, 398, 399, 400, 385, + 386, 401, 402, 403, 405, 406, 407, 408, 409, 387, + + 410, 389, 411, 390, 391, 392, 393, 394, 412, 413, + 396, 414, 397, 398, 399, 400, 415, 416, 401, 402, + 403, 405, 406, 407, 408, 409, 417, 410, 419, 411, + 421, 423, 424, 425, 426, 412, 413, 428, 414, 430, + 418, 420, 431, 415, 416, 432, 434, 435, 436, 437, + 1301, 1300, 1299, 417, 447, 419, 1296, 421, 423, 424, + 425, 426, 448, 1284, 428, 449, 430, 418, 450, 431, + 451, 452, 432, 434, 435, 436, 437, 438, 439, 440, + 453, 447, 455, 441, 457, 442, 458, 459, 443, 448, + 444, 460, 449, 461, 1279, 450, 445, 451, 452, 446, + + 467, 469, 1268, 462, 438, 439, 440, 453, 470, 455, + 441, 457, 442, 458, 459, 443, 471, 444, 460, 472, + 461, 463, 473, 445, 474, 464, 446, 467, 469, 465, + 462, 475, 476, 477, 480, 470, 481, 482, 487, 488, + 489, 490, 491, 471, 496, 497, 472, 483, 463, 473, + 478, 474, 464, 484, 493, 494, 498, 485, 475, 476, + 477, 480, 486, 481, 482, 487, 488, 489, 490, 491, + 495, 496, 497, 501, 502, 503, 504, 478, 505, 506, + 484, 493, 494, 498, 485, 507, 508, 509, 510, 486, + 512, 513, 515, 516, 517, 511, 518, 495, 519, 520, + + 501, 502, 503, 504, 521, 505, 506, 523, 524, 522, + 525, 527, 507, 508, 509, 510, 528, 512, 513, 515, + 516, 517, 511, 518, 529, 519, 520, 530, 531, 532, + 533, 521, 534, 535, 523, 524, 522, 525, 527, 536, + 537, 538, 539, 528, 540, 541, 542, 544, 545, 546, + 547, 529, 548, 549, 530, 531, 532, 533, 550, 534, + 535, 551, 552, 553, 554, 555, 536, 537, 538, 539, + 556, 540, 541, 542, 544, 545, 546, 547, 559, 548, + 549, 561, 562, 563, 564, 550, 565, 568, 551, 552, + 553, 554, 555, 569, 566, 570, 573, 556, 567, 574, + + 571, 575, 576, 577, 578, 559, 579, 580, 561, 562, + 563, 564, 572, 565, 568, 581, 584, 582, 585, 586, + 569, 566, 570, 573, 583, 567, 574, 571, 575, 576, + 577, 578, 587, 579, 580, 588, 589, 590, 591, 572, + 593, 597, 581, 584, 582, 585, 586, 594, 595, 598, + 603, 583, 600, 596, 605, 606, 608, 609, 607, 587, + 599, 610, 588, 589, 590, 591, 611, 593, 597, 601, + 612, 615, 602, 616, 594, 595, 598, 603, 617, 600, + 596, 605, 606, 608, 609, 607, 613, 599, 610, 614, + 618, 619, 620, 611, 622, 627, 601, 612, 615, 602, + + 616, 628, 624, 630, 631, 617, 625, 632, 633, 626, + 634, 635, 636, 613, 637, 638, 614, 618, 619, 620, + 639, 622, 627, 640, 641, 642, 643, 645, 628, 624, + 630, 631, 646, 625, 632, 633, 626, 634, 635, 636, + 647, 637, 638, 649, 650, 651, 652, 639, 653, 655, + 640, 641, 642, 643, 645, 656, 657, 658, 659, 646, + 660, 661, 662, 663, 664, 665, 654, 647, 666, 668, + 649, 650, 651, 652, 670, 653, 655, 671, 677, 679, + 1267, 683, 656, 657, 658, 659, 681, 660, 661, 662, + 663, 664, 665, 672, 673, 666, 668, 682, 685, 686, + + 687, 670, 674, 688, 671, 677, 679, 675, 683, 689, + 690, 691, 692, 681, 693, 694, 695, 696, 697, 698, + 672, 673, 699, 700, 682, 685, 686, 687, 701, 674, + 688, 702, 703, 704, 675, 705, 689, 690, 691, 692, + 706, 693, 694, 695, 696, 697, 698, 707, 708, 699, + 700, 709, 710, 711, 712, 701, 713, 714, 702, 703, + 704, 715, 705, 716, 717, 719, 720, 706, 721, 722, + 723, 724, 725, 726, 707, 708, 727, 728, 709, 710, + 711, 712, 729, 713, 714, 730, 731, 732, 715, 733, + 716, 717, 719, 720, 734, 721, 722, 723, 724, 725, + + 726, 735, 736, 727, 728, 737, 738, 739, 740, 729, + 741, 744, 730, 731, 732, 745, 733, 742, 743, 746, + 747, 734, 748, 749, 750, 751, 753, 1256, 735, 736, + 759, 1226, 737, 738, 739, 740, 761, 741, 744, 763, + 764, 765, 745, 766, 742, 743, 746, 747, 767, 748, + 749, 750, 751, 753, 754, 768, 769, 759, 755, 770, + 756, 771, 772, 761, 757, 758, 763, 764, 765, 773, + 766, 774, 775, 776, 777, 767, 778, 779, 780, 781, + 782, 754, 768, 769, 784, 755, 770, 756, 771, 772, + 788, 757, 758, 789, 790, 791, 773, 793, 774, 775, + + 776, 777, 794, 778, 779, 780, 781, 782, 796, 797, + 798, 784, 795, 799, 800, 801, 802, 788, 803, 804, + 789, 790, 791, 805, 793, 806, 807, 808, 809, 794, + 810, 811, 812, 813, 814, 796, 797, 798, 815, 795, + 799, 800, 801, 802, 816, 803, 804, 817, 818, 819, + 805, 820, 806, 807, 808, 809, 821, 810, 811, 812, + 813, 814, 822, 823, 824, 815, 825, 827, 828, 829, + 831, 816, 832, 835, 817, 818, 819, 836, 820, 837, + 838, 839, 840, 821, 841, 842, 843, 844, 845, 822, + 823, 824, 846, 825, 827, 828, 829, 831, 847, 832, + + 835, 848, 849, 850, 836, 851, 837, 838, 839, 840, + 852, 841, 842, 843, 844, 845, 853, 854, 855, 846, + 856, 857, 858, 859, 860, 847, 861, 862, 848, 849, + 850, 863, 851, 864, 865, 866, 867, 852, 868, 869, + 875, 876, 878, 853, 854, 855, 880, 856, 857, 858, + 859, 860, 881, 861, 862, 886, 887, 888, 863, 889, + 864, 865, 866, 867, 890, 868, 869, 875, 876, 878, + 891, 892, 893, 880, 894, 895, 897, 1204, 901, 881, + 902, 903, 886, 887, 888, 904, 889, 898, 896, 905, + 906, 890, 899, 907, 908, 909, 910, 891, 892, 893, + + 911, 894, 895, 897, 900, 901, 912, 902, 903, 913, + 914, 915, 904, 916, 898, 896, 905, 906, 917, 899, + 907, 908, 909, 910, 918, 919, 920, 911, 921, 922, + 923, 900, 924, 912, 925, 926, 913, 914, 915, 927, + 916, 928, 929, 930, 931, 917, 932, 934, 935, 936, + 937, 918, 919, 920, 938, 921, 922, 923, 939, 924, + 940, 925, 926, 941, 944, 945, 927, 946, 928, 929, + 930, 931, 942, 932, 934, 935, 936, 937, 947, 948, + 949, 938, 943, 950, 951, 939, 952, 940, 953, 954, + 941, 944, 945, 955, 946, 956, 957, 959, 960, 942, + + 961, 963, 964, 965, 966, 947, 948, 949, 967, 943, + 950, 951, 968, 952, 970, 953, 954, 971, 972, 973, + 955, 974, 956, 957, 959, 960, 975, 961, 963, 964, + 965, 966, 976, 977, 978, 967, 979, 980, 981, 968, + 982, 970, 983, 985, 971, 972, 973, 986, 974, 987, + 988, 989, 990, 975, 991, 996, 997, 1001, 1002, 976, + 977, 978, 1003, 979, 980, 981, 1004, 982, 1005, 983, + 985, 1006, 1007, 1008, 986, 1009, 987, 988, 989, 990, + 1010, 991, 996, 997, 1001, 1002, 1011, 1012, 1013, 1003, + 1014, 1015, 1016, 1004, 1017, 1005, 1019, 1020, 1006, 1007, + + 1008, 1021, 1009, 1022, 1023, 1024, 1025, 1010, 1026, 1028, + 1029, 1030, 1031, 1011, 1012, 1013, 1032, 1014, 1015, 1016, + 1033, 1017, 1035, 1019, 1020, 1036, 1039, 1037, 1021, 1040, + 1022, 1023, 1024, 1025, 1041, 1026, 1028, 1029, 1030, 1031, + 1042, 1043, 1044, 1032, 1038, 1045, 1046, 1033, 1047, 1035, + 1049, 1050, 1036, 1039, 1037, 1051, 1040, 1052, 1055, 1057, + 1058, 1041, 1059, 1060, 1061, 1062, 1063, 1042, 1043, 1044, + 1064, 1038, 1045, 1046, 1065, 1047, 1066, 1049, 1050, 1067, + 1068, 1069, 1051, 1070, 1052, 1055, 1057, 1058, 1071, 1059, + 1060, 1061, 1062, 1063, 1072, 1073, 1074, 1064, 1075, 1076, + + 1077, 1065, 1078, 1066, 1079, 1080, 1067, 1068, 1069, 1081, + 1070, 1082, 1083, 1084, 1085, 1071, 1086, 1087, 1088, 1089, + 1090, 1072, 1073, 1074, 1091, 1075, 1076, 1077, 1092, 1078, + 1093, 1079, 1080, 1094, 1095, 1096, 1081, 1097, 1082, 1083, + 1084, 1085, 1098, 1086, 1087, 1088, 1089, 1090, 1099, 1100, + 1101, 1091, 1102, 1103, 1104, 1092, 1105, 1093, 1106, 1107, + 1094, 1095, 1096, 1108, 1097, 1109, 1110, 1111, 1112, 1098, + 1113, 1114, 1115, 1116, 1118, 1099, 1100, 1101, 1119, 1102, + 1103, 1104, 1122, 1105, 1123, 1106, 1107, 1124, 1125, 1126, + 1108, 1127, 1109, 1110, 1111, 1112, 1128, 1113, 1114, 1115, + + 1116, 1118, 1129, 1130, 1131, 1119, 1132, 1133, 1134, 1122, + 1135, 1123, 1136, 1138, 1124, 1125, 1126, 1140, 1127, 1141, + 1142, 1143, 1144, 1128, 1145, 1146, 1147, 1148, 1149, 1129, + 1130, 1131, 1150, 1132, 1133, 1134, 1152, 1135, 1153, 1136, + 1138, 1154, 1155, 1156, 1140, 1159, 1141, 1142, 1143, 1144, + 1161, 1145, 1146, 1147, 1148, 1149, 1162, 1163, 1164, 1150, + 1165, 1166, 1167, 1152, 1168, 1153, 1169, 1170, 1154, 1155, + 1156, 1171, 1159, 1172, 1173, 1174, 1175, 1161, 1176, 1177, + 1179, 1180, 1181, 1162, 1163, 1164, 1182, 1165, 1166, 1167, + 1183, 1168, 1184, 1169, 1170, 1185, 1186, 1188, 1171, 1189, + + 1172, 1173, 1174, 1175, 1190, 1176, 1177, 1179, 1180, 1181, + 1191, 1192, 1193, 1182, 1197, 1198, 1199, 1183, 1200, 1184, + 1195, 1202, 1185, 1186, 1188, 1203, 1189, 1205, 1196, 1206, + 1207, 1190, 1208, 1209, 1210, 1201, 1211, 1191, 1192, 1193, + 1212, 1197, 1198, 1199, 1213, 1200, 1214, 1195, 1202, 1215, + 1216, 1219, 1203, 1220, 1205, 1221, 1206, 1207, 1217, 1208, + 1209, 1210, 1201, 1211, 1218, 1222, 1223, 1212, 1224, 1225, + 1227, 1213, 1228, 1214, 1229, 1230, 1215, 1216, 1219, 1231, + 1220, 1232, 1221, 1233, 1234, 1217, 1235, 1236, 1237, 1238, + 1239, 1218, 1222, 1223, 1240, 1224, 1225, 1227, 1241, 1228, + + 1242, 1229, 1230, 1243, 1244, 1245, 1231, 1246, 1232, 1247, + 1233, 1234, 1248, 1235, 1236, 1237, 1238, 1239, 1249, 1250, + 1251, 1240, 1252, 1253, 1254, 1241, 1255, 1242, 1257, 1258, + 1243, 1244, 1245, 1259, 1246, 1260, 1247, 1261, 1262, 1248, + 1263, 1264, 1265, 1266, 1269, 1249, 1250, 1251, 1270, 1252, + 1253, 1254, 1271, 1255, 1272, 1257, 1258, 1273, 1274, 1275, + 1259, 1276, 1260, 1277, 1261, 1262, 1278, 1263, 1264, 1265, + 1266, 1269, 1280, 1281, 1282, 1270, 1283, 1285, 1286, 1271, + 1287, 1272, 1288, 1289, 1273, 1274, 1275, 1290, 1276, 1291, + 1277, 1292, 1293, 1278, 1294, 1295, 1297, 1298, 1303, 1280, + + 1281, 1282, 1304, 1283, 1285, 1286, 1306, 1287, 1307, 1288, + 1289, 1308, 1309, 1310, 1290, 1311, 1291, 1312, 1292, 1293, + 1313, 1294, 1295, 1297, 1298, 1303, 1315, 1316, 1317, 1304, + 1318, 1319, 1321, 1306, 1322, 1307, 1323, 1324, 1308, 1309, + 1310, 1325, 1311, 1326, 1312, 1327, 1328, 1313, 1329, 1331, + 1332, 1333, 1334, 1315, 1316, 1317, 1335, 1318, 1319, 1321, + 1336, 1322, 1337, 1323, 1324, 1338, 1339, 1340, 1325, 1341, + 1326, 1342, 1327, 1328, 1343, 1329, 1331, 1332, 1333, 1334, + 1344, 1345, 1346, 1335, 1347, 1348, 1349, 1336, 1350, 1337, + 1351, 1352, 1338, 1339, 1340, 1353, 1341, 1355, 1342, 1356, + + 1357, 1343, 1359, 1360, 1361, 1363, 1362, 1344, 1345, 1346, + 1365, 1347, 1348, 1349, 1367, 1350, 1368, 1351, 1352, 1369, + 1370, 1371, 1353, 1372, 1355, 1373, 1356, 1357, 1374, 1359, + 1360, 1361, 1363, 1362, 1375, 1378, 1376, 1365, 1379, 1380, + 1381, 1367, 1377, 1368, 1382, 1383, 1369, 1370, 1371, 1384, + 1372, 1385, 1373, 1386, 1387, 1374, 1389, 1390, 1391, 1392, + 1393, 1375, 1378, 1376, 1394, 1379, 1380, 1381, 1395, 1377, + 1396, 1382, 1383, 1397, 1398, 1399, 1384, 1400, 1385, 1401, + 1386, 1387, 1404, 1389, 1390, 1391, 1392, 1393, 1405, 1406, + 1407, 1394, 1408, 1409, 1410, 1395, 1411, 1396, 1412, 1413, + + 1397, 1398, 1399, 1415, 1400, 1416, 1401, 1417, 1418, 1404, + 1420, 1421, 1422, 1423, 1424, 1405, 1406, 1407, 1425, 1408, + 1409, 1410, 1427, 1411, 1429, 1412, 1413, 1430, 1431, 1432, + 1415, 1433, 1416, 1434, 1417, 1418, 1435, 1420, 1421, 1422, + 1423, 1424, 1436, 1437, 1438, 1425, 1439, 1440, 1441, 1427, + 1442, 1429, 1443, 1444, 1430, 1431, 1432, 1445, 1433, 1446, + 1434, 1447, 1448, 1435, 1449, 1450, 1451, 1452, 1453, 1436, + 1437, 1438, 1454, 1439, 1440, 1441, 1455, 1442, 1456, 1443, + 1444, 1457, 1458, 1459, 1445, 1460, 1446, 1461, 1447, 1448, + 1462, 1449, 1450, 1451, 1452, 1453, 1463, 1464, 1465, 1454, + + 1466, 1467, 1468, 1455, 1469, 1456, 1470, 1471, 1457, 1458, + 1459, 1472, 1460, 1473, 1461, 1474, 1475, 1462, 1476, 1477, + 1478, 1479, 1480, 1463, 1464, 1465, 1481, 1466, 1467, 1468, + 1482, 1469, 1483, 1470, 1471, 1484, 1485, 1486, 1472, 1487, + 1473, 1488, 1474, 1475, 1489, 1476, 1477, 1478, 1479, 1480, + 1490, 1492, 1493, 1481, 1494, 1495, 1496, 1482, 1497, 1483, + 1498, 1499, 1484, 1485, 1486, 1500, 1487, 1501, 1488, 1502, + 1503, 1489, 1504, 1505, 1506, 1507, 1508, 1490, 1492, 1493, + 1509, 1494, 1495, 1496, 1510, 1497, 1511, 1498, 1499, 1512, + 1513, 1514, 1500, 1515, 1501, 1516, 1502, 1503, 1517, 1504, + + 1505, 1506, 1507, 1508, 1519, 1520, 1521, 1509, 1522, 1523, + 1524, 1510, 1525, 1511, 1526, 1527, 1512, 1513, 1514, 1528, + 1515, 1529, 1516, 1530, 1531, 1517, 1532, 1534, 1535, 1536, + 1537, 1519, 1520, 1521, 1538, 1522, 1523, 1524, 1539, 1525, + 1540, 1526, 1527, 1541, 1542, 1543, 1528, 1544, 1529, 1194, + 1530, 1531, 1187, 1532, 1534, 1535, 1536, 1537, 1178, 1160, + 1158, 1538, 1157, 1151, 1139, 1539, 1137, 1540, 1121, 1120, + 1541, 1542, 1543, 1117, 1544, 39, 39, 995, 995, 993, + 993, 1056, 1054, 1053, 1048, 1034, 1027, 1018, 1000, 999, + 998, 995, 993, 984, 969, 962, 958, 933, 882, 879, + + 877, 874, 873, 872, 871, 870, 834, 833, 830, 826, + 792, 787, 786, 785, 783, 762, 760, 752, 718, 684, + 680, 678, 676, 669, 667, 648, 644, 629, 623, 621, + 604, 592, 560, 558, 557, 543, 526, 514, 500, 499, + 492, 479, 468, 466, 456, 454, 433, 429, 427, 422, + 404, 395, 388, 350, 317, 301, 265, 239, 202, 37, + 37, 1545, 3, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545 + } ; + +static yyconst flex_int16_t yy_chk[3032] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, + 9, 10, 13, 10, 11, 11, 11, 11, 11, 16, + 21, 1550, 13, 26, 1549, 16, 16, 9, 39, 39, + 15, 771, 28, 771, 15, 18, 16, 1548, 15, 13, + + 17, 15, 18, 771, 15, 1546, 16, 21, 17, 13, + 26, 17, 16, 16, 9, 12, 12, 15, 12, 28, + 17, 15, 18, 16, 12, 15, 12, 17, 15, 18, + 20, 15, 19, 12, 1527, 17, 1505, 20, 17, 20, + 19, 1471, 12, 12, 29, 12, 19, 17, 1389, 33, + 1387, 12, 19, 12, 35, 179, 179, 20, 29, 19, + 12, 14, 36, 14, 20, 1379, 20, 19, 14, 14, + 22, 29, 14, 19, 23, 14, 33, 22, 23, 19, + 22, 35, 22, 34, 23, 29, 1374, 34, 14, 36, + 14, 883, 27, 883, 43, 14, 14, 22, 47, 14, + + 27, 23, 14, 883, 22, 23, 27, 22, 48, 22, + 34, 23, 24, 24, 34, 49, 24, 32, 32, 27, + 24, 43, 50, 32, 51, 47, 24, 27, 46, 46, + 46, 46, 46, 27, 52, 48, 53, 54, 56, 24, + 24, 1343, 49, 24, 32, 32, 55, 24, 55, 50, + 32, 51, 57, 24, 25, 58, 25, 59, 25, 60, + 61, 52, 25, 53, 54, 56, 63, 64, 25, 65, + 66, 67, 68, 55, 25, 55, 70, 59, 1319, 57, + 63, 25, 58, 25, 59, 25, 60, 61, 71, 25, + 1316, 72, 73, 63, 64, 25, 65, 66, 67, 68, + + 76, 25, 30, 70, 59, 30, 30, 63, 30, 69, + 77, 69, 30, 30, 1310, 71, 30, 30, 72, 73, + 74, 1359, 1359, 78, 75, 78, 69, 76, 1304, 30, + 75, 74, 30, 30, 79, 30, 69, 77, 69, 30, + 30, 62, 62, 30, 30, 31, 62, 74, 31, 31, + 78, 75, 78, 69, 62, 31, 31, 75, 74, 62, + 80, 79, 31, 81, 82, 83, 84, 85, 62, 62, + 86, 87, 31, 62, 88, 31, 31, 92, 94, 89, + 91, 62, 31, 31, 89, 91, 62, 80, 93, 31, + 81, 82, 83, 84, 85, 90, 95, 86, 87, 90, + + 93, 88, 96, 97, 92, 94, 89, 91, 99, 98, + 101, 89, 91, 102, 104, 93, 103, 105, 108, 112, + 106, 1273, 90, 95, 98, 113, 90, 93, 106, 96, + 97, 111, 103, 103, 1263, 99, 98, 101, 115, 109, + 102, 104, 116, 103, 105, 108, 112, 106, 110, 117, + 109, 98, 113, 111, 109, 106, 109, 118, 111, 103, + 103, 107, 110, 107, 107, 115, 109, 107, 107, 116, + 107, 119, 114, 107, 120, 110, 117, 109, 122, 107, + 111, 109, 114, 109, 118, 123, 1255, 125, 107, 110, + 107, 107, 126, 128, 107, 107, 1244, 107, 119, 114, + + 107, 120, 127, 1241, 129, 122, 107, 130, 127, 114, + 131, 132, 123, 124, 125, 133, 124, 134, 136, 126, + 128, 137, 138, 124, 124, 139, 140, 142, 137, 127, + 124, 129, 143, 144, 130, 127, 124, 131, 132, 145, + 124, 146, 133, 124, 134, 136, 147, 148, 137, 138, + 124, 124, 139, 140, 142, 137, 149, 124, 150, 143, + 144, 151, 152, 124, 153, 155, 145, 156, 146, 157, + 158, 159, 160, 147, 148, 161, 162, 163, 164, 165, + 166, 167, 168, 149, 169, 150, 170, 171, 151, 152, + 172, 153, 155, 166, 156, 174, 157, 158, 159, 160, + + 173, 173, 161, 162, 163, 164, 165, 166, 167, 168, + 175, 169, 177, 170, 171, 178, 180, 172, 181, 183, + 166, 182, 174, 184, 182, 185, 186, 173, 173, 187, + 188, 190, 192, 193, 194, 195, 196, 175, 197, 177, + 198, 195, 178, 180, 199, 181, 183, 200, 182, 201, + 184, 182, 185, 186, 203, 204, 187, 188, 190, 192, + 193, 194, 195, 196, 205, 197, 202, 198, 206, 207, + 208, 199, 209, 202, 200, 210, 201, 211, 202, 212, + 213, 203, 204, 202, 214, 215, 216, 218, 219, 221, + 219, 205, 222, 202, 223, 206, 207, 208, 225, 209, + + 202, 226, 210, 228, 211, 202, 212, 213, 229, 230, + 202, 214, 215, 216, 218, 219, 221, 219, 231, 222, + 234, 223, 233, 235, 236, 225, 237, 233, 226, 238, + 228, 239, 240, 241, 242, 229, 230, 243, 244, 245, + 246, 239, 247, 248, 249, 231, 250, 234, 251, 233, + 235, 236, 248, 237, 252, 253, 238, 255, 239, 240, + 241, 242, 256, 257, 243, 244, 245, 246, 239, 247, + 248, 249, 258, 250, 261, 251, 263, 264, 265, 266, + 267, 252, 253, 269, 255, 270, 271, 274, 275, 256, + 257, 277, 278, 279, 281, 282, 283, 284, 285, 258, + + 286, 261, 287, 263, 264, 265, 266, 267, 289, 290, + 269, 292, 270, 271, 274, 275, 293, 294, 277, 278, + 279, 281, 282, 283, 284, 285, 295, 286, 296, 287, + 297, 300, 301, 302, 303, 289, 290, 307, 292, 309, + 295, 296, 310, 293, 294, 311, 313, 314, 315, 316, + 1240, 1239, 1238, 295, 318, 296, 1235, 297, 300, 301, + 302, 303, 319, 1219, 307, 320, 309, 295, 321, 310, + 322, 323, 311, 313, 314, 315, 316, 317, 317, 317, + 325, 318, 327, 317, 329, 317, 330, 331, 317, 319, + 317, 332, 320, 333, 1214, 321, 317, 322, 323, 317, + + 336, 340, 1199, 334, 317, 317, 317, 325, 341, 327, + 317, 329, 317, 330, 331, 317, 342, 317, 332, 343, + 333, 334, 344, 317, 345, 334, 317, 336, 340, 334, + 334, 346, 347, 348, 350, 341, 351, 352, 354, 355, + 357, 358, 359, 342, 362, 363, 343, 352, 334, 344, + 348, 345, 334, 353, 361, 361, 364, 353, 346, 347, + 348, 350, 353, 351, 352, 354, 355, 357, 358, 359, + 361, 362, 363, 367, 368, 370, 371, 348, 372, 373, + 353, 361, 361, 364, 353, 374, 375, 376, 378, 353, + 379, 380, 382, 383, 384, 378, 385, 361, 386, 387, + + 367, 368, 370, 371, 388, 372, 373, 389, 391, 388, + 392, 394, 374, 375, 376, 378, 395, 379, 380, 382, + 383, 384, 378, 385, 397, 386, 387, 398, 400, 401, + 402, 388, 404, 405, 389, 391, 388, 392, 394, 407, + 408, 409, 410, 395, 411, 413, 415, 417, 418, 419, + 420, 397, 421, 422, 398, 400, 401, 402, 424, 404, + 405, 425, 426, 427, 428, 429, 407, 408, 409, 410, + 430, 411, 413, 415, 417, 418, 419, 420, 433, 421, + 422, 435, 436, 437, 438, 424, 439, 441, 425, 426, + 427, 428, 429, 442, 440, 443, 445, 430, 440, 446, + + 444, 447, 448, 449, 450, 433, 451, 452, 435, 436, + 437, 438, 444, 439, 441, 453, 455, 454, 456, 457, + 442, 440, 443, 445, 454, 440, 446, 444, 447, 448, + 449, 450, 458, 451, 452, 459, 460, 461, 462, 444, + 464, 466, 453, 455, 454, 456, 457, 465, 465, 467, + 469, 454, 468, 465, 471, 473, 475, 476, 473, 458, + 467, 477, 459, 460, 461, 462, 478, 464, 466, 468, + 479, 481, 468, 483, 465, 465, 467, 469, 484, 468, + 465, 471, 473, 475, 476, 473, 480, 467, 477, 480, + 485, 486, 487, 478, 490, 494, 468, 479, 481, 468, + + 483, 495, 493, 497, 498, 484, 493, 500, 501, 493, + 502, 503, 504, 480, 505, 506, 480, 485, 486, 487, + 507, 490, 494, 508, 509, 510, 511, 513, 495, 493, + 497, 498, 514, 493, 500, 501, 493, 502, 503, 504, + 517, 505, 506, 519, 521, 522, 523, 507, 524, 525, + 508, 509, 510, 511, 513, 526, 527, 528, 529, 514, + 530, 531, 532, 533, 534, 535, 524, 517, 536, 539, + 519, 521, 522, 523, 541, 524, 525, 542, 545, 547, + 1198, 550, 526, 527, 528, 529, 549, 530, 531, 532, + 533, 534, 535, 543, 543, 536, 539, 549, 552, 553, + + 555, 541, 543, 556, 542, 545, 547, 543, 550, 557, + 558, 559, 560, 549, 564, 565, 566, 567, 568, 569, + 543, 543, 570, 571, 549, 552, 553, 555, 572, 543, + 556, 573, 574, 576, 543, 577, 557, 558, 559, 560, + 578, 564, 565, 566, 567, 568, 569, 579, 580, 570, + 571, 581, 582, 583, 584, 572, 585, 586, 573, 574, + 576, 587, 577, 588, 589, 591, 592, 578, 593, 594, + 595, 596, 597, 599, 579, 580, 600, 601, 581, 582, + 583, 584, 602, 585, 586, 603, 604, 606, 587, 607, + 588, 589, 591, 592, 609, 593, 594, 595, 596, 597, + + 599, 610, 611, 600, 601, 612, 613, 614, 615, 602, + 616, 618, 603, 604, 606, 619, 607, 617, 617, 621, + 622, 609, 623, 624, 625, 626, 628, 1182, 610, 611, + 630, 1150, 612, 613, 614, 615, 632, 616, 618, 634, + 637, 638, 619, 639, 617, 617, 621, 622, 641, 623, + 624, 625, 626, 628, 629, 642, 643, 630, 629, 646, + 629, 647, 648, 632, 629, 629, 634, 637, 638, 649, + 639, 650, 651, 652, 653, 641, 654, 655, 656, 658, + 660, 629, 642, 643, 662, 629, 646, 629, 647, 648, + 666, 629, 629, 667, 668, 669, 649, 672, 650, 651, + + 652, 653, 673, 654, 655, 656, 658, 660, 674, 675, + 676, 662, 673, 678, 679, 680, 681, 666, 682, 683, + 667, 668, 669, 684, 672, 685, 686, 687, 688, 673, + 689, 690, 691, 692, 693, 674, 675, 676, 694, 673, + 678, 679, 680, 681, 695, 682, 683, 696, 697, 698, + 684, 699, 685, 686, 687, 688, 700, 689, 690, 691, + 692, 693, 701, 702, 703, 694, 704, 707, 710, 711, + 713, 695, 714, 717, 696, 697, 698, 718, 699, 719, + 720, 721, 722, 700, 723, 724, 725, 726, 727, 701, + 702, 703, 728, 704, 707, 710, 711, 713, 729, 714, + + 717, 730, 731, 732, 718, 733, 719, 720, 721, 722, + 734, 723, 724, 725, 726, 727, 736, 737, 738, 728, + 739, 741, 742, 743, 744, 729, 745, 746, 730, 731, + 732, 747, 733, 748, 749, 750, 751, 734, 752, 753, + 759, 760, 762, 736, 737, 738, 766, 739, 741, 742, + 743, 744, 769, 745, 746, 772, 773, 774, 747, 775, + 748, 749, 750, 751, 778, 752, 753, 759, 760, 762, + 779, 780, 781, 766, 782, 783, 784, 1123, 786, 769, + 787, 788, 772, 773, 774, 789, 775, 785, 783, 791, + 792, 778, 785, 793, 794, 795, 796, 779, 780, 781, + + 797, 782, 783, 784, 785, 786, 798, 787, 788, 799, + 800, 801, 789, 802, 785, 783, 791, 792, 803, 785, + 793, 794, 795, 796, 805, 806, 807, 797, 808, 809, + 810, 785, 811, 798, 812, 813, 799, 800, 801, 814, + 802, 816, 817, 818, 819, 803, 820, 822, 823, 824, + 825, 805, 806, 807, 826, 808, 809, 810, 827, 811, + 828, 812, 813, 829, 831, 832, 814, 833, 816, 817, + 818, 819, 830, 820, 822, 823, 824, 825, 834, 836, + 838, 826, 830, 840, 841, 827, 842, 828, 843, 845, + 829, 831, 832, 846, 833, 847, 848, 850, 851, 830, + + 852, 854, 855, 856, 857, 834, 836, 838, 858, 830, + 840, 841, 859, 842, 861, 843, 845, 862, 863, 864, + 846, 865, 847, 848, 850, 851, 866, 852, 854, 855, + 856, 857, 867, 868, 869, 858, 870, 871, 872, 859, + 873, 861, 874, 876, 862, 863, 864, 877, 865, 878, + 879, 880, 881, 866, 882, 886, 887, 892, 893, 867, + 868, 869, 894, 870, 871, 872, 895, 873, 896, 874, + 876, 897, 898, 899, 877, 900, 878, 879, 880, 881, + 901, 882, 886, 887, 892, 893, 902, 904, 905, 894, + 906, 907, 908, 895, 909, 896, 911, 912, 897, 898, + + 899, 913, 900, 914, 915, 916, 917, 901, 918, 920, + 921, 923, 924, 902, 904, 905, 926, 906, 907, 908, + 927, 909, 929, 911, 912, 930, 934, 933, 913, 935, + 914, 915, 916, 917, 938, 918, 920, 921, 923, 924, + 939, 940, 941, 926, 933, 942, 943, 927, 944, 929, + 946, 947, 930, 934, 933, 948, 935, 949, 952, 954, + 956, 938, 957, 958, 962, 963, 964, 939, 940, 941, + 965, 933, 942, 943, 966, 944, 967, 946, 947, 968, + 969, 970, 948, 971, 949, 952, 954, 956, 972, 957, + 958, 962, 963, 964, 973, 974, 975, 965, 976, 977, + + 978, 966, 979, 967, 980, 981, 968, 969, 970, 982, + 971, 983, 984, 985, 986, 972, 987, 988, 990, 991, + 996, 973, 974, 975, 997, 976, 977, 978, 998, 979, + 999, 980, 981, 1000, 1002, 1003, 982, 1004, 983, 984, + 985, 986, 1005, 987, 988, 990, 991, 996, 1006, 1007, + 1008, 997, 1009, 1010, 1011, 998, 1012, 999, 1013, 1014, + 1000, 1002, 1003, 1015, 1004, 1016, 1017, 1018, 1019, 1005, + 1020, 1021, 1023, 1024, 1026, 1006, 1007, 1008, 1027, 1009, + 1010, 1011, 1030, 1012, 1031, 1013, 1014, 1032, 1034, 1035, + 1015, 1037, 1016, 1017, 1018, 1019, 1038, 1020, 1021, 1023, + + 1024, 1026, 1040, 1041, 1042, 1027, 1044, 1045, 1046, 1030, + 1047, 1031, 1048, 1050, 1032, 1034, 1035, 1052, 1037, 1053, + 1054, 1055, 1056, 1038, 1057, 1058, 1060, 1061, 1062, 1040, + 1041, 1042, 1063, 1044, 1045, 1046, 1065, 1047, 1068, 1048, + 1050, 1071, 1072, 1073, 1052, 1076, 1053, 1054, 1055, 1056, + 1078, 1057, 1058, 1060, 1061, 1062, 1079, 1080, 1081, 1063, + 1082, 1083, 1084, 1065, 1085, 1068, 1086, 1087, 1071, 1072, + 1073, 1088, 1076, 1089, 1090, 1091, 1092, 1078, 1093, 1094, + 1097, 1098, 1100, 1079, 1080, 1081, 1101, 1082, 1083, 1084, + 1102, 1085, 1103, 1086, 1087, 1104, 1105, 1107, 1088, 1108, + + 1089, 1090, 1091, 1092, 1109, 1093, 1094, 1097, 1098, 1100, + 1110, 1111, 1112, 1101, 1117, 1118, 1119, 1102, 1120, 1103, + 1116, 1121, 1104, 1105, 1107, 1122, 1108, 1125, 1116, 1127, + 1128, 1109, 1130, 1131, 1132, 1120, 1133, 1110, 1111, 1112, + 1134, 1117, 1118, 1119, 1135, 1120, 1136, 1116, 1121, 1137, + 1138, 1140, 1122, 1141, 1125, 1142, 1127, 1128, 1139, 1130, + 1131, 1132, 1120, 1133, 1139, 1144, 1146, 1134, 1147, 1148, + 1151, 1135, 1152, 1136, 1153, 1154, 1137, 1138, 1140, 1155, + 1141, 1156, 1142, 1157, 1158, 1139, 1159, 1160, 1161, 1162, + 1163, 1139, 1144, 1146, 1164, 1147, 1148, 1151, 1165, 1152, + + 1166, 1153, 1154, 1167, 1168, 1169, 1155, 1170, 1156, 1172, + 1157, 1158, 1173, 1159, 1160, 1161, 1162, 1163, 1174, 1175, + 1176, 1164, 1177, 1178, 1179, 1165, 1180, 1166, 1183, 1184, + 1167, 1168, 1169, 1187, 1170, 1188, 1172, 1189, 1192, 1173, + 1193, 1194, 1196, 1197, 1200, 1174, 1175, 1176, 1201, 1177, + 1178, 1179, 1202, 1180, 1204, 1183, 1184, 1205, 1206, 1207, + 1187, 1208, 1188, 1209, 1189, 1192, 1210, 1193, 1194, 1196, + 1197, 1200, 1215, 1216, 1217, 1201, 1218, 1220, 1221, 1202, + 1222, 1204, 1225, 1226, 1205, 1206, 1207, 1227, 1208, 1228, + 1209, 1229, 1232, 1210, 1233, 1234, 1236, 1237, 1242, 1215, + + 1216, 1217, 1243, 1218, 1220, 1221, 1246, 1222, 1247, 1225, + 1226, 1248, 1250, 1251, 1227, 1252, 1228, 1253, 1229, 1232, + 1254, 1233, 1234, 1236, 1237, 1242, 1256, 1257, 1259, 1243, + 1261, 1262, 1264, 1246, 1265, 1247, 1266, 1267, 1248, 1250, + 1251, 1268, 1252, 1269, 1253, 1270, 1271, 1254, 1272, 1274, + 1276, 1277, 1279, 1256, 1257, 1259, 1280, 1261, 1262, 1264, + 1282, 1265, 1284, 1266, 1267, 1285, 1286, 1287, 1268, 1288, + 1269, 1289, 1270, 1271, 1290, 1272, 1274, 1276, 1277, 1279, + 1293, 1294, 1295, 1280, 1296, 1297, 1298, 1282, 1299, 1284, + 1300, 1301, 1285, 1286, 1287, 1302, 1288, 1305, 1289, 1308, + + 1309, 1290, 1312, 1313, 1314, 1315, 1314, 1293, 1294, 1295, + 1317, 1296, 1297, 1298, 1320, 1299, 1321, 1300, 1301, 1322, + 1324, 1325, 1302, 1326, 1305, 1327, 1308, 1309, 1328, 1312, + 1313, 1314, 1315, 1314, 1329, 1331, 1330, 1317, 1333, 1334, + 1335, 1320, 1330, 1321, 1336, 1337, 1322, 1324, 1325, 1338, + 1326, 1340, 1327, 1341, 1342, 1328, 1344, 1345, 1346, 1347, + 1348, 1329, 1331, 1330, 1349, 1333, 1334, 1335, 1350, 1330, + 1351, 1336, 1337, 1352, 1353, 1354, 1338, 1355, 1340, 1358, + 1341, 1342, 1360, 1344, 1345, 1346, 1347, 1348, 1361, 1362, + 1363, 1349, 1364, 1365, 1367, 1350, 1368, 1351, 1371, 1372, + + 1352, 1353, 1354, 1375, 1355, 1376, 1358, 1377, 1378, 1360, + 1380, 1381, 1383, 1384, 1385, 1361, 1362, 1363, 1386, 1364, + 1365, 1367, 1388, 1368, 1391, 1371, 1372, 1392, 1393, 1394, + 1375, 1395, 1376, 1396, 1377, 1378, 1397, 1380, 1381, 1383, + 1384, 1385, 1398, 1399, 1400, 1386, 1401, 1404, 1405, 1388, + 1406, 1391, 1407, 1408, 1392, 1393, 1394, 1409, 1395, 1410, + 1396, 1412, 1414, 1397, 1415, 1416, 1417, 1419, 1420, 1398, + 1399, 1400, 1422, 1401, 1404, 1405, 1425, 1406, 1426, 1407, + 1408, 1427, 1428, 1429, 1409, 1430, 1410, 1431, 1412, 1414, + 1433, 1415, 1416, 1417, 1419, 1420, 1434, 1435, 1436, 1422, + + 1437, 1438, 1439, 1425, 1440, 1426, 1441, 1442, 1427, 1428, + 1429, 1443, 1430, 1444, 1431, 1445, 1446, 1433, 1447, 1448, + 1449, 1450, 1451, 1434, 1435, 1436, 1452, 1437, 1438, 1439, + 1453, 1440, 1454, 1441, 1442, 1456, 1457, 1458, 1443, 1466, + 1444, 1467, 1445, 1446, 1468, 1447, 1448, 1449, 1450, 1451, + 1470, 1472, 1473, 1452, 1475, 1476, 1477, 1453, 1478, 1454, + 1481, 1483, 1456, 1457, 1458, 1484, 1466, 1485, 1467, 1486, + 1487, 1468, 1489, 1490, 1491, 1492, 1493, 1470, 1472, 1473, + 1494, 1475, 1476, 1477, 1495, 1478, 1496, 1481, 1483, 1498, + 1499, 1500, 1484, 1502, 1485, 1503, 1486, 1487, 1504, 1489, + + 1490, 1491, 1492, 1493, 1506, 1507, 1508, 1494, 1509, 1511, + 1512, 1495, 1513, 1496, 1516, 1517, 1498, 1499, 1500, 1518, + 1502, 1519, 1503, 1521, 1522, 1504, 1524, 1528, 1529, 1530, + 1533, 1506, 1507, 1508, 1534, 1509, 1511, 1512, 1535, 1513, + 1537, 1516, 1517, 1538, 1540, 1541, 1518, 1542, 1519, 1114, + 1521, 1522, 1106, 1524, 1528, 1529, 1530, 1533, 1095, 1077, + 1075, 1534, 1074, 1064, 1051, 1535, 1049, 1537, 1029, 1028, + 1538, 1540, 1541, 1025, 1542, 1547, 1547, 995, 994, 993, + 992, 953, 951, 950, 945, 928, 919, 910, 890, 889, + 888, 885, 884, 875, 860, 853, 849, 821, 770, 763, + + 761, 758, 757, 756, 755, 754, 716, 715, 712, 705, + 670, 665, 664, 663, 661, 633, 631, 627, 590, 551, + 548, 546, 544, 540, 537, 518, 512, 496, 491, 488, + 470, 463, 434, 432, 431, 416, 393, 381, 366, 365, + 360, 349, 338, 335, 328, 326, 312, 308, 306, 298, + 280, 268, 259, 220, 191, 176, 141, 121, 100, 37, + 5, 3, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, + 1545 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +static int yy_more_flag = 0; +static int yy_more_len = 0; +#define yymore() ((yy_more_flag) = 1) +#define YY_MORE_ADJ (yy_more_len) +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "conf_lexer.l" +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * conf_lexer.l: Scans the ircd configuration file for tokens. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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: conf_lexer.l 1547 2012-09-30 17:50:03Z michael $ + */ +#line 31 "conf_lexer.l" +#include "stdinc.h" +#include "irc_string.h" +#include "conf.h" +#include "conf_parser.h" /* autogenerated header file */ +#include "memory.h" +#include "hostmask.h" +#include "log.h" + +#undef YY_INPUT +#define YY_FATAL_ERROR(msg) conf_yy_fatal_error(msg) +#define YY_INPUT(buf,result,max_size) \ + if (!(result = conf_yy_input(buf, max_size))) \ + YY_FATAL_ERROR("input in flex scanner failed"); +#define MAX_INCLUDE_DEPTH 10 + + +unsigned int lineno = 1; +char linebuf[IRCD_BUFSIZE]; +char conffilebuf[IRCD_BUFSIZE]; + +static int include_stack_ptr = 0; +static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; +static unsigned int lineno_stack[MAX_INCLUDE_DEPTH]; +static FILE *inc_fbfile_in[MAX_INCLUDE_DEPTH]; +static char conffile_stack[MAX_INCLUDE_DEPTH][IRCD_BUFSIZE]; +static void ccomment(void); +static void cinclude(void); +static int ieof(void); + +static int +conf_yy_input(char *lbuf, unsigned int max_size) +{ + return !fgets(lbuf, max_size, conf_parser_ctx.conf_file) ? 0 : strlen(lbuf); +} + +static int +conf_yy_fatal_error(const char *msg) +{ + return 0; +} + +#line 1700 "conf_lexer.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include <unistd.h> +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (void ); + +int yyget_debug (void ); + +void yyset_debug (int debug_flag ); + +YY_EXTRA_TYPE yyget_extra (void ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in (void ); + +void yyset_in (FILE * in_str ); + +FILE *yyget_out (void ); + +void yyset_out (FILE * out_str ); + +yy_size_t yyget_leng (void ); + +char *yyget_text (void ); + +int yyget_lineno (void ); + +void yyset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (void ); +#else +extern int yywrap (void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 80 "conf_lexer.l" + +#line 1882 "conf_lexer.c" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + (yy_more_len) = 0; + if ( (yy_more_flag) ) + { + (yy_more_len) = (yy_c_buf_p) - (yytext_ptr); + (yy_more_flag) = 0; + } + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1546 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_current_state != 1545 ); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 81 "conf_lexer.l" +{ cinclude(); } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 82 "conf_lexer.l" +{ ccomment(); } + YY_BREAK +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +#line 84 "conf_lexer.l" +{ strlcpy(linebuf, yytext+1, sizeof(linebuf)); ++lineno; yyless(1); } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 86 "conf_lexer.l" +; + YY_BREAK +case 5: +YY_RULE_SETUP +#line 87 "conf_lexer.l" +; + YY_BREAK +case 6: +YY_RULE_SETUP +#line 89 "conf_lexer.l" +{ yylval.number = atoi(yytext); return NUMBER; } + YY_BREAK +case 7: +/* rule 7 can match eol */ +YY_RULE_SETUP +#line 91 "conf_lexer.l" +{ if (yytext[yyleng-2] == '\\') + { + yyless(yyleng-1); /* return last quote */ + yymore(); /* append next string */ + } + else + { + yylval.string = yytext+1; + if(yylval.string[yyleng-2] != '"') + ilog(LOG_TYPE_IRCD, "Unterminated character string"); + else + { + int i,j; + + yylval.string[yyleng-2] = '\0'; /* remove close + * quote + */ + + for (j=i=0 ;yylval.string[i] != '\0'; i++,j++) + { + if (yylval.string[i] != '\\') + { + yylval.string[j] = yylval.string[i]; + } + else + { + i++; + if (yylval.string[i] == '\0') /* XXX + * should not + * happen + */ + { + ilog(LOG_TYPE_IRCD, + "Unterminated character string"); + break; + } + yylval.string[j] = yylval.string[i]; + } + } + yylval.string[j] = '\0'; + return QSTRING; + } + } + } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 136 "conf_lexer.l" +{ return ACCEPT_PASSWORD; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 137 "conf_lexer.l" +{ return ADMIN; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 138 "conf_lexer.l" +{ return ADMIN; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 139 "conf_lexer.l" +{ return AFTYPE; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 140 "conf_lexer.l" +{ return T_ALL; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 141 "conf_lexer.l" +{ return IRCD_AUTH; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 142 "conf_lexer.l" +{ return AUTOCONN; } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 143 "conf_lexer.l" +{ return CAN_FLOOD; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 144 "conf_lexer.l" +{ return CALLER_ID_WAIT; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 145 "conf_lexer.l" +{ return OPERS_BYPASS_CALLERID; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 146 "conf_lexer.l" +{ return CHANNEL; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 147 "conf_lexer.l" +{ return CIDR_BITLEN_IPV4; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 148 "conf_lexer.l" +{ return CIDR_BITLEN_IPV6; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 149 "conf_lexer.l" +{ return CLASS; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 150 "conf_lexer.l" +{ return T_CLUSTER; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 151 "conf_lexer.l" +{ return CONNECT; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 152 "conf_lexer.l" +{ return CONNECTFREQ; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 153 "conf_lexer.l" +{ return DEFAULT_FLOODCOUNT; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 154 "conf_lexer.l" +{ return DEFAULT_SPLIT_SERVER_COUNT; } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 155 "conf_lexer.l" +{ return DEFAULT_SPLIT_USER_COUNT; } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 156 "conf_lexer.l" +{ return DENY; } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 157 "conf_lexer.l" +{ return DESCRIPTION; } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 158 "conf_lexer.l" +{ return DIE; } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 159 "conf_lexer.l" +{ return DISABLE_AUTH; } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 160 "conf_lexer.l" +{ return DISABLE_FAKE_CHANNELS; } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 161 "conf_lexer.l" +{ return DISABLE_REMOTE_COMMANDS; } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 162 "conf_lexer.l" +{ return T_DLINE; } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 163 "conf_lexer.l" +{ return DOTS_IN_IDENT; } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 164 "conf_lexer.l" +{ return EGDPOOL_PATH; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 165 "conf_lexer.l" +{ return EMAIL; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 166 "conf_lexer.l" +{ return ENCRYPTED; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 167 "conf_lexer.l" +{ return EXCEED_LIMIT; } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 168 "conf_lexer.l" +{ return EXEMPT; } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 169 "conf_lexer.l" +{ return T_FILE; } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 170 "conf_lexer.l" +{ return IRCD_FLAGS; } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 171 "conf_lexer.l" +{ return FLATTEN_LINKS; } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 172 "conf_lexer.l" +{ return GECOS; } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 173 "conf_lexer.l" +{ return GENERAL; } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 174 "conf_lexer.l" +{ return GLINE; } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 175 "conf_lexer.l" +{ return GLINE_ENABLE; } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 176 "conf_lexer.l" +{ return GLINE_EXEMPT; } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 177 "conf_lexer.l" +{ return GLINE_DURATION; } + YY_BREAK +case 50: +YY_RULE_SETUP +#line 178 "conf_lexer.l" +{ return GLINE_REQUEST_DURATION; } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 179 "conf_lexer.l" +{ return GLINE_MIN_CIDR; } + YY_BREAK +case 52: +YY_RULE_SETUP +#line 180 "conf_lexer.l" +{ return GLINE_MIN_CIDR6; } + YY_BREAK +case 53: +YY_RULE_SETUP +#line 181 "conf_lexer.l" +{ return T_GLOBOPS; } + YY_BREAK +case 54: +YY_RULE_SETUP +#line 182 "conf_lexer.l" +{ return GLOBAL_KILL; } + YY_BREAK +case 55: +YY_RULE_SETUP +#line 183 "conf_lexer.l" +{ return NEED_IDENT; } + YY_BREAK +case 56: +YY_RULE_SETUP +#line 184 "conf_lexer.l" +{ return NEED_IDENT; } + YY_BREAK +case 57: +YY_RULE_SETUP +#line 185 "conf_lexer.l" +{ return HAVENT_READ_CONF; } + YY_BREAK +case 58: +YY_RULE_SETUP +#line 186 "conf_lexer.l" +{ return HIDDEN; } + YY_BREAK +case 59: +YY_RULE_SETUP +#line 187 "conf_lexer.l" +{ return HIDDEN_NAME; } + YY_BREAK +case 60: +YY_RULE_SETUP +#line 188 "conf_lexer.l" +{ return HIDE_SERVER_IPS; } + YY_BREAK +case 61: +YY_RULE_SETUP +#line 189 "conf_lexer.l" +{ return HIDE_SERVERS; } + YY_BREAK +case 62: +YY_RULE_SETUP +#line 190 "conf_lexer.l" +{ return HIDE_SPOOF_IPS; } + YY_BREAK +case 63: +YY_RULE_SETUP +#line 191 "conf_lexer.l" +{ return HOST; } + YY_BREAK +case 64: +YY_RULE_SETUP +#line 192 "conf_lexer.l" +{ return HUB; } + YY_BREAK +case 65: +YY_RULE_SETUP +#line 193 "conf_lexer.l" +{ return HUB_MASK; } + YY_BREAK +case 66: +YY_RULE_SETUP +#line 194 "conf_lexer.l" +{ return IGNORE_BOGUS_TS; } + YY_BREAK +case 67: +YY_RULE_SETUP +#line 195 "conf_lexer.l" +{ return INVISIBLE_ON_CONNECT; } + YY_BREAK +case 68: +YY_RULE_SETUP +#line 196 "conf_lexer.l" +{ return IP; } + YY_BREAK +case 69: +YY_RULE_SETUP +#line 197 "conf_lexer.l" +{ return T_IPV4; } + YY_BREAK +case 70: +YY_RULE_SETUP +#line 198 "conf_lexer.l" +{ return T_IPV6; } + YY_BREAK +case 71: +YY_RULE_SETUP +#line 199 "conf_lexer.l" +{ return JOIN_FLOOD_COUNT; } + YY_BREAK +case 72: +YY_RULE_SETUP +#line 200 "conf_lexer.l" +{ return JOIN_FLOOD_TIME; } + YY_BREAK +case 73: +YY_RULE_SETUP +#line 201 "conf_lexer.l" +{ return KILL; } + YY_BREAK +case 74: +YY_RULE_SETUP +#line 202 "conf_lexer.l" +{ return KILL_CHASE_TIME_LIMIT; } + YY_BREAK +case 75: +YY_RULE_SETUP +#line 203 "conf_lexer.l" +{ return KLINE; } + YY_BREAK +case 76: +YY_RULE_SETUP +#line 204 "conf_lexer.l" +{ return KLINE_EXEMPT; } + YY_BREAK +case 77: +YY_RULE_SETUP +#line 205 "conf_lexer.l" +{ return LEAF_MASK; } + YY_BREAK +case 78: +YY_RULE_SETUP +#line 206 "conf_lexer.l" +{ return LISTEN; } + YY_BREAK +case 79: +YY_RULE_SETUP +#line 207 "conf_lexer.l" +{ return T_LOG; } + YY_BREAK +case 80: +YY_RULE_SETUP +#line 208 "conf_lexer.l" +{ return TMASKED; } + YY_BREAK +case 81: +YY_RULE_SETUP +#line 209 "conf_lexer.l" +{ return T_MAX_CLIENTS; } + YY_BREAK +case 82: +YY_RULE_SETUP +#line 210 "conf_lexer.l" +{ return MAX_IDENT; } + YY_BREAK +case 83: +YY_RULE_SETUP +#line 211 "conf_lexer.l" +{ return MAX_LOCAL; } + YY_BREAK +case 84: +YY_RULE_SETUP +#line 212 "conf_lexer.l" +{ return MAX_GLOBAL; } + YY_BREAK +case 85: +YY_RULE_SETUP +#line 213 "conf_lexer.l" +{ return MAX_NUMBER; } + YY_BREAK +case 86: +YY_RULE_SETUP +#line 214 "conf_lexer.l" +{ return MAX_WATCH; } + YY_BREAK +case 87: +YY_RULE_SETUP +#line 215 "conf_lexer.l" +{ return MESSAGE_LOCALE; } + YY_BREAK +case 88: +YY_RULE_SETUP +#line 216 "conf_lexer.l" +{ return MIN_NONWILDCARD; } + YY_BREAK +case 89: +YY_RULE_SETUP +#line 217 "conf_lexer.l" +{ return MIN_NONWILDCARD_SIMPLE; } + YY_BREAK +case 90: +YY_RULE_SETUP +#line 218 "conf_lexer.l" +{ return NAME; } + YY_BREAK +case 91: +YY_RULE_SETUP +#line 219 "conf_lexer.l" +{ return NEED_PASSWORD; } + YY_BREAK +case 92: +YY_RULE_SETUP +#line 220 "conf_lexer.l" +{ return NETWORK_DESC; } + YY_BREAK +case 93: +YY_RULE_SETUP +#line 221 "conf_lexer.l" +{ return NETWORK_NAME; } + YY_BREAK +case 94: +YY_RULE_SETUP +#line 222 "conf_lexer.l" +{ return NICK; } + YY_BREAK +case 95: +YY_RULE_SETUP +#line 223 "conf_lexer.l" +{ return NICK_CHANGES; } + YY_BREAK +case 96: +YY_RULE_SETUP +#line 224 "conf_lexer.l" +{ yylval.number = 0; return TBOOL; } + YY_BREAK +case 97: +YY_RULE_SETUP +#line 225 "conf_lexer.l" +{ return NO_CREATE_ON_SPLIT; } + YY_BREAK +case 98: +YY_RULE_SETUP +#line 226 "conf_lexer.l" +{ return NO_JOIN_ON_SPLIT; } + YY_BREAK +case 99: +YY_RULE_SETUP +#line 227 "conf_lexer.l" +{ return NO_OPER_FLOOD; } + YY_BREAK +case 100: +YY_RULE_SETUP +#line 228 "conf_lexer.l" +{ return NO_TILDE; } + YY_BREAK +case 101: +YY_RULE_SETUP +#line 229 "conf_lexer.l" +{ return NUMBER_PER_CIDR; } + YY_BREAK +case 102: +YY_RULE_SETUP +#line 230 "conf_lexer.l" +{ return NUMBER_PER_IP; } + YY_BREAK +case 103: +YY_RULE_SETUP +#line 231 "conf_lexer.l" +{ return OPERATOR; } + YY_BREAK +case 104: +YY_RULE_SETUP +#line 232 "conf_lexer.l" +{ return OPER_PASS_RESV; } + YY_BREAK +case 105: +YY_RULE_SETUP +#line 233 "conf_lexer.l" +{ return OPERATOR; } + YY_BREAK +case 106: +YY_RULE_SETUP +#line 234 "conf_lexer.l" +{ return PASSWORD; } + YY_BREAK +case 107: +YY_RULE_SETUP +#line 235 "conf_lexer.l" +{ return PASSWORD; } + YY_BREAK +case 108: +YY_RULE_SETUP +#line 236 "conf_lexer.l" +{ return PING_COOKIE; } + YY_BREAK +case 109: +YY_RULE_SETUP +#line 237 "conf_lexer.l" +{ return PING_TIME; } + YY_BREAK +case 110: +YY_RULE_SETUP +#line 238 "conf_lexer.l" +{ return PING_WARNING; } + YY_BREAK +case 111: +YY_RULE_SETUP +#line 239 "conf_lexer.l" +{ return PORT; } + YY_BREAK +case 112: +YY_RULE_SETUP +#line 240 "conf_lexer.l" +{ return RESV; } + YY_BREAK +case 113: +YY_RULE_SETUP +#line 241 "conf_lexer.l" +{ return QUIET_ON_BAN; } + YY_BREAK +case 114: +YY_RULE_SETUP +#line 242 "conf_lexer.l" +{ return REASON; } + YY_BREAK +case 115: +YY_RULE_SETUP +#line 243 "conf_lexer.l" +{ return T_RECVQ; } + YY_BREAK +case 116: +YY_RULE_SETUP +#line 244 "conf_lexer.l" +{ return REDIRPORT; } + YY_BREAK +case 117: +YY_RULE_SETUP +#line 245 "conf_lexer.l" +{ return REDIRSERV; } + YY_BREAK +case 118: +YY_RULE_SETUP +#line 246 "conf_lexer.l" +{ return REGEX_T; } + YY_BREAK +case 119: +YY_RULE_SETUP +#line 247 "conf_lexer.l" +{ return REHASH; } + YY_BREAK +case 120: +YY_RULE_SETUP +#line 248 "conf_lexer.l" +{ return REMOTE; } + YY_BREAK +case 121: +YY_RULE_SETUP +#line 249 "conf_lexer.l" +{ return REMOTEBAN; } + YY_BREAK +case 122: +YY_RULE_SETUP +#line 250 "conf_lexer.l" +{ return T_RESTART; } + YY_BREAK +case 123: +YY_RULE_SETUP +#line 251 "conf_lexer.l" +{ return RESTRICT_CHANNELS; } + YY_BREAK +case 124: +YY_RULE_SETUP +#line 252 "conf_lexer.l" +{ return RESV; } + YY_BREAK +case 125: +YY_RULE_SETUP +#line 253 "conf_lexer.l" +{ return RESV_EXEMPT; } + YY_BREAK +case 126: +YY_RULE_SETUP +#line 254 "conf_lexer.l" +{ return RSA_PRIVATE_KEY_FILE; } + YY_BREAK +case 127: +YY_RULE_SETUP +#line 255 "conf_lexer.l" +{ return RSA_PUBLIC_KEY_FILE; } + YY_BREAK +case 128: +YY_RULE_SETUP +#line 256 "conf_lexer.l" +{ return T_SSL; } + YY_BREAK +case 129: +YY_RULE_SETUP +#line 257 "conf_lexer.l" +{ return SSL_CERTIFICATE_FILE; } + YY_BREAK +case 130: +YY_RULE_SETUP +#line 258 "conf_lexer.l" +{ return T_SSL_CLIENT_METHOD; } + YY_BREAK +case 131: +YY_RULE_SETUP +#line 259 "conf_lexer.l" +{ return T_SSL_SERVER_METHOD; } + YY_BREAK +case 132: +YY_RULE_SETUP +#line 260 "conf_lexer.l" +{ return SSL_DH_PARAM_FILE; } + YY_BREAK +case 133: +YY_RULE_SETUP +#line 261 "conf_lexer.l" +{ return T_SSL_CIPHER_LIST; } + YY_BREAK +case 134: +YY_RULE_SETUP +#line 262 "conf_lexer.l" +{ return T_SSLV3; } + YY_BREAK +case 135: +YY_RULE_SETUP +#line 263 "conf_lexer.l" +{ return T_TLSV1; } + YY_BREAK +case 136: +YY_RULE_SETUP +#line 264 "conf_lexer.l" +{ return SEND_PASSWORD; } + YY_BREAK +case 137: +YY_RULE_SETUP +#line 265 "conf_lexer.l" +{ return SENDQ; } + YY_BREAK +case 138: +YY_RULE_SETUP +#line 266 "conf_lexer.l" +{ return T_SERVER; } + YY_BREAK +case 139: +YY_RULE_SETUP +#line 267 "conf_lexer.l" +{ return SERVERHIDE; } + YY_BREAK +case 140: +YY_RULE_SETUP +#line 268 "conf_lexer.l" +{ return SERVERINFO; } + YY_BREAK +case 141: +YY_RULE_SETUP +#line 269 "conf_lexer.l" +{ return T_SERVICE; } + YY_BREAK +case 142: +YY_RULE_SETUP +#line 270 "conf_lexer.l" +{ return T_SERVICES_NAME; } + YY_BREAK +case 143: +YY_RULE_SETUP +#line 271 "conf_lexer.l" +{ return T_SET; } + YY_BREAK +case 144: +YY_RULE_SETUP +#line 272 "conf_lexer.l" +{ return T_SHARED; } + YY_BREAK +case 145: +YY_RULE_SETUP +#line 273 "conf_lexer.l" +{ return SHORT_MOTD; } + YY_BREAK +case 146: +YY_RULE_SETUP +#line 274 "conf_lexer.l" +{ return IRCD_SID; } + YY_BREAK +case 147: +YY_RULE_SETUP +#line 275 "conf_lexer.l" +{ return T_SIZE; } + YY_BREAK +case 148: +YY_RULE_SETUP +#line 276 "conf_lexer.l" +{ return SPOOF; } + YY_BREAK +case 149: +YY_RULE_SETUP +#line 277 "conf_lexer.l" +{ return SPOOF_NOTICE; } + YY_BREAK +case 150: +YY_RULE_SETUP +#line 278 "conf_lexer.l" +{ return TKLINE_EXPIRE_NOTICES; } + YY_BREAK +case 151: +YY_RULE_SETUP +#line 279 "conf_lexer.l" +{ return TYPE; } + YY_BREAK +case 152: +YY_RULE_SETUP +#line 280 "conf_lexer.l" +{ return TRUE_NO_OPER_FLOOD; } + YY_BREAK +case 153: +YY_RULE_SETUP +#line 281 "conf_lexer.l" +{ return T_UMODES; } + YY_BREAK +case 154: +YY_RULE_SETUP +#line 282 "conf_lexer.l" +{ return UNKLINE; } + YY_BREAK +case 155: +YY_RULE_SETUP +#line 283 "conf_lexer.l" +{ return T_UNDLINE; } + YY_BREAK +case 156: +YY_RULE_SETUP +#line 284 "conf_lexer.l" +{ return T_UNLIMITED; } + YY_BREAK +case 157: +YY_RULE_SETUP +#line 285 "conf_lexer.l" +{ return USE_EGD; } + YY_BREAK +case 158: +YY_RULE_SETUP +#line 286 "conf_lexer.l" +{ return USE_LOGGING; } + YY_BREAK +case 159: +YY_RULE_SETUP +#line 287 "conf_lexer.l" +{ return THROTTLE_TIME; } + YY_BREAK +case 160: +YY_RULE_SETUP +#line 288 "conf_lexer.l" +{ return USER; } + YY_BREAK +case 161: +YY_RULE_SETUP +#line 289 "conf_lexer.l" +{ return VHOST; } + YY_BREAK +case 162: +YY_RULE_SETUP +#line 290 "conf_lexer.l" +{ return VHOST6; } + YY_BREAK +case 163: +YY_RULE_SETUP +#line 291 "conf_lexer.l" +{ return XLINE; } + YY_BREAK +case 164: +YY_RULE_SETUP +#line 292 "conf_lexer.l" +{ yylval.number = 1; return TBOOL; } + YY_BREAK +case 165: +YY_RULE_SETUP +#line 294 "conf_lexer.l" +{ return FAILED_OPER_NOTICE; } + YY_BREAK +case 166: +YY_RULE_SETUP +#line 295 "conf_lexer.l" +{ return MAX_ACCEPT; } + YY_BREAK +case 167: +YY_RULE_SETUP +#line 296 "conf_lexer.l" +{ return MAX_NICK_CHANGES; } + YY_BREAK +case 168: +YY_RULE_SETUP +#line 297 "conf_lexer.l" +{ return MAX_CHANS_PER_OPER; } + YY_BREAK +case 169: +YY_RULE_SETUP +#line 298 "conf_lexer.l" +{ return MAX_CHANS_PER_USER; } + YY_BREAK +case 170: +YY_RULE_SETUP +#line 299 "conf_lexer.l" +{ return MAX_NICK_TIME; } + YY_BREAK +case 171: +YY_RULE_SETUP +#line 300 "conf_lexer.l" +{ return ANTI_NICK_FLOOD; } + YY_BREAK +case 172: +YY_RULE_SETUP +#line 301 "conf_lexer.l" +{ return ANTI_SPAM_EXIT_MESSAGE_TIME; } + YY_BREAK +case 173: +YY_RULE_SETUP +#line 302 "conf_lexer.l" +{ return TS_MAX_DELTA; } + YY_BREAK +case 174: +YY_RULE_SETUP +#line 303 "conf_lexer.l" +{ return TS_WARN_DELTA; } + YY_BREAK +case 175: +YY_RULE_SETUP +#line 304 "conf_lexer.l" +{ return LINKS_DELAY; } + YY_BREAK +case 176: +YY_RULE_SETUP +#line 305 "conf_lexer.l" +{ return WARN_NO_NLINE; } + YY_BREAK +case 177: +YY_RULE_SETUP +#line 307 "conf_lexer.l" +{ return STATS_E_DISABLED; } + YY_BREAK +case 178: +YY_RULE_SETUP +#line 308 "conf_lexer.l" +{ return STATS_O_OPER_ONLY; } + YY_BREAK +case 179: +YY_RULE_SETUP +#line 309 "conf_lexer.l" +{ return STATS_K_OPER_ONLY; } + YY_BREAK +case 180: +YY_RULE_SETUP +#line 310 "conf_lexer.l" +{ return STATS_I_OPER_ONLY; } + YY_BREAK +case 181: +YY_RULE_SETUP +#line 311 "conf_lexer.l" +{ return STATS_P_OPER_ONLY; } + YY_BREAK +case 182: +YY_RULE_SETUP +#line 312 "conf_lexer.l" +{ return PACE_WAIT; } + YY_BREAK +case 183: +YY_RULE_SETUP +#line 313 "conf_lexer.l" +{ return PACE_WAIT_SIMPLE; } + YY_BREAK +case 184: +YY_RULE_SETUP +#line 314 "conf_lexer.l" +{ return KNOCK_DELAY; } + YY_BREAK +case 185: +YY_RULE_SETUP +#line 315 "conf_lexer.l" +{ return KNOCK_DELAY_CHANNEL; } + YY_BREAK +case 186: +YY_RULE_SETUP +#line 316 "conf_lexer.l" +{ return MAX_BANS; } + YY_BREAK +case 187: +YY_RULE_SETUP +#line 317 "conf_lexer.l" +{ return MODULES; } + YY_BREAK +case 188: +YY_RULE_SETUP +#line 318 "conf_lexer.l" +{ return MODULE; } + YY_BREAK +case 189: +YY_RULE_SETUP +#line 319 "conf_lexer.l" +{ return PATH; } + YY_BREAK +case 190: +YY_RULE_SETUP +#line 320 "conf_lexer.l" +{ return MAX_TARGETS; } + YY_BREAK +case 191: +YY_RULE_SETUP +#line 322 "conf_lexer.l" +{ return T_UNXLINE; } + YY_BREAK +case 192: +YY_RULE_SETUP +#line 323 "conf_lexer.l" +{ return T_UNRESV; } + YY_BREAK +case 193: +YY_RULE_SETUP +#line 325 "conf_lexer.l" +{ return OPER_ONLY_UMODES; } + YY_BREAK +case 194: +YY_RULE_SETUP +#line 326 "conf_lexer.l" +{ return OPER_UMODES; } + YY_BREAK +case 195: +YY_RULE_SETUP +#line 327 "conf_lexer.l" +{ return T_BOTS; } + YY_BREAK +case 196: +YY_RULE_SETUP +#line 328 "conf_lexer.l" +{ return T_CCONN; } + YY_BREAK +case 197: +YY_RULE_SETUP +#line 329 "conf_lexer.l" +{ return T_CCONN_FULL; } + YY_BREAK +case 198: +YY_RULE_SETUP +#line 330 "conf_lexer.l" +{ return T_DEAF; } + YY_BREAK +case 199: +YY_RULE_SETUP +#line 331 "conf_lexer.l" +{ return T_DEBUG; } + YY_BREAK +case 200: +YY_RULE_SETUP +#line 332 "conf_lexer.l" +{ return T_FULL; } + YY_BREAK +case 201: +YY_RULE_SETUP +#line 333 "conf_lexer.l" +{ return T_SKILL; } + YY_BREAK +case 202: +YY_RULE_SETUP +#line 334 "conf_lexer.l" +{ return T_NCHANGE; } + YY_BREAK +case 203: +YY_RULE_SETUP +#line 335 "conf_lexer.l" +{ return T_REJ; } + YY_BREAK +case 204: +YY_RULE_SETUP +#line 336 "conf_lexer.l" +{ return T_UNAUTH; } + YY_BREAK +case 205: +YY_RULE_SETUP +#line 337 "conf_lexer.l" +{ return T_SPY; } + YY_BREAK +case 206: +YY_RULE_SETUP +#line 338 "conf_lexer.l" +{ return T_EXTERNAL; } + YY_BREAK +case 207: +YY_RULE_SETUP +#line 339 "conf_lexer.l" +{ return T_OPERWALL; } + YY_BREAK +case 208: +YY_RULE_SETUP +#line 340 "conf_lexer.l" +{ return T_SERVNOTICE; } + YY_BREAK +case 209: +YY_RULE_SETUP +#line 341 "conf_lexer.l" +{ return T_INVISIBLE; } + YY_BREAK +case 210: +YY_RULE_SETUP +#line 342 "conf_lexer.l" +{ return T_WALLOP; } + YY_BREAK +case 211: +YY_RULE_SETUP +#line 343 "conf_lexer.l" +{ return T_CALLERID; } + YY_BREAK +case 212: +YY_RULE_SETUP +#line 344 "conf_lexer.l" +{ return T_SOFTCALLERID; } + YY_BREAK +case 213: +YY_RULE_SETUP +#line 345 "conf_lexer.l" +{ return T_LOCOPS; } + YY_BREAK +case 214: +YY_RULE_SETUP +#line 347 "conf_lexer.l" +{ return WEEKS; } + YY_BREAK +case 215: +YY_RULE_SETUP +#line 348 "conf_lexer.l" +{ return WEEKS; } + YY_BREAK +case 216: +YY_RULE_SETUP +#line 349 "conf_lexer.l" +{ return DAYS; } + YY_BREAK +case 217: +YY_RULE_SETUP +#line 350 "conf_lexer.l" +{ return DAYS; } + YY_BREAK +case 218: +YY_RULE_SETUP +#line 351 "conf_lexer.l" +{ return HOURS; } + YY_BREAK +case 219: +YY_RULE_SETUP +#line 352 "conf_lexer.l" +{ return HOURS; } + YY_BREAK +case 220: +YY_RULE_SETUP +#line 353 "conf_lexer.l" +{ return MINUTES; } + YY_BREAK +case 221: +YY_RULE_SETUP +#line 354 "conf_lexer.l" +{ return MINUTES; } + YY_BREAK +case 222: +YY_RULE_SETUP +#line 355 "conf_lexer.l" +{ return SECONDS; } + YY_BREAK +case 223: +YY_RULE_SETUP +#line 356 "conf_lexer.l" +{ return SECONDS; } + YY_BREAK +case 224: +YY_RULE_SETUP +#line 358 "conf_lexer.l" +{ return BYTES; } + YY_BREAK +case 225: +YY_RULE_SETUP +#line 359 "conf_lexer.l" +{ return BYTES; } + YY_BREAK +case 226: +YY_RULE_SETUP +#line 360 "conf_lexer.l" +{ return KBYTES; } + YY_BREAK +case 227: +YY_RULE_SETUP +#line 361 "conf_lexer.l" +{ return KBYTES; } + YY_BREAK +case 228: +YY_RULE_SETUP +#line 362 "conf_lexer.l" +{ return KBYTES; } + YY_BREAK +case 229: +YY_RULE_SETUP +#line 363 "conf_lexer.l" +{ return KBYTES; } + YY_BREAK +case 230: +YY_RULE_SETUP +#line 364 "conf_lexer.l" +{ return KBYTES; } + YY_BREAK +case 231: +YY_RULE_SETUP +#line 365 "conf_lexer.l" +{ return MBYTES; } + YY_BREAK +case 232: +YY_RULE_SETUP +#line 366 "conf_lexer.l" +{ return MBYTES; } + YY_BREAK +case 233: +YY_RULE_SETUP +#line 367 "conf_lexer.l" +{ return MBYTES; } + YY_BREAK +case 234: +YY_RULE_SETUP +#line 368 "conf_lexer.l" +{ return MBYTES; } + YY_BREAK +case 235: +YY_RULE_SETUP +#line 369 "conf_lexer.l" +{ return MBYTES; } + YY_BREAK +case 236: +YY_RULE_SETUP +#line 370 "conf_lexer.l" +{ return TWODOTS; } + YY_BREAK +case 237: +YY_RULE_SETUP +#line 372 "conf_lexer.l" +{ return yytext[0]; } + YY_BREAK +case YY_STATE_EOF(INITIAL): +#line 373 "conf_lexer.l" +{ if (ieof()) yyterminate(); } + YY_BREAK +case 238: +YY_RULE_SETUP +#line 375 "conf_lexer.l" +ECHO; + YY_BREAK +#line 3206 "conf_lexer.c" + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1546 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1546 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 1545); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ); + + yyfree((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +yy_size_t yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno (int line_number ) +{ + + yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str ) +{ + yyin = in_str ; +} + +void yyset_out (FILE * out_str ) +{ + yyout = out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int bdebug ) +{ + yy_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 375 "conf_lexer.l" + + + +/* C-comment ignoring routine -kre*/ +static void +ccomment(void) +{ + int c = 0; + + /* log(L_NOTICE, "got comment"); */ + while (1) + { + while ((c = input()) != '*' && c != EOF) + if (c == '\n') + ++lineno; + + if (c == '*') + { + while ((c = input()) == '*') + /* Nothing */ ; + if (c == '/') + break; + else if (c == '\n') + ++lineno; + } + + if (c == EOF) + { + YY_FATAL_ERROR("EOF in comment"); + /* XXX hack alert this disables + * the stupid unused function warning + * gcc generates + */ + if (1 == 0) + yy_fatal_error("EOF in comment"); + break; + } + } +} + +/* C-style .includes. This function will properly swap input conf buffers, + * and lineno -kre */ +static void +cinclude(void) +{ + char *p = NULL; + + if ((p = strchr(yytext, '<')) == NULL) + *strchr(p = strchr(yytext, '"') + 1, '"') = '\0'; + else + *strchr(++p, '>') = '\0'; + + /* log(L_NOTICE, "got include %s!", c); */ + + /* do stacking and co. */ + if (include_stack_ptr >= MAX_INCLUDE_DEPTH) + ilog(LOG_TYPE_IRCD, "Includes nested too deep in %s", p); + else + { + FILE *tmp_fbfile_in = NULL; + char filenamebuf[IRCD_BUFSIZE]; + + if (*p == '/') /* if it is an absolute path */ + snprintf(filenamebuf, sizeof(filenamebuf), "%s", p); + else + snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", ETCPATH, p); + + tmp_fbfile_in = fopen(filenamebuf, "r"); + + if (tmp_fbfile_in == NULL) + { + ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s", + filenamebuf, strerror(errno)); + return; + } + + lineno_stack[include_stack_ptr] = lineno; + lineno = 1; + inc_fbfile_in[include_stack_ptr] = conf_parser_ctx.conf_file; + strlcpy(conffile_stack[include_stack_ptr], conffilebuf, IRCD_BUFSIZE); + include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; + conf_parser_ctx.conf_file = tmp_fbfile_in; + snprintf(conffilebuf, sizeof(conffilebuf), "%s", filenamebuf); + yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE)); + } +} + +/* This is function that will be called on EOF in conf file. It will + * apropriately close conf if it not main conf and swap input buffers -kre + * */ +static int +ieof(void) +{ + /* log(L_NOTICE, "return from include stack!"); */ + if (include_stack_ptr) + fclose(conf_parser_ctx.conf_file); + if (--include_stack_ptr < 0) + { + /* log(L_NOTICE, "terminating lexer"); */ + /* We will now exit the lexer - restore init values if we get /rehash + * later and reenter lexer -kre */ + include_stack_ptr = 0; + lineno = 1; + return 1; + } + + /* switch buffer */ + /* log(L_NOTICE, "deleting include_stack_ptr=%d", include_stack_ptr); */ + yy_delete_buffer(YY_CURRENT_BUFFER); + lineno = lineno_stack[include_stack_ptr]; + conf_parser_ctx.conf_file = inc_fbfile_in[include_stack_ptr]; + strlcpy(conffilebuf, conffile_stack[include_stack_ptr], sizeof(conffilebuf)); + yy_switch_to_buffer(include_stack[include_stack_ptr]); + + return 0; +} + diff --git a/src/conf_lexer.l b/src/conf_lexer.l new file mode 100644 index 0000000..d089a57 --- /dev/null +++ b/src/conf_lexer.l @@ -0,0 +1,489 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * conf_lexer.l: Scans the ircd configuration file for tokens. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +%option case-insensitive +%option noyywrap +%option nounput +%option never-interactive + +%{ +#include "stdinc.h" +#include "irc_string.h" +#include "conf.h" +#include "conf_parser.h" /* autogenerated header file */ +#include "memory.h" +#include "hostmask.h" +#include "log.h" + +#undef YY_INPUT +#define YY_FATAL_ERROR(msg) conf_yy_fatal_error(msg) +#define YY_INPUT(buf,result,max_size) \ + if (!(result = conf_yy_input(buf, max_size))) \ + YY_FATAL_ERROR("input in flex scanner failed"); +#define MAX_INCLUDE_DEPTH 10 + + +unsigned int lineno = 1; +char linebuf[IRCD_BUFSIZE]; +char conffilebuf[IRCD_BUFSIZE]; + +static int include_stack_ptr = 0; +static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; +static unsigned int lineno_stack[MAX_INCLUDE_DEPTH]; +static FILE *inc_fbfile_in[MAX_INCLUDE_DEPTH]; +static char conffile_stack[MAX_INCLUDE_DEPTH][IRCD_BUFSIZE]; +static void ccomment(void); +static void cinclude(void); +static int ieof(void); + +static int +conf_yy_input(char *lbuf, unsigned int max_size) +{ + return !fgets(lbuf, max_size, conf_parser_ctx.conf_file) ? 0 : strlen(lbuf); +} + +static int +conf_yy_fatal_error(const char *msg) +{ + return 0; +} + +%} + +WS [[:blank:]]* +DIGIT [[:digit:]]+ +COMMENT ("//"|"#").* +qstring \"[^\"\n]*[\"\n] +include \.include{WS}(\<.*\>|\".*\") + +%% +{include} { cinclude(); } +"/*" { ccomment(); } + +\n.* { strlcpy(linebuf, yytext+1, sizeof(linebuf)); ++lineno; yyless(1); } + +{WS} ; +{COMMENT} ; + +{DIGIT} { yylval.number = atoi(yytext); return NUMBER; } + +{qstring} { if (yytext[yyleng-2] == '\\') + { + yyless(yyleng-1); /* return last quote */ + yymore(); /* append next string */ + } + else + { + yylval.string = yytext+1; + if(yylval.string[yyleng-2] != '"') + ilog(LOG_TYPE_IRCD, "Unterminated character string"); + else + { + int i,j; + + yylval.string[yyleng-2] = '\0'; /* remove close + * quote + */ + + for (j=i=0 ;yylval.string[i] != '\0'; i++,j++) + { + if (yylval.string[i] != '\\') + { + yylval.string[j] = yylval.string[i]; + } + else + { + i++; + if (yylval.string[i] == '\0') /* XXX + * should not + * happen + */ + { + ilog(LOG_TYPE_IRCD, + "Unterminated character string"); + break; + } + yylval.string[j] = yylval.string[i]; + } + } + yylval.string[j] = '\0'; + return QSTRING; + } + } + } + +accept_password { return ACCEPT_PASSWORD; } +admin { return ADMIN; } +administrator { return ADMIN; } +aftype { return AFTYPE; } +all { return T_ALL; } +auth { return IRCD_AUTH; } +autoconn { return AUTOCONN; } +can_flood { return CAN_FLOOD; } +caller_id_wait { return CALLER_ID_WAIT; } +opers_bypass_callerid { return OPERS_BYPASS_CALLERID; } +channel { return CHANNEL; } +cidr_bitlen_ipv4 { return CIDR_BITLEN_IPV4; } +cidr_bitlen_ipv6 { return CIDR_BITLEN_IPV6; } +class { return CLASS; } +cluster { return T_CLUSTER; } +connect { return CONNECT; } +connectfreq { return CONNECTFREQ; } +default_floodcount { return DEFAULT_FLOODCOUNT; } +default_split_server_count { return DEFAULT_SPLIT_SERVER_COUNT; } +default_split_user_count { return DEFAULT_SPLIT_USER_COUNT; } +deny { return DENY; } +description { return DESCRIPTION; } +die { return DIE; } +disable_auth { return DISABLE_AUTH; } +disable_fake_channels { return DISABLE_FAKE_CHANNELS; } +disable_remote_commands { return DISABLE_REMOTE_COMMANDS; } +dline { return T_DLINE; } +dots_in_ident { return DOTS_IN_IDENT; } +egdpool_path { return EGDPOOL_PATH; } +email { return EMAIL; } +encrypted { return ENCRYPTED; } +exceed_limit { return EXCEED_LIMIT; } +exempt { return EXEMPT; } +file { return T_FILE; } +flags { return IRCD_FLAGS; } +flatten_links { return FLATTEN_LINKS; } +gecos { return GECOS; } +general { return GENERAL; } +gline { return GLINE; } +gline_enable { return GLINE_ENABLE; } +gline_exempt { return GLINE_EXEMPT; } +gline_duration { return GLINE_DURATION; } +gline_request_duration { return GLINE_REQUEST_DURATION; } +gline_min_cidr { return GLINE_MIN_CIDR; } +gline_min_cidr6 { return GLINE_MIN_CIDR6; } +globops { return T_GLOBOPS; } +global_kill { return GLOBAL_KILL; } +have_ident { return NEED_IDENT; } +need_ident { return NEED_IDENT; } +havent_read_conf { return HAVENT_READ_CONF; } +hidden { return HIDDEN; } +hidden_name { return HIDDEN_NAME; } +hide_server_ips { return HIDE_SERVER_IPS; } +hide_servers { return HIDE_SERVERS; } +hide_spoof_ips { return HIDE_SPOOF_IPS; } +host { return HOST; } +hub { return HUB; } +hub_mask { return HUB_MASK; } +ignore_bogus_ts { return IGNORE_BOGUS_TS; } +invisible_on_connect { return INVISIBLE_ON_CONNECT; } +ip { return IP; } +ipv4 { return T_IPV4; } +ipv6 { return T_IPV6; } +join_flood_count { return JOIN_FLOOD_COUNT; } +join_flood_time { return JOIN_FLOOD_TIME; } +kill { return KILL; } +kill_chase_time_limit { return KILL_CHASE_TIME_LIMIT; } +kline { return KLINE; } +kline_exempt { return KLINE_EXEMPT; } +leaf_mask { return LEAF_MASK; } +listen { return LISTEN; } +log { return T_LOG; } +masked { return TMASKED; } +max_clients { return T_MAX_CLIENTS; } +max_ident { return MAX_IDENT; } +max_local { return MAX_LOCAL; } +max_global { return MAX_GLOBAL; } +max_number { return MAX_NUMBER; } +max_watch { return MAX_WATCH; } +message_locale { return MESSAGE_LOCALE; } +min_nonwildcard { return MIN_NONWILDCARD; } +min_nonwildcard_simple { return MIN_NONWILDCARD_SIMPLE; } +name { return NAME; } +need_password { return NEED_PASSWORD; } +network_desc { return NETWORK_DESC; } +network_name { return NETWORK_NAME; } +nick { return NICK; } +nick_changes { return NICK_CHANGES; } +no { yylval.number = 0; return TBOOL; } +no_create_on_split { return NO_CREATE_ON_SPLIT; } +no_join_on_split { return NO_JOIN_ON_SPLIT; } +no_oper_flood { return NO_OPER_FLOOD; } +no_tilde { return NO_TILDE; } +number_per_cidr { return NUMBER_PER_CIDR; } +number_per_ip { return NUMBER_PER_IP; } +oper { return OPERATOR; } +oper_pass_resv { return OPER_PASS_RESV; } +operator { return OPERATOR; } +passwd { return PASSWORD; } +password { return PASSWORD; } +ping_cookie { return PING_COOKIE; } +ping_time { return PING_TIME; } +ping_warning { return PING_WARNING; } +port { return PORT; } +quarantine { return RESV; } +quiet_on_ban { return QUIET_ON_BAN; } +reason { return REASON; } +recvq { return T_RECVQ; } +redirport { return REDIRPORT; } +redirserv { return REDIRSERV; } +regex { return REGEX_T; } +rehash { return REHASH; } +remote { return REMOTE; } +remoteban { return REMOTEBAN; } +restart { return T_RESTART; } +restrict_channels { return RESTRICT_CHANNELS; } +resv { return RESV; } +resv_exempt { return RESV_EXEMPT; } +rsa_private_key_file { return RSA_PRIVATE_KEY_FILE; } +rsa_public_key_file { return RSA_PUBLIC_KEY_FILE; } +ssl { return T_SSL; } +ssl_certificate_file { return SSL_CERTIFICATE_FILE; } +ssl_client_method { return T_SSL_CLIENT_METHOD; } +ssl_server_method { return T_SSL_SERVER_METHOD; } +ssl_dh_param_file { return SSL_DH_PARAM_FILE; } +ssl_cipher_list { return T_SSL_CIPHER_LIST; } +sslv3 { return T_SSLV3; } +tlsv1 { return T_TLSV1; } +send_password { return SEND_PASSWORD; } +sendq { return SENDQ; } +server { return T_SERVER; } +serverhide { return SERVERHIDE; } +serverinfo { return SERVERINFO; } +service { return T_SERVICE; } +services_name { return T_SERVICES_NAME; } +set { return T_SET; } +shared { return T_SHARED; } +short_motd { return SHORT_MOTD; } +sid { return IRCD_SID; } +size { return T_SIZE; } +spoof { return SPOOF; } +spoof_notice { return SPOOF_NOTICE; } +tkline_expire_notices { return TKLINE_EXPIRE_NOTICES; } +type { return TYPE; } +true_no_oper_flood { return TRUE_NO_OPER_FLOOD; } +umodes { return T_UMODES; } +unkline { return UNKLINE; } +undline { return T_UNDLINE; } +unlimited { return T_UNLIMITED; } +use_egd { return USE_EGD; } +use_logging { return USE_LOGGING; } +throttle_time { return THROTTLE_TIME; } +user { return USER; } +vhost { return VHOST; } +vhost6 { return VHOST6; } +xline { return XLINE; } +yes { yylval.number = 1; return TBOOL; } + +failed_oper_notice { return FAILED_OPER_NOTICE; } +max_accept { return MAX_ACCEPT; } +max_nick_changes { return MAX_NICK_CHANGES; } +max_chans_per_oper { return MAX_CHANS_PER_OPER; } +max_chans_per_user { return MAX_CHANS_PER_USER; } +max_nick_time { return MAX_NICK_TIME; } +anti_nick_flood { return ANTI_NICK_FLOOD; } +anti_spam_exit_message_time { return ANTI_SPAM_EXIT_MESSAGE_TIME; } +ts_max_delta { return TS_MAX_DELTA; } +ts_warn_delta { return TS_WARN_DELTA; } +links_delay { return LINKS_DELAY; } +warn_no_nline { return WARN_NO_NLINE; } + +stats_e_disabled { return STATS_E_DISABLED; } +stats_o_oper_only { return STATS_O_OPER_ONLY; } +stats_k_oper_only { return STATS_K_OPER_ONLY; } +stats_i_oper_only { return STATS_I_OPER_ONLY; } +stats_P_oper_only { return STATS_P_OPER_ONLY; } +pace_wait { return PACE_WAIT; } +pace_wait_simple { return PACE_WAIT_SIMPLE; } +knock_delay { return KNOCK_DELAY; } +knock_delay_channel { return KNOCK_DELAY_CHANNEL; } +max_bans { return MAX_BANS; } +modules { return MODULES; } +module { return MODULE; } +path { return PATH; } +max_targets { return MAX_TARGETS; } + +unxline { return T_UNXLINE; } +unresv { return T_UNRESV; } + +oper_only_umodes { return OPER_ONLY_UMODES; } +oper_umodes { return OPER_UMODES; } +bots { return T_BOTS; } +cconn { return T_CCONN; } +cconn_full { return T_CCONN_FULL; } +deaf { return T_DEAF; } +debug { return T_DEBUG; } +full { return T_FULL; } +skill { return T_SKILL; } +nchange { return T_NCHANGE; } +rej { return T_REJ; } +unauth { return T_UNAUTH; } +spy { return T_SPY; } +external { return T_EXTERNAL; } +operwall { return T_OPERWALL; } +servnotice { return T_SERVNOTICE; } +invisible { return T_INVISIBLE; } +wallop { return T_WALLOP; } +callerid { return T_CALLERID; } +softcallerid { return T_SOFTCALLERID; } +locops { return T_LOCOPS; } + +weeks { return WEEKS; } +week { return WEEKS; } +days { return DAYS; } +day { return DAYS; } +hours { return HOURS; } +hour { return HOURS; } +minutes { return MINUTES; } +minute { return MINUTES; } +seconds { return SECONDS; } +second { return SECONDS; } + +bytes { return BYTES; } +byte { return BYTES; } +kilobytes { return KBYTES; } +kilobyte { return KBYTES; } +kbytes { return KBYTES; } +kbyte { return KBYTES; } +kb { return KBYTES; } +megabytes { return MBYTES; } +megabyte { return MBYTES; } +mbytes { return MBYTES; } +mbyte { return MBYTES; } +mb { return MBYTES; } +\.\. { return TWODOTS; } + +. { return yytext[0]; } +<<EOF>> { if (ieof()) yyterminate(); } + +%% + +/* C-comment ignoring routine -kre*/ +static void +ccomment(void) +{ + int c = 0; + + /* log(L_NOTICE, "got comment"); */ + while (1) + { + while ((c = input()) != '*' && c != EOF) + if (c == '\n') + ++lineno; + + if (c == '*') + { + while ((c = input()) == '*') + /* Nothing */ ; + if (c == '/') + break; + else if (c == '\n') + ++lineno; + } + + if (c == EOF) + { + YY_FATAL_ERROR("EOF in comment"); + /* XXX hack alert this disables + * the stupid unused function warning + * gcc generates + */ + if (1 == 0) + yy_fatal_error("EOF in comment"); + break; + } + } +} + +/* C-style .includes. This function will properly swap input conf buffers, + * and lineno -kre */ +static void +cinclude(void) +{ + char *p = NULL; + + if ((p = strchr(yytext, '<')) == NULL) + *strchr(p = strchr(yytext, '"') + 1, '"') = '\0'; + else + *strchr(++p, '>') = '\0'; + + /* log(L_NOTICE, "got include %s!", c); */ + + /* do stacking and co. */ + if (include_stack_ptr >= MAX_INCLUDE_DEPTH) + ilog(LOG_TYPE_IRCD, "Includes nested too deep in %s", p); + else + { + FILE *tmp_fbfile_in = NULL; + char filenamebuf[IRCD_BUFSIZE]; + + if (*p == '/') /* if it is an absolute path */ + snprintf(filenamebuf, sizeof(filenamebuf), "%s", p); + else + snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", ETCPATH, p); + + tmp_fbfile_in = fopen(filenamebuf, "r"); + + if (tmp_fbfile_in == NULL) + { + ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s", + filenamebuf, strerror(errno)); + return; + } + + lineno_stack[include_stack_ptr] = lineno; + lineno = 1; + inc_fbfile_in[include_stack_ptr] = conf_parser_ctx.conf_file; + strlcpy(conffile_stack[include_stack_ptr], conffilebuf, IRCD_BUFSIZE); + include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; + conf_parser_ctx.conf_file = tmp_fbfile_in; + snprintf(conffilebuf, sizeof(conffilebuf), "%s", filenamebuf); + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + } +} + +/* This is function that will be called on EOF in conf file. It will + * apropriately close conf if it not main conf and swap input buffers -kre + * */ +static int +ieof(void) +{ + /* log(L_NOTICE, "return from include stack!"); */ + if (include_stack_ptr) + fclose(conf_parser_ctx.conf_file); + if (--include_stack_ptr < 0) + { + /* log(L_NOTICE, "terminating lexer"); */ + /* We will now exit the lexer - restore init values if we get /rehash + * later and reenter lexer -kre */ + include_stack_ptr = 0; + lineno = 1; + return 1; + } + + /* switch buffer */ + /* log(L_NOTICE, "deleting include_stack_ptr=%d", include_stack_ptr); */ + yy_delete_buffer(YY_CURRENT_BUFFER); + lineno = lineno_stack[include_stack_ptr]; + conf_parser_ctx.conf_file = inc_fbfile_in[include_stack_ptr]; + strlcpy(conffilebuf, conffile_stack[include_stack_ptr], sizeof(conffilebuf)); + yy_switch_to_buffer(include_stack[include_stack_ptr]); + + return 0; +} diff --git a/src/conf_parser.c b/src/conf_parser.c new file mode 100644 index 0000000..294935c --- /dev/null +++ b/src/conf_parser.c @@ -0,0 +1,7071 @@ +/* A Bison parser, made by GNU Bison 2.6.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.6.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* Copy the first part of user declarations. */ +/* Line 336 of yacc.c */ +#line 25 "conf_parser.y" + + +#define YY_NO_UNPUT +#include <sys/types.h> +#include <string.h> + +#include "config.h" +#include "stdinc.h" +#include "ircd.h" +#include "list.h" +#include "conf.h" +#include "event.h" +#include "log.h" +#include "client.h" /* for UMODE_ALL only */ +#include "irc_string.h" +#include "sprintf_irc.h" +#include "memory.h" +#include "modules.h" +#include "s_serv.h" +#include "hostmask.h" +#include "send.h" +#include "listener.h" +#include "resv.h" +#include "numeric.h" +#include "s_user.h" + +#ifdef HAVE_LIBCRYPTO +#include <openssl/rsa.h> +#include <openssl/bio.h> +#include <openssl/pem.h> +#include <openssl/dh.h> +#endif + +int yylex(void); + +static char *class_name = NULL; +static struct ConfItem *yy_conf = NULL; +static struct AccessItem *yy_aconf = NULL; +static struct MatchItem *yy_match_item = NULL; +static struct ClassItem *yy_class = NULL; +static char *yy_class_name = NULL; + +static dlink_list col_conf_list = { NULL, NULL, 0 }; +static unsigned int listener_flags = 0; +static unsigned int regex_ban = 0; +static char userbuf[IRCD_BUFSIZE]; +static char hostbuf[IRCD_BUFSIZE]; +static char reasonbuf[REASONLEN + 1]; +static char gecos_name[REALLEN * 4]; +static char lfile[IRCD_BUFSIZE]; +static unsigned int ltype = 0; +static unsigned int lsize = 0; +static char *resv_reason = NULL; +static char *listener_address = NULL; + +struct CollectItem +{ + dlink_node node; + char *name; + char *user; + char *host; + char *passwd; + int port; + int flags; +#ifdef HAVE_LIBCRYPTO + char *rsa_public_key_file; + RSA *rsa_public_key; +#endif +}; + +static void +free_collect_item(struct CollectItem *item) +{ + MyFree(item->name); + MyFree(item->user); + MyFree(item->host); + MyFree(item->passwd); +#ifdef HAVE_LIBCRYPTO + MyFree(item->rsa_public_key_file); +#endif + MyFree(item); +} + + +/* Line 336 of yacc.c */ +#line 153 "conf_parser.c" + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "y.tab.h". */ +#ifndef YY_Y_TAB_H +# define YY_Y_TAB_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ACCEPT_PASSWORD = 258, + ADMIN = 259, + AFTYPE = 260, + ANTI_NICK_FLOOD = 261, + ANTI_SPAM_EXIT_MESSAGE_TIME = 262, + AUTOCONN = 263, + BYTES = 264, + KBYTES = 265, + MBYTES = 266, + CALLER_ID_WAIT = 267, + CAN_FLOOD = 268, + CHANNEL = 269, + CIDR_BITLEN_IPV4 = 270, + CIDR_BITLEN_IPV6 = 271, + CLASS = 272, + CONNECT = 273, + CONNECTFREQ = 274, + DEFAULT_FLOODCOUNT = 275, + DEFAULT_SPLIT_SERVER_COUNT = 276, + DEFAULT_SPLIT_USER_COUNT = 277, + DENY = 278, + DESCRIPTION = 279, + DIE = 280, + DISABLE_AUTH = 281, + DISABLE_FAKE_CHANNELS = 282, + DISABLE_REMOTE_COMMANDS = 283, + DOTS_IN_IDENT = 284, + EGDPOOL_PATH = 285, + EMAIL = 286, + ENCRYPTED = 287, + EXCEED_LIMIT = 288, + EXEMPT = 289, + FAILED_OPER_NOTICE = 290, + IRCD_FLAGS = 291, + FLATTEN_LINKS = 292, + GECOS = 293, + GENERAL = 294, + GLINE = 295, + GLINE_DURATION = 296, + GLINE_ENABLE = 297, + GLINE_EXEMPT = 298, + GLINE_REQUEST_DURATION = 299, + GLINE_MIN_CIDR = 300, + GLINE_MIN_CIDR6 = 301, + GLOBAL_KILL = 302, + IRCD_AUTH = 303, + NEED_IDENT = 304, + HAVENT_READ_CONF = 305, + HIDDEN = 306, + HIDDEN_NAME = 307, + HIDE_SERVER_IPS = 308, + HIDE_SERVERS = 309, + HIDE_SPOOF_IPS = 310, + HOST = 311, + HUB = 312, + HUB_MASK = 313, + IGNORE_BOGUS_TS = 314, + INVISIBLE_ON_CONNECT = 315, + IP = 316, + KILL = 317, + KILL_CHASE_TIME_LIMIT = 318, + KLINE = 319, + KLINE_EXEMPT = 320, + KNOCK_DELAY = 321, + KNOCK_DELAY_CHANNEL = 322, + LEAF_MASK = 323, + LINKS_DELAY = 324, + LISTEN = 325, + T_LOG = 326, + MAX_ACCEPT = 327, + MAX_BANS = 328, + MAX_CHANS_PER_OPER = 329, + MAX_CHANS_PER_USER = 330, + MAX_GLOBAL = 331, + MAX_IDENT = 332, + MAX_LOCAL = 333, + MAX_NICK_CHANGES = 334, + MAX_NICK_TIME = 335, + MAX_NUMBER = 336, + MAX_TARGETS = 337, + MAX_WATCH = 338, + MESSAGE_LOCALE = 339, + MIN_NONWILDCARD = 340, + MIN_NONWILDCARD_SIMPLE = 341, + MODULE = 342, + MODULES = 343, + NAME = 344, + NEED_PASSWORD = 345, + NETWORK_DESC = 346, + NETWORK_NAME = 347, + NICK = 348, + NICK_CHANGES = 349, + NO_CREATE_ON_SPLIT = 350, + NO_JOIN_ON_SPLIT = 351, + NO_OPER_FLOOD = 352, + NO_TILDE = 353, + NUMBER = 354, + NUMBER_PER_CIDR = 355, + NUMBER_PER_IP = 356, + OPERATOR = 357, + OPERS_BYPASS_CALLERID = 358, + OPER_ONLY_UMODES = 359, + OPER_PASS_RESV = 360, + OPER_SPY_T = 361, + OPER_UMODES = 362, + JOIN_FLOOD_COUNT = 363, + JOIN_FLOOD_TIME = 364, + PACE_WAIT = 365, + PACE_WAIT_SIMPLE = 366, + PASSWORD = 367, + PATH = 368, + PING_COOKIE = 369, + PING_TIME = 370, + PING_WARNING = 371, + PORT = 372, + QSTRING = 373, + QUIET_ON_BAN = 374, + REASON = 375, + REDIRPORT = 376, + REDIRSERV = 377, + REGEX_T = 378, + REHASH = 379, + REMOTE = 380, + REMOTEBAN = 381, + RESTRICT_CHANNELS = 382, + RSA_PRIVATE_KEY_FILE = 383, + RSA_PUBLIC_KEY_FILE = 384, + SSL_CERTIFICATE_FILE = 385, + SSL_DH_PARAM_FILE = 386, + T_SSL_CLIENT_METHOD = 387, + T_SSL_SERVER_METHOD = 388, + T_SSLV3 = 389, + T_TLSV1 = 390, + RESV = 391, + RESV_EXEMPT = 392, + SECONDS = 393, + MINUTES = 394, + HOURS = 395, + DAYS = 396, + WEEKS = 397, + SENDQ = 398, + SEND_PASSWORD = 399, + SERVERHIDE = 400, + SERVERINFO = 401, + IRCD_SID = 402, + TKLINE_EXPIRE_NOTICES = 403, + T_SHARED = 404, + T_CLUSTER = 405, + TYPE = 406, + SHORT_MOTD = 407, + SPOOF = 408, + SPOOF_NOTICE = 409, + STATS_E_DISABLED = 410, + STATS_I_OPER_ONLY = 411, + STATS_K_OPER_ONLY = 412, + STATS_O_OPER_ONLY = 413, + STATS_P_OPER_ONLY = 414, + TBOOL = 415, + TMASKED = 416, + TS_MAX_DELTA = 417, + TS_WARN_DELTA = 418, + TWODOTS = 419, + T_ALL = 420, + T_BOTS = 421, + T_SOFTCALLERID = 422, + T_CALLERID = 423, + T_CCONN = 424, + T_CCONN_FULL = 425, + T_SSL_CIPHER_LIST = 426, + T_DEAF = 427, + T_DEBUG = 428, + T_DLINE = 429, + T_EXTERNAL = 430, + T_FULL = 431, + T_INVISIBLE = 432, + T_IPV4 = 433, + T_IPV6 = 434, + T_LOCOPS = 435, + T_MAX_CLIENTS = 436, + T_NCHANGE = 437, + T_OPERWALL = 438, + T_RECVQ = 439, + T_REJ = 440, + T_SERVER = 441, + T_SERVNOTICE = 442, + T_SET = 443, + T_SKILL = 444, + T_SPY = 445, + T_SSL = 446, + T_UMODES = 447, + T_UNAUTH = 448, + T_UNDLINE = 449, + T_UNLIMITED = 450, + T_UNRESV = 451, + T_UNXLINE = 452, + T_GLOBOPS = 453, + T_WALLOP = 454, + T_RESTART = 455, + T_SERVICE = 456, + T_SERVICES_NAME = 457, + THROTTLE_TIME = 458, + TRUE_NO_OPER_FLOOD = 459, + UNKLINE = 460, + USER = 461, + USE_EGD = 462, + USE_LOGGING = 463, + VHOST = 464, + VHOST6 = 465, + XLINE = 466, + WARN_NO_NLINE = 467, + T_SIZE = 468, + T_FILE = 469 + }; +#endif +/* Tokens. */ +#define ACCEPT_PASSWORD 258 +#define ADMIN 259 +#define AFTYPE 260 +#define ANTI_NICK_FLOOD 261 +#define ANTI_SPAM_EXIT_MESSAGE_TIME 262 +#define AUTOCONN 263 +#define BYTES 264 +#define KBYTES 265 +#define MBYTES 266 +#define CALLER_ID_WAIT 267 +#define CAN_FLOOD 268 +#define CHANNEL 269 +#define CIDR_BITLEN_IPV4 270 +#define CIDR_BITLEN_IPV6 271 +#define CLASS 272 +#define CONNECT 273 +#define CONNECTFREQ 274 +#define DEFAULT_FLOODCOUNT 275 +#define DEFAULT_SPLIT_SERVER_COUNT 276 +#define DEFAULT_SPLIT_USER_COUNT 277 +#define DENY 278 +#define DESCRIPTION 279 +#define DIE 280 +#define DISABLE_AUTH 281 +#define DISABLE_FAKE_CHANNELS 282 +#define DISABLE_REMOTE_COMMANDS 283 +#define DOTS_IN_IDENT 284 +#define EGDPOOL_PATH 285 +#define EMAIL 286 +#define ENCRYPTED 287 +#define EXCEED_LIMIT 288 +#define EXEMPT 289 +#define FAILED_OPER_NOTICE 290 +#define IRCD_FLAGS 291 +#define FLATTEN_LINKS 292 +#define GECOS 293 +#define GENERAL 294 +#define GLINE 295 +#define GLINE_DURATION 296 +#define GLINE_ENABLE 297 +#define GLINE_EXEMPT 298 +#define GLINE_REQUEST_DURATION 299 +#define GLINE_MIN_CIDR 300 +#define GLINE_MIN_CIDR6 301 +#define GLOBAL_KILL 302 +#define IRCD_AUTH 303 +#define NEED_IDENT 304 +#define HAVENT_READ_CONF 305 +#define HIDDEN 306 +#define HIDDEN_NAME 307 +#define HIDE_SERVER_IPS 308 +#define HIDE_SERVERS 309 +#define HIDE_SPOOF_IPS 310 +#define HOST 311 +#define HUB 312 +#define HUB_MASK 313 +#define IGNORE_BOGUS_TS 314 +#define INVISIBLE_ON_CONNECT 315 +#define IP 316 +#define KILL 317 +#define KILL_CHASE_TIME_LIMIT 318 +#define KLINE 319 +#define KLINE_EXEMPT 320 +#define KNOCK_DELAY 321 +#define KNOCK_DELAY_CHANNEL 322 +#define LEAF_MASK 323 +#define LINKS_DELAY 324 +#define LISTEN 325 +#define T_LOG 326 +#define MAX_ACCEPT 327 +#define MAX_BANS 328 +#define MAX_CHANS_PER_OPER 329 +#define MAX_CHANS_PER_USER 330 +#define MAX_GLOBAL 331 +#define MAX_IDENT 332 +#define MAX_LOCAL 333 +#define MAX_NICK_CHANGES 334 +#define MAX_NICK_TIME 335 +#define MAX_NUMBER 336 +#define MAX_TARGETS 337 +#define MAX_WATCH 338 +#define MESSAGE_LOCALE 339 +#define MIN_NONWILDCARD 340 +#define MIN_NONWILDCARD_SIMPLE 341 +#define MODULE 342 +#define MODULES 343 +#define NAME 344 +#define NEED_PASSWORD 345 +#define NETWORK_DESC 346 +#define NETWORK_NAME 347 +#define NICK 348 +#define NICK_CHANGES 349 +#define NO_CREATE_ON_SPLIT 350 +#define NO_JOIN_ON_SPLIT 351 +#define NO_OPER_FLOOD 352 +#define NO_TILDE 353 +#define NUMBER 354 +#define NUMBER_PER_CIDR 355 +#define NUMBER_PER_IP 356 +#define OPERATOR 357 +#define OPERS_BYPASS_CALLERID 358 +#define OPER_ONLY_UMODES 359 +#define OPER_PASS_RESV 360 +#define OPER_SPY_T 361 +#define OPER_UMODES 362 +#define JOIN_FLOOD_COUNT 363 +#define JOIN_FLOOD_TIME 364 +#define PACE_WAIT 365 +#define PACE_WAIT_SIMPLE 366 +#define PASSWORD 367 +#define PATH 368 +#define PING_COOKIE 369 +#define PING_TIME 370 +#define PING_WARNING 371 +#define PORT 372 +#define QSTRING 373 +#define QUIET_ON_BAN 374 +#define REASON 375 +#define REDIRPORT 376 +#define REDIRSERV 377 +#define REGEX_T 378 +#define REHASH 379 +#define REMOTE 380 +#define REMOTEBAN 381 +#define RESTRICT_CHANNELS 382 +#define RSA_PRIVATE_KEY_FILE 383 +#define RSA_PUBLIC_KEY_FILE 384 +#define SSL_CERTIFICATE_FILE 385 +#define SSL_DH_PARAM_FILE 386 +#define T_SSL_CLIENT_METHOD 387 +#define T_SSL_SERVER_METHOD 388 +#define T_SSLV3 389 +#define T_TLSV1 390 +#define RESV 391 +#define RESV_EXEMPT 392 +#define SECONDS 393 +#define MINUTES 394 +#define HOURS 395 +#define DAYS 396 +#define WEEKS 397 +#define SENDQ 398 +#define SEND_PASSWORD 399 +#define SERVERHIDE 400 +#define SERVERINFO 401 +#define IRCD_SID 402 +#define TKLINE_EXPIRE_NOTICES 403 +#define T_SHARED 404 +#define T_CLUSTER 405 +#define TYPE 406 +#define SHORT_MOTD 407 +#define SPOOF 408 +#define SPOOF_NOTICE 409 +#define STATS_E_DISABLED 410 +#define STATS_I_OPER_ONLY 411 +#define STATS_K_OPER_ONLY 412 +#define STATS_O_OPER_ONLY 413 +#define STATS_P_OPER_ONLY 414 +#define TBOOL 415 +#define TMASKED 416 +#define TS_MAX_DELTA 417 +#define TS_WARN_DELTA 418 +#define TWODOTS 419 +#define T_ALL 420 +#define T_BOTS 421 +#define T_SOFTCALLERID 422 +#define T_CALLERID 423 +#define T_CCONN 424 +#define T_CCONN_FULL 425 +#define T_SSL_CIPHER_LIST 426 +#define T_DEAF 427 +#define T_DEBUG 428 +#define T_DLINE 429 +#define T_EXTERNAL 430 +#define T_FULL 431 +#define T_INVISIBLE 432 +#define T_IPV4 433 +#define T_IPV6 434 +#define T_LOCOPS 435 +#define T_MAX_CLIENTS 436 +#define T_NCHANGE 437 +#define T_OPERWALL 438 +#define T_RECVQ 439 +#define T_REJ 440 +#define T_SERVER 441 +#define T_SERVNOTICE 442 +#define T_SET 443 +#define T_SKILL 444 +#define T_SPY 445 +#define T_SSL 446 +#define T_UMODES 447 +#define T_UNAUTH 448 +#define T_UNDLINE 449 +#define T_UNLIMITED 450 +#define T_UNRESV 451 +#define T_UNXLINE 452 +#define T_GLOBOPS 453 +#define T_WALLOP 454 +#define T_RESTART 455 +#define T_SERVICE 456 +#define T_SERVICES_NAME 457 +#define THROTTLE_TIME 458 +#define TRUE_NO_OPER_FLOOD 459 +#define UNKLINE 460 +#define USER 461 +#define USE_EGD 462 +#define USE_LOGGING 463 +#define VHOST 464 +#define VHOST6 465 +#define XLINE 466 +#define WARN_NO_NLINE 467 +#define T_SIZE 468 +#define T_FILE 469 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 350 of yacc.c */ +#line 110 "conf_parser.y" + + int number; + char *string; + + +/* Line 350 of yacc.c */ +#line 630 "conf_parser.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE yylval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !YY_Y_TAB_H */ + +/* Copy the second part of user declarations. */ + +/* Line 353 of yacc.c */ +#line 658 "conf_parser.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 2 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 1206 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 220 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 283 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 627 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 1228 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 469 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 219, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 215, + 2, 218, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 217, 2, 216, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 4, 7, 9, 11, 13, 15, 17, + 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, + 39, 41, 43, 45, 47, 50, 53, 54, 56, 59, + 63, 67, 71, 75, 79, 80, 82, 85, 89, 93, + 97, 103, 106, 108, 110, 112, 115, 120, 125, 131, + 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, + 154, 156, 158, 160, 162, 164, 166, 169, 174, 179, + 183, 185, 187, 189, 193, 195, 197, 199, 204, 209, + 214, 219, 224, 229, 234, 239, 244, 249, 254, 259, + 264, 270, 273, 275, 277, 279, 281, 284, 289, 294, + 299, 305, 308, 310, 312, 314, 317, 322, 323, 330, + 333, 335, 337, 339, 341, 344, 349, 354, 359, 360, + 366, 370, 372, 374, 376, 378, 380, 382, 384, 386, + 387, 394, 397, 399, 401, 403, 405, 407, 409, 411, + 413, 415, 418, 423, 428, 433, 438, 443, 448, 449, + 455, 459, 461, 463, 465, 467, 469, 471, 473, 475, + 477, 479, 481, 483, 485, 487, 489, 491, 493, 495, + 497, 499, 501, 502, 508, 512, 514, 516, 518, 520, + 522, 524, 526, 528, 530, 532, 534, 536, 538, 540, + 542, 544, 546, 548, 550, 552, 553, 560, 563, 565, + 567, 569, 571, 573, 575, 577, 579, 581, 583, 585, + 587, 589, 591, 593, 596, 601, 606, 611, 616, 621, + 626, 631, 636, 641, 646, 651, 656, 661, 666, 667, + 674, 675, 681, 685, 687, 689, 691, 693, 696, 698, + 700, 702, 704, 706, 709, 710, 716, 720, 722, 724, + 728, 733, 738, 739, 746, 749, 751, 753, 755, 757, + 759, 761, 763, 765, 767, 770, 775, 780, 785, 790, + 791, 797, 801, 803, 805, 807, 809, 811, 813, 815, + 817, 819, 821, 826, 831, 836, 837, 844, 847, 849, + 851, 853, 855, 858, 863, 868, 873, 879, 882, 884, + 886, 888, 893, 894, 901, 904, 906, 908, 910, 912, + 915, 920, 925, 926, 932, 936, 938, 940, 942, 944, + 946, 948, 950, 952, 954, 956, 958, 959, 966, 969, + 971, 973, 975, 978, 983, 984, 990, 994, 996, 998, + 1000, 1002, 1004, 1006, 1008, 1010, 1012, 1014, 1016, 1017, + 1024, 1027, 1029, 1031, 1033, 1035, 1037, 1039, 1041, 1043, + 1045, 1047, 1049, 1051, 1053, 1055, 1058, 1063, 1068, 1073, + 1078, 1083, 1088, 1093, 1098, 1099, 1105, 1109, 1111, 1113, + 1115, 1120, 1125, 1130, 1135, 1140, 1141, 1148, 1149, 1155, + 1159, 1161, 1163, 1166, 1168, 1170, 1172, 1174, 1176, 1181, + 1186, 1187, 1194, 1197, 1199, 1201, 1203, 1205, 1210, 1215, + 1221, 1224, 1226, 1228, 1230, 1235, 1236, 1243, 1244, 1250, + 1254, 1256, 1258, 1261, 1263, 1265, 1267, 1269, 1271, 1276, + 1281, 1287, 1290, 1292, 1294, 1296, 1298, 1300, 1302, 1304, + 1306, 1308, 1310, 1312, 1314, 1316, 1318, 1320, 1322, 1324, + 1326, 1328, 1330, 1332, 1334, 1336, 1338, 1340, 1342, 1344, + 1346, 1348, 1350, 1352, 1354, 1356, 1358, 1360, 1362, 1364, + 1366, 1368, 1370, 1372, 1374, 1376, 1378, 1380, 1382, 1384, + 1386, 1388, 1390, 1392, 1397, 1402, 1407, 1412, 1417, 1422, + 1427, 1432, 1437, 1442, 1447, 1452, 1457, 1462, 1467, 1472, + 1477, 1482, 1487, 1492, 1497, 1502, 1507, 1512, 1517, 1522, + 1527, 1532, 1537, 1542, 1547, 1552, 1557, 1562, 1567, 1572, + 1577, 1582, 1587, 1592, 1597, 1602, 1607, 1612, 1617, 1622, + 1623, 1629, 1633, 1635, 1637, 1639, 1641, 1643, 1645, 1647, + 1649, 1651, 1653, 1655, 1657, 1659, 1661, 1663, 1665, 1667, + 1669, 1671, 1673, 1675, 1676, 1682, 1686, 1688, 1690, 1692, + 1694, 1696, 1698, 1700, 1702, 1704, 1706, 1708, 1710, 1712, + 1714, 1716, 1718, 1720, 1722, 1724, 1726, 1728, 1733, 1738, + 1743, 1749, 1752, 1754, 1756, 1758, 1760, 1762, 1764, 1766, + 1768, 1770, 1772, 1774, 1776, 1778, 1780, 1782, 1784, 1789, + 1794, 1799, 1804, 1809, 1814, 1819, 1824, 1829, 1834, 1839, + 1844, 1849, 1854, 1860, 1863, 1865, 1867, 1869, 1871, 1873, + 1875, 1877, 1879, 1884, 1889, 1894, 1899, 1904 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int16 yyrhs[] = +{ + 221, 0, -1, -1, 221, 222, -1, 254, -1, 260, + -1, 274, -1, 477, -1, 292, -1, 310, -1, 324, + -1, 232, -1, 494, -1, 339, -1, 346, -1, 350, + -1, 360, -1, 369, -1, 389, -1, 399, -1, 405, + -1, 419, -1, 409, -1, 227, -1, 1, 215, -1, + 1, 216, -1, -1, 224, -1, 99, 223, -1, 99, + 138, 223, -1, 99, 139, 223, -1, 99, 140, 223, + -1, 99, 141, 223, -1, 99, 142, 223, -1, -1, + 226, -1, 99, 225, -1, 99, 9, 225, -1, 99, + 10, 225, -1, 99, 11, 225, -1, 88, 217, 228, + 216, 215, -1, 228, 229, -1, 229, -1, 230, -1, + 231, -1, 1, 215, -1, 87, 218, 118, 215, -1, + 113, 218, 118, 215, -1, 146, 217, 233, 216, 215, + -1, 233, 234, -1, 234, -1, 245, -1, 250, -1, + 253, -1, 247, -1, 248, -1, 249, -1, 252, -1, + 243, -1, 242, -1, 251, -1, 246, -1, 241, -1, + 235, -1, 236, -1, 244, -1, 1, 215, -1, 132, + 218, 237, 215, -1, 133, 218, 239, 215, -1, 237, + 219, 238, -1, 238, -1, 134, -1, 135, -1, 239, + 219, 240, -1, 240, -1, 134, -1, 135, -1, 130, + 218, 118, 215, -1, 128, 218, 118, 215, -1, 131, + 218, 118, 215, -1, 171, 218, 118, 215, -1, 89, + 218, 118, 215, -1, 147, 218, 118, 215, -1, 24, + 218, 118, 215, -1, 92, 218, 118, 215, -1, 91, + 218, 118, 215, -1, 209, 218, 118, 215, -1, 210, + 218, 118, 215, -1, 181, 218, 99, 215, -1, 57, + 218, 160, 215, -1, 4, 217, 255, 216, 215, -1, + 255, 256, -1, 256, -1, 257, -1, 259, -1, 258, + -1, 1, 215, -1, 89, 218, 118, 215, -1, 31, + 218, 118, 215, -1, 24, 218, 118, 215, -1, 71, + 217, 261, 216, 215, -1, 261, 262, -1, 262, -1, + 263, -1, 264, -1, 1, 215, -1, 208, 218, 160, + 215, -1, -1, 265, 214, 217, 266, 216, 215, -1, + 266, 267, -1, 267, -1, 268, -1, 270, -1, 269, + -1, 1, 215, -1, 89, 218, 118, 215, -1, 213, + 218, 226, 215, -1, 213, 218, 195, 215, -1, -1, + 151, 271, 218, 272, 215, -1, 272, 219, 273, -1, + 273, -1, 206, -1, 102, -1, 40, -1, 174, -1, + 64, -1, 62, -1, 173, -1, -1, 102, 275, 217, + 276, 216, 215, -1, 276, 277, -1, 277, -1, 278, + -1, 279, -1, 280, -1, 284, -1, 283, -1, 281, + -1, 282, -1, 288, -1, 1, 215, -1, 89, 218, + 118, 215, -1, 206, 218, 118, 215, -1, 112, 218, + 118, 215, -1, 32, 218, 160, 215, -1, 129, 218, + 118, 215, -1, 17, 218, 118, 215, -1, -1, 192, + 285, 218, 286, 215, -1, 286, 219, 287, -1, 287, + -1, 166, -1, 169, -1, 170, -1, 172, -1, 173, + -1, 176, -1, 51, -1, 189, -1, 182, -1, 185, + -1, 193, -1, 190, -1, 175, -1, 183, -1, 187, + -1, 177, -1, 199, -1, 167, -1, 168, -1, 180, + -1, -1, 36, 289, 218, 290, 215, -1, 290, 219, + 291, -1, 291, -1, 47, -1, 125, -1, 64, -1, + 205, -1, 174, -1, 194, -1, 211, -1, 40, -1, + 25, -1, 200, -1, 124, -1, 4, -1, 94, -1, + 183, -1, 198, -1, 106, -1, 126, -1, 188, -1, + 87, -1, -1, 17, 293, 217, 294, 216, 215, -1, + 294, 295, -1, 295, -1, 296, -1, 307, -1, 308, + -1, 297, -1, 298, -1, 309, -1, 299, -1, 300, + -1, 301, -1, 302, -1, 303, -1, 304, -1, 305, + -1, 306, -1, 1, 215, -1, 89, 218, 118, 215, + -1, 115, 218, 224, 215, -1, 116, 218, 224, 215, + -1, 101, 218, 99, 215, -1, 19, 218, 224, 215, + -1, 81, 218, 99, 215, -1, 76, 218, 99, 215, + -1, 78, 218, 99, 215, -1, 77, 218, 99, 215, + -1, 143, 218, 226, 215, -1, 184, 218, 226, 215, + -1, 15, 218, 99, 215, -1, 16, 218, 99, 215, + -1, 100, 218, 99, 215, -1, -1, 70, 311, 217, + 316, 216, 215, -1, -1, 36, 313, 218, 314, 215, + -1, 314, 219, 315, -1, 315, -1, 191, -1, 51, + -1, 186, -1, 316, 317, -1, 317, -1, 318, -1, + 312, -1, 322, -1, 323, -1, 1, 215, -1, -1, + 117, 218, 320, 319, 215, -1, 320, 219, 321, -1, + 321, -1, 99, -1, 99, 164, 99, -1, 61, 218, + 118, 215, -1, 56, 218, 118, 215, -1, -1, 48, + 325, 217, 326, 216, 215, -1, 326, 327, -1, 327, + -1, 328, -1, 329, -1, 330, -1, 332, -1, 336, + -1, 337, -1, 338, -1, 331, -1, 1, 215, -1, + 206, 218, 118, 215, -1, 112, 218, 118, 215, -1, + 17, 218, 118, 215, -1, 32, 218, 160, 215, -1, + -1, 36, 333, 218, 334, 215, -1, 334, 219, 335, + -1, 335, -1, 154, -1, 33, -1, 65, -1, 49, + -1, 13, -1, 98, -1, 43, -1, 137, -1, 90, + -1, 153, 218, 118, 215, -1, 122, 218, 118, 215, + -1, 121, 218, 99, 215, -1, -1, 136, 340, 217, + 341, 216, 215, -1, 341, 342, -1, 342, -1, 343, + -1, 344, -1, 345, -1, 1, 215, -1, 120, 218, + 118, 215, -1, 14, 218, 118, 215, -1, 93, 218, + 118, 215, -1, 201, 217, 347, 216, 215, -1, 347, + 348, -1, 348, -1, 349, -1, 1, -1, 89, 218, + 118, 215, -1, -1, 149, 351, 217, 352, 216, 215, + -1, 352, 353, -1, 353, -1, 354, -1, 355, -1, + 356, -1, 1, 215, -1, 89, 218, 118, 215, -1, + 206, 218, 118, 215, -1, -1, 151, 357, 218, 358, + 215, -1, 358, 219, 359, -1, 359, -1, 64, -1, + 205, -1, 174, -1, 194, -1, 211, -1, 197, -1, + 136, -1, 196, -1, 180, -1, 165, -1, -1, 150, + 361, 217, 362, 216, 215, -1, 362, 363, -1, 363, + -1, 364, -1, 365, -1, 1, 215, -1, 89, 218, + 118, 215, -1, -1, 151, 366, 218, 367, 215, -1, + 367, 219, 368, -1, 368, -1, 64, -1, 205, -1, + 174, -1, 194, -1, 211, -1, 197, -1, 136, -1, + 196, -1, 180, -1, 165, -1, -1, 18, 370, 217, + 371, 216, 215, -1, 371, 372, -1, 372, -1, 373, + -1, 374, -1, 375, -1, 376, -1, 377, -1, 379, + -1, 378, -1, 388, -1, 380, -1, 385, -1, 386, + -1, 387, -1, 384, -1, 1, 215, -1, 89, 218, + 118, 215, -1, 56, 218, 118, 215, -1, 209, 218, + 118, 215, -1, 144, 218, 118, 215, -1, 3, 218, + 118, 215, -1, 117, 218, 99, 215, -1, 5, 218, + 178, 215, -1, 5, 218, 179, 215, -1, -1, 36, + 381, 218, 382, 215, -1, 382, 219, 383, -1, 383, + -1, 8, -1, 191, -1, 32, 218, 160, 215, -1, + 58, 218, 118, 215, -1, 68, 218, 118, 215, -1, + 17, 218, 118, 215, -1, 171, 218, 118, 215, -1, + -1, 62, 390, 217, 395, 216, 215, -1, -1, 151, + 392, 218, 393, 215, -1, 393, 219, 394, -1, 394, + -1, 123, -1, 395, 396, -1, 396, -1, 397, -1, + 398, -1, 391, -1, 1, -1, 206, 218, 118, 215, + -1, 120, 218, 118, 215, -1, -1, 23, 400, 217, + 401, 216, 215, -1, 401, 402, -1, 402, -1, 403, + -1, 404, -1, 1, -1, 61, 218, 118, 215, -1, + 120, 218, 118, 215, -1, 34, 217, 406, 216, 215, + -1, 406, 407, -1, 407, -1, 408, -1, 1, -1, + 61, 218, 118, 215, -1, -1, 38, 410, 217, 415, + 216, 215, -1, -1, 151, 412, 218, 413, 215, -1, + 413, 219, 414, -1, 414, -1, 123, -1, 415, 416, + -1, 416, -1, 417, -1, 418, -1, 411, -1, 1, + -1, 89, 218, 118, 215, -1, 120, 218, 118, 215, + -1, 39, 217, 420, 216, 215, -1, 420, 421, -1, + 421, -1, 430, -1, 431, -1, 433, -1, 434, -1, + 435, -1, 436, -1, 437, -1, 438, -1, 439, -1, + 440, -1, 429, -1, 442, -1, 443, -1, 458, -1, + 445, -1, 447, -1, 449, -1, 448, -1, 452, -1, + 446, -1, 453, -1, 454, -1, 455, -1, 456, -1, + 457, -1, 470, -1, 459, -1, 460, -1, 461, -1, + 466, -1, 450, -1, 451, -1, 476, -1, 474, -1, + 475, -1, 432, -1, 465, -1, 441, -1, 463, -1, + 464, -1, 428, -1, 423, -1, 424, -1, 425, -1, + 426, -1, 427, -1, 444, -1, 422, -1, 462, -1, + 1, -1, 83, 218, 99, 215, -1, 42, 218, 160, + 215, -1, 41, 218, 224, 215, -1, 44, 218, 224, + 215, -1, 45, 218, 99, 215, -1, 46, 218, 99, + 215, -1, 148, 218, 160, 215, -1, 63, 218, 224, + 215, -1, 55, 218, 160, 215, -1, 59, 218, 160, + 215, -1, 28, 218, 160, 215, -1, 35, 218, 160, + 215, -1, 6, 218, 160, 215, -1, 80, 218, 224, + 215, -1, 79, 218, 99, 215, -1, 72, 218, 99, + 215, -1, 7, 218, 224, 215, -1, 163, 218, 224, + 215, -1, 162, 218, 224, 215, -1, 50, 218, 99, + 215, -1, 60, 218, 160, 215, -1, 212, 218, 160, + 215, -1, 155, 218, 160, 215, -1, 158, 218, 160, + 215, -1, 159, 218, 160, 215, -1, 157, 218, 160, + 215, -1, 157, 218, 161, 215, -1, 156, 218, 160, + 215, -1, 156, 218, 161, 215, -1, 110, 218, 224, + 215, -1, 12, 218, 224, 215, -1, 103, 218, 160, + 215, -1, 111, 218, 224, 215, -1, 152, 218, 160, + 215, -1, 97, 218, 160, 215, -1, 204, 218, 160, + 215, -1, 105, 218, 160, 215, -1, 84, 218, 118, + 215, -1, 29, 218, 99, 215, -1, 82, 218, 99, + 215, -1, 207, 218, 160, 215, -1, 30, 218, 118, + 215, -1, 202, 218, 118, 215, -1, 114, 218, 160, + 215, -1, 26, 218, 160, 215, -1, 203, 218, 224, + 215, -1, -1, 107, 467, 218, 468, 215, -1, 468, + 219, 469, -1, 469, -1, 166, -1, 169, -1, 170, + -1, 172, -1, 173, -1, 176, -1, 51, -1, 189, + -1, 182, -1, 185, -1, 193, -1, 190, -1, 175, + -1, 183, -1, 187, -1, 177, -1, 199, -1, 167, + -1, 168, -1, 180, -1, -1, 104, 471, 218, 472, + 215, -1, 472, 219, 473, -1, 473, -1, 166, -1, + 169, -1, 170, -1, 172, -1, 173, -1, 176, -1, + 189, -1, 51, -1, 182, -1, 185, -1, 193, -1, + 190, -1, 175, -1, 183, -1, 187, -1, 177, -1, + 199, -1, 167, -1, 168, -1, 180, -1, 85, 218, + 99, 215, -1, 86, 218, 99, 215, -1, 20, 218, + 99, 215, -1, 14, 217, 478, 216, 215, -1, 478, + 479, -1, 479, -1, 487, -1, 482, -1, 483, -1, + 484, -1, 485, -1, 486, -1, 488, -1, 489, -1, + 490, -1, 481, -1, 491, -1, 492, -1, 493, -1, + 480, -1, 1, -1, 27, 218, 160, 215, -1, 127, + 218, 160, 215, -1, 66, 218, 224, 215, -1, 67, + 218, 224, 215, -1, 75, 218, 99, 215, -1, 74, + 218, 99, 215, -1, 119, 218, 160, 215, -1, 73, + 218, 99, 215, -1, 22, 218, 99, 215, -1, 21, + 218, 99, 215, -1, 95, 218, 160, 215, -1, 96, + 218, 160, 215, -1, 108, 218, 99, 215, -1, 109, + 218, 224, 215, -1, 145, 217, 495, 216, 215, -1, + 495, 496, -1, 496, -1, 497, -1, 498, -1, 500, + -1, 501, -1, 499, -1, 502, -1, 1, -1, 37, + 218, 160, 215, -1, 54, 218, 160, 215, -1, 52, + 218, 118, 215, -1, 69, 218, 224, 215, -1, 51, + 218, 160, 215, -1, 53, 218, 160, 215, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 330, 330, 331, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, + 350, 351, 352, 353, 354, 355, 359, 359, 360, 364, + 368, 372, 376, 380, 386, 386, 387, 388, 389, 390, + 397, 400, 400, 401, 401, 401, 403, 409, 416, 418, + 418, 419, 419, 420, 420, 421, 421, 422, 422, 423, + 423, 424, 424, 425, 425, 426, 427, 430, 431, 433, + 433, 434, 440, 448, 448, 449, 455, 463, 502, 561, + 589, 597, 612, 627, 636, 650, 659, 687, 717, 740, + 749, 751, 751, 752, 752, 753, 753, 755, 764, 773, + 785, 786, 786, 788, 788, 789, 791, 798, 798, 808, + 809, 811, 811, 812, 812, 814, 819, 822, 828, 827, + 833, 833, 834, 838, 842, 846, 850, 854, 858, 869, + 868, 966, 966, 967, 967, 967, 968, 968, 968, 969, + 969, 969, 971, 980, 1017, 1029, 1040, 1082, 1092, 1091, + 1097, 1097, 1098, 1102, 1106, 1110, 1114, 1118, 1122, 1126, + 1130, 1134, 1138, 1142, 1146, 1150, 1154, 1158, 1162, 1166, + 1170, 1174, 1181, 1180, 1186, 1186, 1187, 1191, 1195, 1199, + 1203, 1207, 1211, 1215, 1219, 1223, 1227, 1231, 1235, 1239, + 1243, 1247, 1251, 1255, 1259, 1270, 1269, 1319, 1319, 1320, + 1321, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, + 1330, 1331, 1331, 1332, 1334, 1343, 1349, 1355, 1361, 1367, + 1373, 1379, 1385, 1391, 1397, 1404, 1410, 1416, 1426, 1425, + 1442, 1441, 1446, 1446, 1447, 1451, 1455, 1463, 1463, 1464, + 1464, 1464, 1464, 1464, 1466, 1466, 1468, 1468, 1470, 1484, + 1504, 1513, 1526, 1525, 1594, 1594, 1595, 1595, 1595, 1595, + 1596, 1596, 1596, 1597, 1597, 1599, 1634, 1647, 1656, 1668, + 1667, 1671, 1671, 1672, 1676, 1680, 1684, 1688, 1692, 1696, + 1700, 1704, 1710, 1729, 1739, 1753, 1752, 1768, 1768, 1769, + 1769, 1769, 1769, 1771, 1780, 1795, 1808, 1810, 1810, 1811, + 1811, 1813, 1829, 1828, 1844, 1844, 1845, 1845, 1845, 1845, + 1847, 1856, 1879, 1878, 1884, 1884, 1885, 1889, 1893, 1897, + 1901, 1905, 1909, 1913, 1917, 1921, 1931, 1930, 1947, 1947, + 1948, 1948, 1948, 1950, 1957, 1956, 1962, 1962, 1963, 1967, + 1971, 1975, 1979, 1983, 1987, 1991, 1995, 1999, 2009, 2008, + 2059, 2059, 2060, 2060, 2060, 2061, 2061, 2062, 2062, 2062, + 2063, 2063, 2063, 2064, 2064, 2065, 2067, 2076, 2085, 2111, + 2129, 2147, 2153, 2157, 2166, 2165, 2169, 2169, 2170, 2174, + 2180, 2191, 2202, 2213, 2222, 2241, 2240, 2306, 2305, 2309, + 2309, 2310, 2316, 2316, 2317, 2317, 2317, 2317, 2319, 2338, + 2348, 2347, 2372, 2372, 2373, 2373, 2373, 2375, 2381, 2390, + 2392, 2392, 2393, 2393, 2395, 2414, 2413, 2461, 2460, 2464, + 2464, 2465, 2471, 2471, 2472, 2472, 2472, 2472, 2474, 2480, + 2489, 2492, 2492, 2493, 2493, 2494, 2494, 2495, 2495, 2496, + 2496, 2497, 2497, 2498, 2499, 2500, 2500, 2501, 2501, 2502, + 2502, 2503, 2503, 2504, 2504, 2505, 2505, 2506, 2507, 2507, + 2508, 2508, 2509, 2509, 2510, 2510, 2511, 2511, 2512, 2513, + 2513, 2514, 2515, 2516, 2516, 2517, 2517, 2518, 2519, 2520, + 2521, 2521, 2522, 2525, 2530, 2536, 2542, 2548, 2553, 2558, + 2563, 2568, 2573, 2578, 2583, 2588, 2593, 2598, 2603, 2608, + 2613, 2618, 2624, 2635, 2640, 2645, 2650, 2655, 2660, 2663, + 2668, 2671, 2676, 2681, 2686, 2691, 2696, 2701, 2706, 2711, + 2716, 2727, 2732, 2737, 2742, 2751, 2760, 2765, 2770, 2776, + 2775, 2780, 2780, 2781, 2784, 2787, 2790, 2793, 2796, 2799, + 2802, 2805, 2808, 2811, 2814, 2817, 2820, 2823, 2826, 2829, + 2832, 2835, 2838, 2844, 2843, 2848, 2848, 2849, 2852, 2855, + 2858, 2861, 2864, 2867, 2870, 2873, 2876, 2879, 2882, 2885, + 2888, 2891, 2894, 2897, 2900, 2903, 2906, 2911, 2916, 2921, + 2930, 2933, 2933, 2934, 2935, 2935, 2936, 2936, 2937, 2937, + 2938, 2939, 2939, 2940, 2941, 2941, 2942, 2942, 2944, 2949, + 2954, 2959, 2964, 2969, 2974, 2979, 2984, 2989, 2994, 2999, + 3004, 3009, 3017, 3020, 3020, 3021, 3021, 3022, 3023, 3023, + 3024, 3025, 3027, 3033, 3039, 3048, 3062, 3068 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "ACCEPT_PASSWORD", "ADMIN", "AFTYPE", + "ANTI_NICK_FLOOD", "ANTI_SPAM_EXIT_MESSAGE_TIME", "AUTOCONN", "BYTES", + "KBYTES", "MBYTES", "CALLER_ID_WAIT", "CAN_FLOOD", "CHANNEL", + "CIDR_BITLEN_IPV4", "CIDR_BITLEN_IPV6", "CLASS", "CONNECT", + "CONNECTFREQ", "DEFAULT_FLOODCOUNT", "DEFAULT_SPLIT_SERVER_COUNT", + "DEFAULT_SPLIT_USER_COUNT", "DENY", "DESCRIPTION", "DIE", "DISABLE_AUTH", + "DISABLE_FAKE_CHANNELS", "DISABLE_REMOTE_COMMANDS", "DOTS_IN_IDENT", + "EGDPOOL_PATH", "EMAIL", "ENCRYPTED", "EXCEED_LIMIT", "EXEMPT", + "FAILED_OPER_NOTICE", "IRCD_FLAGS", "FLATTEN_LINKS", "GECOS", "GENERAL", + "GLINE", "GLINE_DURATION", "GLINE_ENABLE", "GLINE_EXEMPT", + "GLINE_REQUEST_DURATION", "GLINE_MIN_CIDR", "GLINE_MIN_CIDR6", + "GLOBAL_KILL", "IRCD_AUTH", "NEED_IDENT", "HAVENT_READ_CONF", "HIDDEN", + "HIDDEN_NAME", "HIDE_SERVER_IPS", "HIDE_SERVERS", "HIDE_SPOOF_IPS", + "HOST", "HUB", "HUB_MASK", "IGNORE_BOGUS_TS", "INVISIBLE_ON_CONNECT", + "IP", "KILL", "KILL_CHASE_TIME_LIMIT", "KLINE", "KLINE_EXEMPT", + "KNOCK_DELAY", "KNOCK_DELAY_CHANNEL", "LEAF_MASK", "LINKS_DELAY", + "LISTEN", "T_LOG", "MAX_ACCEPT", "MAX_BANS", "MAX_CHANS_PER_OPER", + "MAX_CHANS_PER_USER", "MAX_GLOBAL", "MAX_IDENT", "MAX_LOCAL", + "MAX_NICK_CHANGES", "MAX_NICK_TIME", "MAX_NUMBER", "MAX_TARGETS", + "MAX_WATCH", "MESSAGE_LOCALE", "MIN_NONWILDCARD", + "MIN_NONWILDCARD_SIMPLE", "MODULE", "MODULES", "NAME", "NEED_PASSWORD", + "NETWORK_DESC", "NETWORK_NAME", "NICK", "NICK_CHANGES", + "NO_CREATE_ON_SPLIT", "NO_JOIN_ON_SPLIT", "NO_OPER_FLOOD", "NO_TILDE", + "NUMBER", "NUMBER_PER_CIDR", "NUMBER_PER_IP", "OPERATOR", + "OPERS_BYPASS_CALLERID", "OPER_ONLY_UMODES", "OPER_PASS_RESV", + "OPER_SPY_T", "OPER_UMODES", "JOIN_FLOOD_COUNT", "JOIN_FLOOD_TIME", + "PACE_WAIT", "PACE_WAIT_SIMPLE", "PASSWORD", "PATH", "PING_COOKIE", + "PING_TIME", "PING_WARNING", "PORT", "QSTRING", "QUIET_ON_BAN", "REASON", + "REDIRPORT", "REDIRSERV", "REGEX_T", "REHASH", "REMOTE", "REMOTEBAN", + "RESTRICT_CHANNELS", "RSA_PRIVATE_KEY_FILE", "RSA_PUBLIC_KEY_FILE", + "SSL_CERTIFICATE_FILE", "SSL_DH_PARAM_FILE", "T_SSL_CLIENT_METHOD", + "T_SSL_SERVER_METHOD", "T_SSLV3", "T_TLSV1", "RESV", "RESV_EXEMPT", + "SECONDS", "MINUTES", "HOURS", "DAYS", "WEEKS", "SENDQ", "SEND_PASSWORD", + "SERVERHIDE", "SERVERINFO", "IRCD_SID", "TKLINE_EXPIRE_NOTICES", + "T_SHARED", "T_CLUSTER", "TYPE", "SHORT_MOTD", "SPOOF", "SPOOF_NOTICE", + "STATS_E_DISABLED", "STATS_I_OPER_ONLY", "STATS_K_OPER_ONLY", + "STATS_O_OPER_ONLY", "STATS_P_OPER_ONLY", "TBOOL", "TMASKED", + "TS_MAX_DELTA", "TS_WARN_DELTA", "TWODOTS", "T_ALL", "T_BOTS", + "T_SOFTCALLERID", "T_CALLERID", "T_CCONN", "T_CCONN_FULL", + "T_SSL_CIPHER_LIST", "T_DEAF", "T_DEBUG", "T_DLINE", "T_EXTERNAL", + "T_FULL", "T_INVISIBLE", "T_IPV4", "T_IPV6", "T_LOCOPS", "T_MAX_CLIENTS", + "T_NCHANGE", "T_OPERWALL", "T_RECVQ", "T_REJ", "T_SERVER", + "T_SERVNOTICE", "T_SET", "T_SKILL", "T_SPY", "T_SSL", "T_UMODES", + "T_UNAUTH", "T_UNDLINE", "T_UNLIMITED", "T_UNRESV", "T_UNXLINE", + "T_GLOBOPS", "T_WALLOP", "T_RESTART", "T_SERVICE", "T_SERVICES_NAME", + "THROTTLE_TIME", "TRUE_NO_OPER_FLOOD", "UNKLINE", "USER", "USE_EGD", + "USE_LOGGING", "VHOST", "VHOST6", "XLINE", "WARN_NO_NLINE", "T_SIZE", + "T_FILE", "';'", "'}'", "'{'", "'='", "','", "$accept", "conf", + "conf_item", "timespec_", "timespec", "sizespec_", "sizespec", + "modules_entry", "modules_items", "modules_item", "modules_module", + "modules_path", "serverinfo_entry", "serverinfo_items", + "serverinfo_item", "serverinfo_ssl_client_method", + "serverinfo_ssl_server_method", "client_method_types", + "client_method_type_item", "server_method_types", + "server_method_type_item", "serverinfo_ssl_certificate_file", + "serverinfo_rsa_private_key_file", "serverinfo_ssl_dh_param_file", + "serverinfo_ssl_cipher_list", "serverinfo_name", "serverinfo_sid", + "serverinfo_description", "serverinfo_network_name", + "serverinfo_network_desc", "serverinfo_vhost", "serverinfo_vhost6", + "serverinfo_max_clients", "serverinfo_hub", "admin_entry", "admin_items", + "admin_item", "admin_name", "admin_email", "admin_description", + "logging_entry", "logging_items", "logging_item", "logging_use_logging", + "logging_file_entry", "$@1", "logging_file_items", "logging_file_item", + "logging_file_name", "logging_file_size", "logging_file_type", "$@2", + "logging_file_type_items", "logging_file_type_item", "oper_entry", "$@3", + "oper_items", "oper_item", "oper_name", "oper_user", "oper_password", + "oper_encrypted", "oper_rsa_public_key_file", "oper_class", + "oper_umodes", "$@4", "oper_umodes_items", "oper_umodes_item", + "oper_flags", "$@5", "oper_flags_items", "oper_flags_item", + "class_entry", "$@6", "class_items", "class_item", "class_name", + "class_ping_time", "class_ping_warning", "class_number_per_ip", + "class_connectfreq", "class_max_number", "class_max_global", + "class_max_local", "class_max_ident", "class_sendq", "class_recvq", + "class_cidr_bitlen_ipv4", "class_cidr_bitlen_ipv6", + "class_number_per_cidr", "listen_entry", "$@7", "listen_flags", "$@8", + "listen_flags_items", "listen_flags_item", "listen_items", "listen_item", + "listen_port", "$@9", "port_items", "port_item", "listen_address", + "listen_host", "auth_entry", "$@10", "auth_items", "auth_item", + "auth_user", "auth_passwd", "auth_class", "auth_encrypted", "auth_flags", + "$@11", "auth_flags_items", "auth_flags_item", "auth_spoof", + "auth_redir_serv", "auth_redir_port", "resv_entry", "$@12", "resv_items", + "resv_item", "resv_creason", "resv_channel", "resv_nick", + "service_entry", "service_items", "service_item", "service_name", + "shared_entry", "$@13", "shared_items", "shared_item", "shared_name", + "shared_user", "shared_type", "$@14", "shared_types", "shared_type_item", + "cluster_entry", "$@15", "cluster_items", "cluster_item", "cluster_name", + "cluster_type", "$@16", "cluster_types", "cluster_type_item", + "connect_entry", "$@17", "connect_items", "connect_item", "connect_name", + "connect_host", "connect_vhost", "connect_send_password", + "connect_accept_password", "connect_port", "connect_aftype", + "connect_flags", "$@18", "connect_flags_items", "connect_flags_item", + "connect_encrypted", "connect_hub_mask", "connect_leaf_mask", + "connect_class", "connect_ssl_cipher_list", "kill_entry", "$@19", + "kill_type", "$@20", "kill_type_items", "kill_type_item", "kill_items", + "kill_item", "kill_user", "kill_reason", "deny_entry", "$@21", + "deny_items", "deny_item", "deny_ip", "deny_reason", "exempt_entry", + "exempt_items", "exempt_item", "exempt_ip", "gecos_entry", "$@22", + "gecos_flags", "$@23", "gecos_flags_items", "gecos_flags_item", + "gecos_items", "gecos_item", "gecos_name", "gecos_reason", + "general_entry", "general_items", "general_item", "general_max_watch", + "general_gline_enable", "general_gline_duration", + "general_gline_request_duration", "general_gline_min_cidr", + "general_gline_min_cidr6", "general_tkline_expire_notices", + "general_kill_chase_time_limit", "general_hide_spoof_ips", + "general_ignore_bogus_ts", "general_disable_remote_commands", + "general_failed_oper_notice", "general_anti_nick_flood", + "general_max_nick_time", "general_max_nick_changes", + "general_max_accept", "general_anti_spam_exit_message_time", + "general_ts_warn_delta", "general_ts_max_delta", + "general_havent_read_conf", "general_invisible_on_connect", + "general_warn_no_nline", "general_stats_e_disabled", + "general_stats_o_oper_only", "general_stats_P_oper_only", + "general_stats_k_oper_only", "general_stats_i_oper_only", + "general_pace_wait", "general_caller_id_wait", + "general_opers_bypass_callerid", "general_pace_wait_simple", + "general_short_motd", "general_no_oper_flood", + "general_true_no_oper_flood", "general_oper_pass_resv", + "general_message_locale", "general_dots_in_ident", "general_max_targets", + "general_use_egd", "general_egdpool_path", "general_services_name", + "general_ping_cookie", "general_disable_auth", "general_throttle_time", + "general_oper_umodes", "$@24", "umode_oitems", "umode_oitem", + "general_oper_only_umodes", "$@25", "umode_items", "umode_item", + "general_min_nonwildcard", "general_min_nonwildcard_simple", + "general_default_floodcount", "channel_entry", "channel_items", + "channel_item", "channel_disable_fake_channels", + "channel_restrict_channels", "channel_knock_delay", + "channel_knock_delay_channel", "channel_max_chans_per_user", + "channel_max_chans_per_oper", "channel_quiet_on_ban", "channel_max_bans", + "channel_default_split_user_count", "channel_default_split_server_count", + "channel_no_create_on_split", "channel_no_join_on_split", + "channel_jflood_count", "channel_jflood_time", "serverhide_entry", + "serverhide_items", "serverhide_item", "serverhide_flatten_links", + "serverhide_hide_servers", "serverhide_hidden_name", + "serverhide_links_delay", "serverhide_hidden", + "serverhide_hide_server_ips", YY_NULL +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, + 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 59, 125, 123, 61, 44 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint16 yyr1[] = +{ + 0, 220, 221, 221, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 223, 223, 224, 224, + 224, 224, 224, 224, 225, 225, 226, 226, 226, 226, + 227, 228, 228, 229, 229, 229, 230, 231, 232, 233, + 233, 234, 234, 234, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 234, 234, 234, 235, 236, 237, + 237, 238, 238, 239, 239, 240, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 255, 256, 256, 256, 256, 257, 258, 259, + 260, 261, 261, 262, 262, 262, 263, 265, 264, 266, + 266, 267, 267, 267, 267, 268, 269, 269, 271, 270, + 272, 272, 273, 273, 273, 273, 273, 273, 273, 275, + 274, 276, 276, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 278, 279, 280, 281, 282, 283, 285, 284, + 286, 286, 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 289, 288, 290, 290, 291, 291, 291, 291, + 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, + 291, 291, 291, 291, 291, 293, 292, 294, 294, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, 311, 310, + 313, 312, 314, 314, 315, 315, 315, 316, 316, 317, + 317, 317, 317, 317, 319, 318, 320, 320, 321, 321, + 322, 323, 325, 324, 326, 326, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 328, 329, 330, 331, 333, + 332, 334, 334, 335, 335, 335, 335, 335, 335, 335, + 335, 335, 336, 337, 338, 340, 339, 341, 341, 342, + 342, 342, 342, 343, 344, 345, 346, 347, 347, 348, + 348, 349, 351, 350, 352, 352, 353, 353, 353, 353, + 354, 355, 357, 356, 358, 358, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 361, 360, 362, 362, + 363, 363, 363, 364, 366, 365, 367, 367, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 370, 369, + 371, 371, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 372, 372, 372, 372, 373, 374, 375, 376, + 377, 378, 379, 379, 381, 380, 382, 382, 383, 383, + 384, 385, 386, 387, 388, 390, 389, 392, 391, 393, + 393, 394, 395, 395, 396, 396, 396, 396, 397, 398, + 400, 399, 401, 401, 402, 402, 402, 403, 404, 405, + 406, 406, 407, 407, 408, 410, 409, 412, 411, 413, + 413, 414, 415, 415, 416, 416, 416, 416, 417, 418, + 419, 420, 420, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 422, 423, 424, 425, 426, 427, 428, + 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, + 439, 440, 441, 442, 443, 444, 445, 446, 447, 447, + 448, 448, 449, 450, 451, 452, 453, 454, 455, 456, + 457, 458, 459, 460, 461, 462, 463, 464, 465, 467, + 466, 468, 468, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 471, 470, 472, 472, 473, 473, 473, + 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, + 473, 473, 473, 473, 473, 473, 473, 474, 475, 476, + 477, 478, 478, 479, 479, 479, 479, 479, 479, 479, + 479, 479, 479, 479, 479, 479, 479, 479, 480, 481, + 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, + 492, 493, 494, 495, 495, 496, 496, 496, 496, 496, + 496, 496, 497, 498, 499, 500, 501, 502 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 0, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 0, 1, 2, 3, + 3, 3, 3, 3, 0, 1, 2, 3, 3, 3, + 5, 2, 1, 1, 1, 2, 4, 4, 5, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 4, 4, 3, + 1, 1, 1, 3, 1, 1, 1, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 2, 1, 1, 1, 1, 2, 4, 4, 4, + 5, 2, 1, 1, 1, 2, 4, 0, 6, 2, + 1, 1, 1, 1, 2, 4, 4, 4, 0, 5, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 6, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 4, 4, 4, 4, 4, 0, 5, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 5, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 6, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 6, + 0, 5, 3, 1, 1, 1, 1, 2, 1, 1, + 1, 1, 1, 2, 0, 5, 3, 1, 1, 3, + 4, 4, 0, 6, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 4, 4, 4, 4, 0, + 5, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 4, 4, 4, 0, 6, 2, 1, 1, + 1, 1, 2, 4, 4, 4, 5, 2, 1, 1, + 1, 4, 0, 6, 2, 1, 1, 1, 1, 2, + 4, 4, 0, 5, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 6, 2, 1, + 1, 1, 2, 4, 0, 5, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 6, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 5, 3, 1, 1, 1, + 4, 4, 4, 4, 4, 0, 6, 0, 5, 3, + 1, 1, 2, 1, 1, 1, 1, 1, 4, 4, + 0, 6, 2, 1, 1, 1, 1, 4, 4, 5, + 2, 1, 1, 1, 4, 0, 6, 0, 5, 3, + 1, 1, 2, 1, 1, 1, 1, 1, 4, 4, + 5, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, + 5, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 5, 3, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, + 5, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 5, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 4, 4, 4, 4, 4, 4 +}; + +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint16 yydefact[] = +{ + 2, 0, 1, 0, 0, 0, 195, 348, 400, 0, + 415, 0, 252, 385, 228, 0, 0, 129, 285, 0, + 0, 302, 326, 0, 3, 23, 11, 4, 5, 6, + 8, 9, 10, 13, 14, 15, 16, 17, 18, 19, + 20, 22, 21, 7, 12, 24, 25, 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, 92, 93, 95, 94, 597, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 582, 596, 592, 584, 585, 586, 587, 588, + 583, 589, 590, 591, 593, 594, 595, 0, 0, 0, + 413, 0, 0, 411, 412, 0, 482, 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, 553, 0, 529, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 432, 480, 474, + 475, 476, 477, 478, 473, 443, 433, 434, 468, 435, + 436, 437, 438, 439, 440, 441, 442, 470, 444, 445, + 479, 447, 452, 448, 450, 449, 463, 464, 451, 453, + 454, 455, 456, 457, 446, 459, 460, 461, 481, 471, + 472, 469, 462, 458, 466, 467, 465, 0, 0, 0, + 0, 0, 0, 102, 103, 104, 0, 0, 0, 0, + 0, 42, 43, 44, 0, 0, 621, 0, 0, 0, + 0, 0, 0, 0, 614, 615, 616, 619, 617, 618, + 620, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 50, 63, + 64, 62, 59, 58, 65, 51, 61, 54, 55, 56, + 52, 60, 57, 53, 0, 0, 300, 0, 0, 298, + 299, 96, 0, 0, 0, 0, 91, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 581, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 199, 202, 203, 205, 206, 207, 208, 209, 210, 211, + 212, 200, 201, 204, 0, 0, 0, 0, 0, 374, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, + 352, 353, 354, 355, 356, 358, 357, 360, 364, 361, + 362, 363, 359, 406, 0, 0, 0, 403, 404, 405, + 0, 0, 410, 427, 0, 0, 417, 426, 0, 423, + 424, 425, 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, 431, 0, 0, 0, 269, 0, 0, 0, + 0, 0, 0, 255, 256, 257, 258, 263, 259, 260, + 261, 262, 397, 0, 387, 0, 396, 0, 393, 394, + 395, 0, 230, 0, 0, 0, 240, 0, 238, 239, + 241, 242, 105, 0, 0, 101, 0, 45, 0, 0, + 0, 41, 0, 0, 0, 172, 0, 0, 0, 148, + 0, 0, 132, 133, 134, 135, 138, 139, 137, 136, + 140, 0, 0, 0, 0, 0, 288, 289, 290, 291, + 0, 0, 0, 0, 0, 0, 0, 613, 66, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 49, 0, 0, 312, 0, + 0, 305, 306, 307, 308, 0, 0, 334, 0, 329, + 330, 331, 0, 0, 297, 0, 0, 0, 90, 0, + 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 580, 213, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 197, 365, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 350, 0, 0, + 0, 402, 0, 409, 0, 0, 0, 0, 422, 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, + 430, 264, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 254, 0, 0, 0, 0, 392, 243, 0, 0, + 0, 0, 0, 237, 0, 100, 0, 0, 0, 40, + 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 131, 292, 0, 0, 0, 0, 287, 0, 0, 0, + 0, 0, 0, 612, 0, 0, 0, 0, 0, 0, + 0, 0, 71, 72, 0, 70, 75, 76, 0, 74, + 0, 0, 0, 0, 0, 48, 309, 0, 0, 0, + 0, 304, 332, 0, 0, 0, 328, 0, 296, 99, + 98, 97, 607, 606, 598, 26, 26, 26, 26, 26, + 28, 27, 600, 601, 605, 603, 602, 608, 609, 610, + 611, 604, 599, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 34, 0, 0, 196, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 349, 0, 0, 401, 414, 0, 0, + 0, 416, 495, 499, 513, 579, 527, 493, 521, 524, + 494, 485, 484, 486, 487, 488, 502, 491, 492, 503, + 490, 498, 497, 496, 522, 483, 520, 577, 578, 517, + 514, 564, 557, 574, 575, 558, 559, 560, 561, 569, + 562, 572, 576, 565, 570, 566, 571, 563, 568, 567, + 573, 0, 556, 519, 539, 533, 550, 551, 534, 535, + 536, 537, 545, 538, 548, 552, 541, 546, 542, 547, + 540, 544, 543, 549, 0, 532, 512, 515, 526, 489, + 516, 505, 510, 511, 508, 509, 506, 507, 501, 500, + 525, 528, 518, 523, 504, 0, 0, 0, 0, 0, + 0, 0, 0, 253, 0, 0, 0, 386, 0, 0, + 0, 248, 244, 247, 229, 106, 0, 0, 118, 0, + 0, 110, 111, 113, 112, 46, 47, 0, 0, 0, + 0, 0, 0, 0, 0, 130, 0, 0, 0, 286, + 622, 626, 624, 627, 623, 625, 83, 89, 81, 85, + 84, 78, 77, 79, 67, 0, 68, 0, 82, 80, + 88, 86, 87, 0, 0, 0, 303, 0, 0, 327, + 301, 29, 30, 31, 32, 33, 225, 226, 218, 220, + 222, 221, 219, 214, 227, 217, 215, 216, 34, 34, + 34, 36, 35, 223, 224, 370, 372, 373, 383, 380, + 378, 379, 0, 377, 367, 381, 382, 366, 371, 369, + 384, 368, 407, 408, 428, 429, 421, 0, 420, 554, + 0, 530, 0, 267, 268, 277, 274, 279, 276, 275, + 281, 278, 280, 273, 0, 272, 266, 284, 283, 282, + 265, 399, 391, 0, 390, 398, 235, 236, 234, 0, + 233, 251, 250, 0, 0, 0, 114, 0, 0, 0, + 0, 109, 147, 145, 187, 184, 183, 176, 178, 194, + 188, 191, 186, 177, 192, 180, 189, 193, 181, 190, + 185, 179, 182, 0, 175, 142, 144, 146, 158, 152, + 169, 170, 153, 154, 155, 156, 164, 157, 167, 171, + 160, 165, 161, 166, 159, 163, 162, 168, 0, 151, + 143, 294, 295, 293, 69, 73, 310, 316, 322, 325, + 318, 324, 319, 323, 321, 317, 320, 0, 315, 311, + 333, 338, 344, 347, 340, 346, 341, 345, 343, 339, + 342, 0, 337, 37, 38, 39, 375, 0, 418, 0, + 555, 531, 270, 0, 388, 0, 231, 0, 249, 246, + 245, 0, 0, 0, 0, 108, 173, 0, 149, 0, + 313, 0, 335, 0, 376, 419, 271, 389, 232, 115, + 124, 127, 126, 123, 128, 125, 122, 0, 121, 117, + 116, 174, 150, 314, 336, 119, 0, 120 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 1, 24, 780, 781, 1021, 1022, 25, 230, 231, + 232, 233, 26, 267, 268, 269, 270, 744, 745, 748, + 749, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 27, 71, 72, 73, 74, 75, + 28, 222, 223, 224, 225, 226, 950, 951, 952, 953, + 954, 1088, 1217, 1218, 29, 60, 501, 502, 503, 504, + 505, 506, 507, 508, 509, 717, 1138, 1139, 510, 713, + 1113, 1114, 30, 49, 328, 329, 330, 331, 332, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 31, 57, 476, 698, 1079, 1080, 477, 478, 479, 1085, + 942, 943, 480, 481, 32, 55, 452, 453, 454, 455, + 456, 457, 458, 684, 1064, 1065, 459, 460, 461, 33, + 61, 515, 516, 517, 518, 519, 34, 288, 289, 290, + 35, 64, 550, 551, 552, 553, 554, 758, 1157, 1158, + 36, 65, 558, 559, 560, 561, 764, 1171, 1172, 37, + 50, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 607, 1032, 1033, 368, 369, 370, 371, 372, 38, + 56, 466, 693, 1073, 1074, 467, 468, 469, 470, 39, + 51, 376, 377, 378, 379, 40, 112, 113, 114, 41, + 53, 387, 626, 1047, 1048, 388, 389, 390, 391, 42, + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 423, 904, 905, + 213, 421, 881, 882, 214, 215, 216, 43, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 44, 243, 244, 245, 246, 247, + 248, 249, 250 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -744 +static const yytype_int16 yypact[] = +{ + -744, 610, -744, -209, -187, -179, -744, -744, -744, -176, + -744, -171, -744, -744, -744, -166, -164, -744, -744, -139, + -136, -744, -744, -131, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, 61, 807, -126, + -104, -84, 16, -79, 382, -77, -63, -60, 7, 21, + -49, -40, 638, 381, -26, 52, 25, -152, 62, 85, + 86, 18, -744, -744, -744, -744, -744, 88, 89, 93, + 94, 96, 101, 108, 112, 118, 119, 125, 127, 132, + 133, 162, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, 531, 499, 266, + -744, 135, 28, -744, -744, 11, -744, 142, 143, 145, + 147, 148, 150, 153, 163, 166, 167, 169, 173, 174, + 175, 177, 178, 180, 182, 183, 185, 191, 197, 200, + 201, 202, 204, 211, 212, 215, -744, 216, -744, 217, + 218, 221, 222, 225, 226, 229, 234, 235, 237, 238, + 239, 242, 253, 256, 257, 262, 38, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, 337, 24, 259, + 73, 263, 4, -744, -744, -744, 126, 131, 264, 270, + 59, -744, -744, -744, 389, 209, -744, 276, 279, 280, + 281, 285, 287, 3, -744, -744, -744, -744, -744, -744, + -744, 149, 288, 289, 290, 292, 299, 301, 302, 303, + 304, 305, 307, 308, 315, 324, 330, 75, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, 208, 30, -744, 331, 15, -744, + -744, -744, 107, 254, 359, 165, -744, 385, 396, 367, + 454, 454, 455, 457, 461, 399, 401, 464, 454, 404, + 405, 351, -744, 358, 356, 360, 361, 362, 364, 365, + 369, 374, 375, 379, 383, 386, 388, 395, 232, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, 384, 397, 400, 403, 408, -744, + 411, 412, 420, 423, 424, 427, 433, 434, 260, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, 435, 437, 8, -744, -744, -744, + 458, 407, -744, -744, 441, 442, -744, -744, 36, -744, + -744, -744, 417, 454, 454, 501, 443, 459, 524, 543, + 502, 454, 503, 454, 565, 567, 568, 508, 509, 513, + 454, 577, 578, 454, 580, 583, 566, 584, 587, 527, + 528, 475, 535, 478, 454, 454, 537, 540, 541, 542, + -146, -133, 544, 546, 454, 454, 585, 454, 550, 553, + 554, 510, -744, 515, 514, 517, -744, 519, 521, 525, + 529, 530, 58, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, 533, -744, 534, -744, 10, -744, -744, + -744, 538, -744, 536, 539, 545, -744, 115, -744, -744, + -744, -744, -744, 582, 547, -744, 532, -744, 640, 643, + 549, -744, 555, 559, 560, -744, 562, 569, 572, -744, + 573, 70, -744, -744, -744, -744, -744, -744, -744, -744, + -744, 558, 588, 595, 597, 146, -744, -744, -744, -744, + 623, 625, 687, 658, 659, 454, 606, -744, -744, 704, + 663, 706, 707, 709, 713, 714, 715, 79, 159, 717, + 718, 646, 719, 720, 626, -744, 628, 622, -744, 624, + 128, -744, -744, -744, -744, 629, 630, -744, 22, -744, + -744, -744, 728, 632, -744, 634, 635, 636, -744, 637, + 639, 641, 430, 642, 645, 648, 649, 650, 651, 652, + 653, 654, 656, 657, -744, -744, 754, 756, 454, 759, + 776, 778, 779, 761, 784, 785, 454, 454, 786, 786, + 671, -744, -744, 769, 122, 770, 729, 672, 773, 774, + 775, 777, 795, 780, 781, 782, 681, -744, 783, 787, + 682, -744, 689, -744, 788, 789, 690, 694, -744, 695, + 696, 697, 698, 699, 702, 703, 705, 708, 710, 712, + 716, 721, 722, 723, 724, 725, 726, 727, 730, 731, + 732, 733, 734, 735, 736, 737, 738, 739, 551, 740, + 599, 741, 742, 743, 744, 745, 746, 747, 748, 749, + 750, 751, 752, 753, 755, 757, 758, 760, 762, 763, + -744, -744, 801, 764, 711, 803, 823, 810, 812, 814, + 765, -744, 815, 766, 817, 767, -744, -744, 768, 825, + 826, 870, 772, -744, 790, -744, 184, 791, 792, -744, + -744, 853, 816, 771, 856, 861, 863, 793, 865, 794, + -744, -744, 867, 872, 873, 797, -744, 798, 799, 800, + 802, 804, 805, -744, 806, 808, 809, 811, 813, 818, + 819, 820, -744, -744, -195, -744, -744, -744, -172, -744, + 821, 822, 824, 827, 828, -744, -744, 874, 829, 875, + 830, -744, -744, 876, 831, 833, -744, 835, -744, -744, + -744, -744, -744, -744, -744, 454, 454, 454, 454, 454, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, 836, 837, 838, 839, 840, 841, 842, + 843, 844, 845, 846, 847, 314, 848, 849, -744, 850, + 851, 852, 854, 855, 13, 857, 858, 859, 860, 862, + 864, 866, 868, -744, 869, 871, -744, -744, 877, 878, + 879, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -167, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -154, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, 880, 881, 309, 882, 883, + 884, 885, 886, -744, 887, 893, 888, -744, -33, 889, + 890, 832, 891, -744, -744, -744, 892, 894, -744, 895, + 154, -744, -744, -744, -744, -744, -744, 896, 899, 511, + 900, 901, 902, 627, 903, -744, 904, 905, 906, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, 79, -744, 159, -744, -744, + -744, -744, -744, 907, 460, 908, -744, 909, 665, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, 786, 786, + 786, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -145, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -50, -744, -744, + 551, -744, 599, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -41, -744, -744, -744, -744, -744, + -744, -744, -744, -27, -744, -744, -744, -744, -744, -17, + -744, -744, -744, 898, 870, 910, -744, 911, 912, -86, + 913, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, 34, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, 40, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, 53, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, 63, -744, -744, -744, -744, -744, 13, -744, 879, + -744, -744, -744, 309, -744, 893, -744, -33, -744, -744, + -744, 914, 277, 916, 917, -744, -744, 511, -744, 627, + -744, 460, -744, 665, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, 68, -744, -744, + -744, -744, -744, -744, -744, -744, 277, -744 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -744, -744, -744, -743, -298, -663, -598, -744, -744, 897, + -744, -744, -744, -744, 915, -744, -744, -744, 14, -744, + 1, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, 924, -744, -744, -744, + -744, -744, 796, -744, -744, -744, -744, 48, -744, -744, + -744, -744, -744, -226, -744, -744, -744, 500, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -196, -744, -744, + -744, -193, -744, -744, -744, 680, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -177, -744, 548, -744, -744, + -744, -62, -744, -744, -744, -744, -744, 575, -744, -744, + -744, -744, -744, -744, -744, -153, -744, -744, -744, -744, + -744, -744, 516, -744, -744, -744, -744, -744, 918, -744, + -744, -744, -744, 482, -744, -744, -744, -744, -744, -163, + -744, -744, -744, 483, -744, -744, -744, -744, -159, -744, + -744, -744, 688, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -137, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -117, -744, 604, -744, -744, -744, + -744, -744, 700, -744, -744, -744, -744, 966, -744, -744, + -744, -744, -744, -744, -99, -744, 701, -744, -744, -744, + -744, 919, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, -744, -744, -744, 35, + -744, -744, -744, 32, -744, -744, -744, -744, -744, 997, + -744, -744, -744, -744, -744, -744, -744, -744, -744, -744, + -744, -744, -744, -744, -744, -744, 920, -744, -744, -744, + -744, -744, -744 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -108 +static const yytype_int16 yytable[] = +{ + 806, 807, 573, 574, 236, 220, 45, 46, 220, 373, + 581, 462, 383, 805, 667, 668, 286, 110, 1076, 67, + 984, 1030, 227, 555, 985, 462, 286, 669, 670, 110, + 47, 555, 1001, 1002, 1003, 1004, 1005, 383, 48, 116, + 237, 52, 68, 986, 117, 118, 54, 987, 1049, 69, + 119, 58, 1050, 59, 238, 239, 240, 241, 120, 443, + 227, 1051, 67, 291, 121, 1052, 122, 123, 124, 374, + 1176, 492, 242, 125, 1177, 444, 251, 111, 62, 126, + 127, 63, 128, 129, 130, 68, 66, 493, 131, 111, + 445, 107, 69, 132, 446, 630, 631, 133, 134, 252, + 384, 135, 494, 638, 287, 640, 495, 70, 228, 1193, + 136, 556, 647, 108, 287, 650, 471, 137, 138, 556, + 139, 140, 141, 142, 143, 384, 661, 662, 375, 546, + 463, 385, 253, 109, 229, 144, 673, 674, 115, 676, + 217, 145, 146, 147, 463, 148, 228, 511, 149, 150, + 70, 472, 151, 1077, 218, 946, 385, 219, 1078, 496, + 512, 464, 386, 76, 254, 1178, 255, 256, 234, 1179, + 447, 473, 229, 557, 1182, 464, 474, 235, 1183, 448, + 449, 557, 497, 77, 78, 946, 152, 386, 1184, 79, + 153, 284, 1185, 154, 155, 156, 157, 158, 1186, 498, + 159, 160, 1187, 257, 1031, 258, 259, 260, 261, 546, + 511, 450, 221, 742, 743, 221, 465, 547, -107, 526, + 484, -107, 262, 512, 620, 565, 695, 732, 80, 81, + 465, 563, 475, 313, 295, 82, 83, 84, 765, 513, + 161, 162, 163, 947, 381, 164, 263, 314, 315, 1196, + 165, 316, 627, 1197, 441, 1198, 264, 85, 86, 1199, + 471, 344, 499, 345, 451, 346, 514, 373, 1200, 285, + 87, 88, 1201, 947, 690, 490, 500, 347, 1202, 548, + 292, 89, 1203, 1225, 265, 266, 719, 1226, 482, 90, + 795, 544, 348, 746, 747, 472, 349, 547, 803, 804, + 810, 811, 513, 293, 294, 948, 297, 298, 317, 318, + 319, 299, 300, 320, 301, 473, 350, 1210, 351, 302, + 474, 321, 1055, 1018, 1019, 1020, 303, 374, 352, 514, + 304, 702, 322, 323, 549, 948, 305, 306, 443, 1211, + 486, 1212, 1056, 307, 760, 308, 487, 324, 325, 353, + 309, 310, 1057, 380, 444, 1173, 1174, 1175, 1058, 548, + 392, 393, 725, 394, 528, 395, 396, 949, 397, 445, + 1090, 398, 566, 446, 1059, 326, 475, 354, 311, 1213, + 568, 399, 251, 116, 400, 401, 375, 402, 117, 118, + 492, 403, 404, 405, 119, 406, 407, 949, 408, 1060, + 409, 410, 120, 411, 355, 252, 493, 1061, 121, 412, + 122, 123, 124, 805, 549, 413, 327, 125, 414, 415, + 416, 494, 417, 126, 127, 495, 128, 129, 130, 418, + 419, 356, 131, 420, 422, 424, 425, 132, 253, 426, + 427, 133, 134, 428, 429, 135, 1062, 430, 600, 447, + 1214, 1215, 431, 432, 136, 433, 434, 435, 448, 449, + 436, 137, 138, 1063, 139, 140, 141, 142, 143, 357, + 254, 437, 255, 256, 438, 439, 616, 567, 496, 144, + 440, 483, 488, 1216, 569, 145, 146, 147, 489, 148, + 450, 1194, 149, 150, 520, 570, 151, 521, 522, 523, + 344, 497, 345, 524, 346, 525, 529, 530, 531, 257, + 532, 258, 259, 260, 261, 1094, 347, 533, 498, 534, + 535, 536, 537, 538, 1147, 539, 540, 571, 262, 572, + 152, 348, 313, 541, 153, 349, 1095, 154, 155, 156, + 157, 158, 542, 451, 159, 160, 314, 315, 543, 562, + 316, 1096, 263, 572, 575, 350, 576, 351, 1097, 578, + 577, 579, 264, 580, 582, 583, 584, 352, 775, 776, + 777, 778, 779, 585, 586, 1098, 622, 629, 587, 588, + 589, 499, 590, 591, 161, 162, 163, 592, 353, 164, + 265, 266, 593, 594, 165, 500, 1148, 595, 1099, 602, + 632, 596, 861, 633, 597, 1100, 598, 317, 318, 319, + 2, 3, 320, 599, 4, 603, 354, 1101, 604, 634, + 321, 605, 623, 635, 5, 1149, 606, 6, 7, 608, + 609, 322, 323, 8, 1150, 1102, 1103, 1104, 610, 236, + 1151, 611, 612, 355, 9, 613, 324, 325, 10, 11, + 884, 614, 615, 618, 1152, 619, 1153, 1154, 12, 624, + 625, 636, 637, 639, 641, 1155, 642, 643, 644, 645, + 356, 1156, 13, 646, 326, 237, 648, 649, 1118, 651, + 14, 15, 652, 654, 653, 1105, 655, 656, 657, 238, + 239, 240, 241, 658, 1106, 659, 660, 663, 16, 1107, + 664, 665, 666, 675, 671, 1108, 672, 242, 357, 1109, + 677, 1110, 17, 678, 679, 327, 1111, 862, 863, 864, + 865, 866, 1112, 867, 868, 680, 869, 870, 871, 1161, + 681, 872, 682, 873, 874, 683, 875, 685, 876, 686, + 877, 878, 704, 687, 879, 752, 18, 688, 689, 706, + 880, 692, 694, 697, 699, 19, 20, 700, 707, 21, + 22, 708, 705, 701, 709, 885, 886, 887, 888, 889, + 710, 890, 891, 721, 892, 893, 894, 711, 712, 895, + 714, 896, 897, 727, 898, 728, 899, 715, 900, 901, + 716, 718, 902, 1119, 1120, 1121, 1122, 1123, 903, 1124, + 1125, 1162, 1126, 1127, 1128, 729, 722, 1129, 76, 1130, + 1131, 23, 1132, 723, 1133, 724, 1134, 1135, 730, 731, + 1136, 733, 734, 735, 736, 737, 1137, 738, 77, 78, + 1163, 739, 740, 741, 79, 750, 751, 753, 754, 1164, + 757, 755, 759, 756, 762, 1165, 767, 768, 763, 769, + 770, 771, 772, 793, 773, 794, 774, 782, 796, 1166, + 783, 1167, 1168, 784, 785, 786, 787, 788, 789, 790, + 1169, 791, 792, 80, 81, 797, 1170, 798, 799, 800, + 82, 83, 84, 801, 802, 805, 808, 809, 812, 813, + 814, 815, 816, 817, 819, 818, 823, 826, 820, 821, + 822, 824, 85, 86, 827, 825, 828, 829, 830, 831, + 832, 833, 834, 835, 836, 87, 88, 837, 838, 925, + 839, 928, 929, 840, 926, 841, 89, 842, 930, 927, + 931, 843, 932, 934, 90, 936, 844, 845, 846, 847, + 848, 849, 850, 939, 940, 851, 852, 853, 854, 855, + 856, 857, 858, 859, 860, 883, 906, 907, 908, 909, + 910, 911, 912, 913, 914, 915, 916, 917, 918, 941, + 919, 957, 920, 921, 960, 922, 958, 923, 924, 961, + 933, 962, 937, 964, 935, 966, 938, 944, 1145, 959, + 967, 968, 993, 995, 997, 296, 1083, 1188, 1091, 1144, + 1227, 720, 1046, 1222, 1221, 945, 955, 956, 601, 965, + 1208, 963, 969, 970, 971, 972, 1072, 973, 485, 974, + 975, 976, 1189, 977, 978, 703, 979, 691, 980, 1191, + 1206, 726, 761, 981, 982, 983, 988, 989, 1223, 990, + 1204, 766, 991, 992, 1224, 996, 617, 994, 999, 998, + 1000, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, + 1015, 1016, 1017, 1023, 1024, 1025, 1026, 1027, 1207, 1028, + 1029, 696, 1034, 1035, 1036, 1037, 621, 1038, 382, 1039, + 1205, 1040, 1180, 1041, 1042, 442, 1043, 1181, 312, 628, + 0, 0, 1044, 1045, 0, 1053, 1054, 1066, 1067, 1068, + 1069, 1070, 1071, 1075, 1081, 1082, 0, 1086, 0, 0, + 1084, 1092, 1087, 1089, 1093, 1115, 1116, 1117, 1140, 1141, + 1142, 1143, 1146, 1159, 1160, 1190, 0, 491, 1195, 1209, + 1192, 1219, 1220, 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, 527, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 545, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 564 +}; + +#define yypact_value_is_default(yystate) \ + ((yystate) == (-744)) + +#define yytable_value_is_error(yytable_value) \ + YYID (0) + +static const yytype_int16 yycheck[] = +{ + 598, 599, 300, 301, 1, 1, 215, 216, 1, 1, + 308, 1, 1, 99, 160, 161, 1, 1, 51, 1, + 215, 8, 1, 1, 219, 1, 1, 160, 161, 1, + 217, 1, 775, 776, 777, 778, 779, 1, 217, 1, + 37, 217, 24, 215, 6, 7, 217, 219, 215, 31, + 12, 217, 219, 217, 51, 52, 53, 54, 20, 1, + 1, 215, 1, 215, 26, 219, 28, 29, 30, 61, + 215, 1, 69, 35, 219, 17, 1, 61, 217, 41, + 42, 217, 44, 45, 46, 24, 217, 17, 50, 61, + 32, 217, 31, 55, 36, 393, 394, 59, 60, 24, + 89, 63, 32, 401, 89, 403, 36, 89, 87, 195, + 72, 89, 410, 217, 89, 413, 1, 79, 80, 89, + 82, 83, 84, 85, 86, 89, 424, 425, 120, 1, + 120, 120, 57, 217, 113, 97, 434, 435, 217, 437, + 217, 103, 104, 105, 120, 107, 87, 1, 110, 111, + 89, 36, 114, 186, 217, 1, 120, 217, 191, 89, + 14, 151, 151, 1, 89, 215, 91, 92, 217, 219, + 112, 56, 113, 151, 215, 151, 61, 217, 219, 121, + 122, 151, 112, 21, 22, 1, 148, 151, 215, 27, + 152, 217, 219, 155, 156, 157, 158, 159, 215, 129, + 162, 163, 219, 128, 191, 130, 131, 132, 133, 1, + 1, 153, 208, 134, 135, 208, 206, 89, 214, 216, + 216, 214, 147, 14, 216, 118, 216, 525, 66, 67, + 206, 216, 117, 1, 216, 73, 74, 75, 216, 93, + 202, 203, 204, 89, 216, 207, 171, 15, 16, 215, + 212, 19, 216, 219, 216, 215, 181, 95, 96, 219, + 1, 1, 192, 3, 206, 5, 120, 1, 215, 217, + 108, 109, 219, 89, 216, 216, 206, 17, 215, 151, + 218, 119, 219, 215, 209, 210, 216, 219, 215, 127, + 588, 216, 32, 134, 135, 36, 36, 89, 596, 597, + 178, 179, 93, 218, 218, 151, 218, 218, 76, 77, + 78, 218, 218, 81, 218, 56, 56, 40, 58, 218, + 61, 89, 13, 9, 10, 11, 218, 61, 68, 120, + 218, 216, 100, 101, 206, 151, 218, 218, 1, 62, + 214, 64, 33, 218, 216, 218, 215, 115, 116, 89, + 218, 218, 43, 218, 17, 1018, 1019, 1020, 49, 151, + 218, 218, 216, 218, 215, 218, 218, 213, 218, 32, + 216, 218, 118, 36, 65, 143, 117, 117, 216, 102, + 215, 218, 1, 1, 218, 218, 120, 218, 6, 7, + 1, 218, 218, 218, 12, 218, 218, 213, 218, 90, + 218, 218, 20, 218, 144, 24, 17, 98, 26, 218, + 28, 29, 30, 99, 206, 218, 184, 35, 218, 218, + 218, 32, 218, 41, 42, 36, 44, 45, 46, 218, + 218, 171, 50, 218, 218, 218, 218, 55, 57, 218, + 218, 59, 60, 218, 218, 63, 137, 218, 216, 112, + 173, 174, 218, 218, 72, 218, 218, 218, 121, 122, + 218, 79, 80, 154, 82, 83, 84, 85, 86, 209, + 89, 218, 91, 92, 218, 218, 216, 118, 89, 97, + 218, 218, 218, 206, 99, 103, 104, 105, 218, 107, + 153, 1089, 110, 111, 218, 99, 114, 218, 218, 218, + 1, 112, 3, 218, 5, 218, 218, 218, 218, 128, + 218, 130, 131, 132, 133, 4, 17, 218, 129, 218, + 218, 218, 218, 218, 64, 218, 218, 160, 147, 99, + 148, 32, 1, 218, 152, 36, 25, 155, 156, 157, + 158, 159, 218, 206, 162, 163, 15, 16, 218, 218, + 19, 40, 171, 99, 99, 56, 99, 58, 47, 160, + 99, 160, 181, 99, 160, 160, 215, 68, 138, 139, + 140, 141, 142, 215, 218, 64, 118, 160, 218, 218, + 218, 192, 218, 218, 202, 203, 204, 218, 89, 207, + 209, 210, 218, 218, 212, 206, 136, 218, 87, 215, + 99, 218, 51, 160, 218, 94, 218, 76, 77, 78, + 0, 1, 81, 218, 4, 218, 117, 106, 218, 160, + 89, 218, 215, 99, 14, 165, 218, 17, 18, 218, + 218, 100, 101, 23, 174, 124, 125, 126, 218, 1, + 180, 218, 218, 144, 34, 218, 115, 116, 38, 39, + 51, 218, 218, 218, 194, 218, 196, 197, 48, 218, + 218, 118, 160, 160, 99, 205, 99, 99, 160, 160, + 171, 211, 62, 160, 143, 37, 99, 99, 51, 99, + 70, 71, 99, 99, 118, 174, 99, 160, 160, 51, + 52, 53, 54, 218, 183, 160, 218, 160, 88, 188, + 160, 160, 160, 118, 160, 194, 160, 69, 209, 198, + 160, 200, 102, 160, 160, 184, 205, 166, 167, 168, + 169, 170, 211, 172, 173, 215, 175, 176, 177, 64, + 215, 180, 218, 182, 183, 218, 185, 218, 187, 218, + 189, 190, 160, 218, 193, 99, 136, 218, 218, 217, + 199, 218, 218, 215, 218, 145, 146, 218, 118, 149, + 150, 118, 215, 218, 215, 166, 167, 168, 169, 170, + 215, 172, 173, 215, 175, 176, 177, 218, 218, 180, + 218, 182, 183, 160, 185, 160, 187, 218, 189, 190, + 218, 218, 193, 166, 167, 168, 169, 170, 199, 172, + 173, 136, 175, 176, 177, 118, 218, 180, 1, 182, + 183, 201, 185, 218, 187, 218, 189, 190, 160, 160, + 193, 215, 118, 160, 118, 118, 199, 118, 21, 22, + 165, 118, 118, 118, 27, 118, 118, 118, 118, 174, + 218, 215, 218, 215, 215, 180, 118, 215, 218, 215, + 215, 215, 215, 99, 215, 99, 215, 215, 99, 194, + 215, 196, 197, 215, 215, 215, 215, 215, 215, 215, + 205, 215, 215, 66, 67, 99, 211, 99, 99, 118, + 73, 74, 75, 99, 99, 99, 215, 118, 118, 160, + 218, 118, 118, 118, 99, 118, 215, 215, 118, 118, + 118, 118, 95, 96, 215, 118, 118, 118, 218, 215, + 215, 215, 215, 215, 215, 108, 109, 215, 215, 118, + 215, 118, 99, 215, 160, 215, 119, 215, 118, 218, + 118, 215, 118, 118, 127, 118, 215, 215, 215, 215, + 215, 215, 215, 118, 118, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, 215, 99, + 215, 118, 215, 215, 118, 215, 160, 215, 215, 118, + 215, 118, 215, 118, 218, 118, 218, 215, 987, 218, + 118, 118, 118, 118, 118, 71, 164, 99, 950, 985, + 1226, 501, 123, 1199, 1197, 215, 215, 215, 328, 215, + 1187, 218, 215, 215, 215, 215, 123, 215, 222, 215, + 215, 215, 1084, 215, 215, 477, 215, 452, 215, 118, + 1183, 515, 550, 215, 215, 215, 215, 215, 1201, 215, + 1177, 558, 215, 215, 1203, 215, 358, 218, 215, 218, + 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, 1185, 215, + 215, 467, 215, 215, 215, 215, 376, 215, 112, 215, + 1179, 215, 1050, 215, 215, 166, 215, 1052, 91, 388, + -1, -1, 215, 215, -1, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, -1, 215, -1, -1, + 219, 215, 218, 218, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, -1, 230, 215, 215, + 218, 215, 215, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 243, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 267, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 288 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint16 yystos[] = +{ + 0, 221, 0, 1, 4, 14, 17, 18, 23, 34, + 38, 39, 48, 62, 70, 71, 88, 102, 136, 145, + 146, 149, 150, 201, 222, 227, 232, 254, 260, 274, + 292, 310, 324, 339, 346, 350, 360, 369, 389, 399, + 405, 409, 419, 477, 494, 215, 216, 217, 217, 293, + 370, 400, 217, 410, 217, 325, 390, 311, 217, 217, + 275, 340, 217, 217, 351, 361, 217, 1, 24, 31, + 89, 255, 256, 257, 258, 259, 1, 21, 22, 27, + 66, 67, 73, 74, 75, 95, 96, 108, 109, 119, + 127, 478, 479, 480, 481, 482, 483, 484, 485, 486, + 487, 488, 489, 490, 491, 492, 493, 217, 217, 217, + 1, 61, 406, 407, 408, 217, 1, 6, 7, 12, + 20, 26, 28, 29, 30, 35, 41, 42, 44, 45, + 46, 50, 55, 59, 60, 63, 72, 79, 80, 82, + 83, 84, 85, 86, 97, 103, 104, 105, 107, 110, + 111, 114, 148, 152, 155, 156, 157, 158, 159, 162, + 163, 202, 203, 204, 207, 212, 420, 421, 422, 423, + 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, + 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, + 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, + 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 470, 474, 475, 476, 217, 217, 217, + 1, 208, 261, 262, 263, 264, 265, 1, 87, 113, + 228, 229, 230, 231, 217, 217, 1, 37, 51, 52, + 53, 54, 69, 495, 496, 497, 498, 499, 500, 501, + 502, 1, 24, 57, 89, 91, 92, 128, 130, 131, + 132, 133, 147, 171, 181, 209, 210, 233, 234, 235, + 236, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 217, 217, 1, 89, 347, 348, + 349, 215, 218, 218, 218, 216, 256, 218, 218, 218, + 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + 218, 216, 479, 1, 15, 16, 19, 76, 77, 78, + 81, 89, 100, 101, 115, 116, 143, 184, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, 1, 3, 5, 17, 32, 36, + 56, 58, 68, 89, 117, 144, 171, 209, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 380, 384, 385, + 386, 387, 388, 1, 61, 120, 401, 402, 403, 404, + 218, 216, 407, 1, 89, 120, 151, 411, 415, 416, + 417, 418, 218, 218, 218, 218, 218, 218, 218, 218, + 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + 218, 471, 218, 467, 218, 218, 218, 218, 218, 218, + 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + 218, 216, 421, 1, 17, 32, 36, 112, 121, 122, + 153, 206, 326, 327, 328, 329, 330, 331, 332, 336, + 337, 338, 1, 120, 151, 206, 391, 395, 396, 397, + 398, 1, 36, 56, 61, 117, 312, 316, 317, 318, + 322, 323, 215, 218, 216, 262, 214, 215, 218, 218, + 216, 229, 1, 17, 32, 36, 89, 112, 129, 192, + 206, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 288, 1, 14, 93, 120, 341, 342, 343, 344, 345, + 218, 218, 218, 218, 218, 218, 216, 496, 215, 218, + 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + 218, 218, 218, 218, 216, 234, 1, 89, 151, 206, + 352, 353, 354, 355, 356, 1, 89, 151, 362, 363, + 364, 365, 218, 216, 348, 118, 118, 118, 215, 99, + 99, 160, 99, 224, 224, 99, 99, 99, 160, 160, + 99, 224, 160, 160, 215, 215, 218, 218, 218, 218, + 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + 216, 295, 215, 218, 218, 218, 218, 381, 218, 218, + 218, 218, 218, 218, 218, 218, 216, 372, 218, 218, + 216, 402, 118, 215, 218, 218, 412, 216, 416, 160, + 224, 224, 99, 160, 160, 99, 118, 160, 224, 160, + 224, 99, 99, 99, 160, 160, 160, 224, 99, 99, + 224, 99, 99, 118, 99, 99, 160, 160, 218, 160, + 218, 224, 224, 160, 160, 160, 160, 160, 161, 160, + 161, 160, 160, 224, 224, 118, 224, 160, 160, 160, + 215, 215, 218, 218, 333, 218, 218, 218, 218, 218, + 216, 327, 218, 392, 218, 216, 396, 215, 313, 218, + 218, 218, 216, 317, 160, 215, 217, 118, 118, 215, + 215, 218, 218, 289, 218, 218, 218, 285, 218, 216, + 277, 215, 218, 218, 218, 216, 342, 160, 160, 118, + 160, 160, 224, 215, 118, 160, 118, 118, 118, 118, + 118, 118, 134, 135, 237, 238, 134, 135, 239, 240, + 118, 118, 99, 118, 118, 215, 215, 218, 357, 218, + 216, 353, 215, 218, 366, 216, 363, 118, 215, 215, + 215, 215, 215, 215, 215, 138, 139, 140, 141, 142, + 223, 224, 215, 215, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 99, 99, 224, 99, 99, 99, 99, + 118, 99, 99, 224, 224, 99, 226, 226, 215, 118, + 178, 179, 118, 160, 218, 118, 118, 118, 118, 99, + 118, 118, 118, 215, 118, 118, 215, 215, 118, 118, + 218, 215, 215, 215, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, + 215, 51, 166, 167, 168, 169, 170, 172, 173, 175, + 176, 177, 180, 182, 183, 185, 187, 189, 190, 193, + 199, 472, 473, 215, 51, 166, 167, 168, 169, 170, + 172, 173, 175, 176, 177, 180, 182, 183, 185, 187, + 189, 190, 193, 199, 468, 469, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 118, 160, 218, 118, 99, + 118, 118, 118, 215, 118, 218, 118, 215, 218, 118, + 118, 99, 320, 321, 215, 215, 1, 89, 151, 213, + 266, 267, 268, 269, 270, 215, 215, 118, 160, 218, + 118, 118, 118, 218, 118, 215, 118, 118, 118, 215, + 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 219, 215, 219, 215, 215, + 215, 215, 215, 118, 218, 118, 215, 118, 218, 215, + 215, 223, 223, 223, 223, 223, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, 9, 10, + 11, 225, 226, 215, 215, 215, 215, 215, 215, 215, + 8, 191, 382, 383, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 123, 413, 414, 215, + 219, 215, 219, 215, 215, 13, 33, 43, 49, 65, + 90, 98, 137, 154, 334, 335, 215, 215, 215, 215, + 215, 215, 123, 393, 394, 215, 51, 186, 191, 314, + 315, 215, 215, 164, 219, 319, 215, 218, 271, 218, + 216, 267, 215, 215, 4, 25, 40, 47, 64, 87, + 94, 106, 124, 125, 126, 174, 183, 188, 194, 198, + 200, 205, 211, 290, 291, 215, 215, 215, 51, 166, + 167, 168, 169, 170, 172, 173, 175, 176, 177, 180, + 182, 183, 185, 187, 189, 190, 193, 199, 286, 287, + 215, 215, 215, 215, 238, 240, 215, 64, 136, 165, + 174, 180, 194, 196, 197, 205, 211, 358, 359, 215, + 215, 64, 136, 165, 174, 180, 194, 196, 197, 205, + 211, 367, 368, 225, 225, 225, 215, 219, 215, 219, + 473, 469, 215, 219, 215, 219, 215, 219, 99, 321, + 215, 118, 218, 195, 226, 215, 215, 219, 215, 219, + 215, 219, 215, 219, 383, 414, 335, 394, 315, 215, + 40, 62, 64, 102, 173, 174, 206, 272, 273, 215, + 215, 291, 287, 359, 368, 215, 219, 273 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + + + +/* This macro is provided for backward compatibility. */ + +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULL; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html> + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 26: +/* Line 1787 of yacc.c */ +#line 359 "conf_parser.y" + { (yyval.number) = 0; } + break; + + case 28: +/* Line 1787 of yacc.c */ +#line 361 "conf_parser.y" + { + (yyval.number) = (yyvsp[(1) - (2)].number) + (yyvsp[(2) - (2)].number); + } + break; + + case 29: +/* Line 1787 of yacc.c */ +#line 365 "conf_parser.y" + { + (yyval.number) = (yyvsp[(1) - (3)].number) + (yyvsp[(3) - (3)].number); + } + break; + + case 30: +/* Line 1787 of yacc.c */ +#line 369 "conf_parser.y" + { + (yyval.number) = (yyvsp[(1) - (3)].number) * 60 + (yyvsp[(3) - (3)].number); + } + break; + + case 31: +/* Line 1787 of yacc.c */ +#line 373 "conf_parser.y" + { + (yyval.number) = (yyvsp[(1) - (3)].number) * 60 * 60 + (yyvsp[(3) - (3)].number); + } + break; + + case 32: +/* Line 1787 of yacc.c */ +#line 377 "conf_parser.y" + { + (yyval.number) = (yyvsp[(1) - (3)].number) * 60 * 60 * 24 + (yyvsp[(3) - (3)].number); + } + break; + + case 33: +/* Line 1787 of yacc.c */ +#line 381 "conf_parser.y" + { + (yyval.number) = (yyvsp[(1) - (3)].number) * 60 * 60 * 24 * 7 + (yyvsp[(3) - (3)].number); + } + break; + + case 34: +/* Line 1787 of yacc.c */ +#line 386 "conf_parser.y" + { (yyval.number) = 0; } + break; + + case 36: +/* Line 1787 of yacc.c */ +#line 387 "conf_parser.y" + { (yyval.number) = (yyvsp[(1) - (2)].number) + (yyvsp[(2) - (2)].number); } + break; + + case 37: +/* Line 1787 of yacc.c */ +#line 388 "conf_parser.y" + { (yyval.number) = (yyvsp[(1) - (3)].number) + (yyvsp[(3) - (3)].number); } + break; + + case 38: +/* Line 1787 of yacc.c */ +#line 389 "conf_parser.y" + { (yyval.number) = (yyvsp[(1) - (3)].number) * 1024 + (yyvsp[(3) - (3)].number); } + break; + + case 39: +/* Line 1787 of yacc.c */ +#line 390 "conf_parser.y" + { (yyval.number) = (yyvsp[(1) - (3)].number) * 1024 * 1024 + (yyvsp[(3) - (3)].number); } + break; + + case 46: +/* Line 1787 of yacc.c */ +#line 404 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + add_conf_module(libio_basename(yylval.string)); +} + break; + + case 47: +/* Line 1787 of yacc.c */ +#line 410 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + mod_add_path(yylval.string); +} + break; + + case 71: +/* Line 1787 of yacc.c */ +#line 435 "conf_parser.y" + { +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx) + SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv3); +#endif +} + break; + + case 72: +/* Line 1787 of yacc.c */ +#line 441 "conf_parser.y" + { +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx) + SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_TLSv1); +#endif +} + break; + + case 75: +/* Line 1787 of yacc.c */ +#line 450 "conf_parser.y" + { +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) + SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv3); +#endif +} + break; + + case 76: +/* Line 1787 of yacc.c */ +#line 456 "conf_parser.y" + { +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) + SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_TLSv1); +#endif +} + break; + + case 77: +/* Line 1787 of yacc.c */ +#line 464 "conf_parser.y" + { +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) + { + if (!ServerInfo.rsa_private_key_file) + { + yyerror("No rsa_private_key_file specified, SSL disabled"); + break; + } + + if (SSL_CTX_use_certificate_file(ServerInfo.server_ctx, yylval.string, + SSL_FILETYPE_PEM) <= 0 || + SSL_CTX_use_certificate_file(ServerInfo.client_ctx, yylval.string, + SSL_FILETYPE_PEM) <= 0) + { + yyerror(ERR_lib_error_string(ERR_get_error())); + break; + } + + if (SSL_CTX_use_PrivateKey_file(ServerInfo.server_ctx, ServerInfo.rsa_private_key_file, + SSL_FILETYPE_PEM) <= 0 || + SSL_CTX_use_PrivateKey_file(ServerInfo.client_ctx, ServerInfo.rsa_private_key_file, + SSL_FILETYPE_PEM) <= 0) + { + yyerror(ERR_lib_error_string(ERR_get_error())); + break; + } + + if (!SSL_CTX_check_private_key(ServerInfo.server_ctx) || + !SSL_CTX_check_private_key(ServerInfo.client_ctx)) + { + yyerror(ERR_lib_error_string(ERR_get_error())); + break; + } + } +#endif +} + break; + + case 78: +/* Line 1787 of yacc.c */ +#line 503 "conf_parser.y" + { +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 1) + { + BIO *file; + + if (ServerInfo.rsa_private_key) + { + RSA_free(ServerInfo.rsa_private_key); + ServerInfo.rsa_private_key = NULL; + } + + if (ServerInfo.rsa_private_key_file) + { + MyFree(ServerInfo.rsa_private_key_file); + ServerInfo.rsa_private_key_file = NULL; + } + + DupString(ServerInfo.rsa_private_key_file, yylval.string); + + if ((file = BIO_new_file(yylval.string, "r")) == NULL) + { + yyerror("File open failed, ignoring"); + break; + } + + ServerInfo.rsa_private_key = PEM_read_bio_RSAPrivateKey(file, NULL, 0, NULL); + + BIO_set_close(file, BIO_CLOSE); + BIO_free(file); + + if (ServerInfo.rsa_private_key == NULL) + { + yyerror("Couldn't extract key, ignoring"); + break; + } + + if (!RSA_check_key(ServerInfo.rsa_private_key)) + { + RSA_free(ServerInfo.rsa_private_key); + ServerInfo.rsa_private_key = NULL; + + yyerror("Invalid key, ignoring"); + break; + } + + /* require 2048 bit (256 byte) key */ + if (RSA_size(ServerInfo.rsa_private_key) != 256) + { + RSA_free(ServerInfo.rsa_private_key); + ServerInfo.rsa_private_key = NULL; + + yyerror("Not a 2048 bit key, ignoring"); + } + } +#endif +} + break; + + case 79: +/* Line 1787 of yacc.c */ +#line 562 "conf_parser.y" + { +/* TBD - XXX: error reporting */ +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) + { + BIO *file = BIO_new_file(yylval.string, "r"); + + if (file) + { + DH *dh = PEM_read_bio_DHparams(file, NULL, NULL, NULL); + + BIO_free(file); + + if (dh) + { + if (DH_size(dh) < 128) + ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::ssl_dh_param_file -- need at least a 1024 bit DH prime size"); + else + SSL_CTX_set_tmp_dh(ServerInfo.server_ctx, dh); + + DH_free(dh); + } + } + } +#endif +} + break; + + case 80: +/* Line 1787 of yacc.c */ +#line 590 "conf_parser.y" + { +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) + SSL_CTX_set_cipher_list(ServerInfo.server_ctx, yylval.string); +#endif +} + break; + + case 81: +/* Line 1787 of yacc.c */ +#line 598 "conf_parser.y" + { + /* this isn't rehashable */ + if (conf_parser_ctx.pass == 2 && !ServerInfo.name) + { + if (valid_servname(yylval.string)) + DupString(ServerInfo.name, yylval.string); + else + { + ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::name -- invalid name. Aborting."); + exit(0); + } + } +} + break; + + case 82: +/* Line 1787 of yacc.c */ +#line 613 "conf_parser.y" + { + /* this isn't rehashable */ + if (conf_parser_ctx.pass == 2 && !ServerInfo.sid) + { + if (valid_sid(yylval.string)) + DupString(ServerInfo.sid, yylval.string); + else + { + ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::sid -- invalid SID. Aborting."); + exit(0); + } + } +} + break; + + case 83: +/* Line 1787 of yacc.c */ +#line 628 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(ServerInfo.description); + DupString(ServerInfo.description,yylval.string); + } +} + break; + + case 84: +/* Line 1787 of yacc.c */ +#line 637 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + char *p; + + if ((p = strchr(yylval.string, ' ')) != NULL) + p = '\0'; + + MyFree(ServerInfo.network_name); + DupString(ServerInfo.network_name, yylval.string); + } +} + break; + + case 85: +/* Line 1787 of yacc.c */ +#line 651 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(ServerInfo.network_desc); + DupString(ServerInfo.network_desc, yylval.string); + } +} + break; + + case 86: +/* Line 1787 of yacc.c */ +#line 660 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2 && *yylval.string != '*') + { + struct addrinfo hints, *res; + + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + + if (getaddrinfo(yylval.string, NULL, &hints, &res)) + ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string); + else + { + assert(res != NULL); + + memcpy(&ServerInfo.ip, res->ai_addr, res->ai_addrlen); + ServerInfo.ip.ss.ss_family = res->ai_family; + ServerInfo.ip.ss_len = res->ai_addrlen; + freeaddrinfo(res); + + ServerInfo.specific_ipv4_vhost = 1; + } + } +} + break; + + case 87: +/* Line 1787 of yacc.c */ +#line 688 "conf_parser.y" + { +#ifdef IPV6 + if (conf_parser_ctx.pass == 2 && *yylval.string != '*') + { + struct addrinfo hints, *res; + + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + + if (getaddrinfo(yylval.string, NULL, &hints, &res)) + ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost6(%s)", yylval.string); + else + { + assert(res != NULL); + + memcpy(&ServerInfo.ip6, res->ai_addr, res->ai_addrlen); + ServerInfo.ip6.ss.ss_family = res->ai_family; + ServerInfo.ip6.ss_len = res->ai_addrlen; + freeaddrinfo(res); + + ServerInfo.specific_ipv6_vhost = 1; + } + } +#endif +} + break; + + case 88: +/* Line 1787 of yacc.c */ +#line 718 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + recalc_fdlimit(NULL); + + if ((yyvsp[(3) - (4)].number) < MAXCLIENTS_MIN) + { + char buf[IRCD_BUFSIZE]; + ircsprintf(buf, "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN); + yyerror(buf); + } + else if ((yyvsp[(3) - (4)].number) > MAXCLIENTS_MAX) + { + char buf[IRCD_BUFSIZE]; + ircsprintf(buf, "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX); + yyerror(buf); + } + else + ServerInfo.max_clients = (yyvsp[(3) - (4)].number); + } +} + break; + + case 89: +/* Line 1787 of yacc.c */ +#line 741 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ServerInfo.hub = yylval.number; +} + break; + + case 97: +/* Line 1787 of yacc.c */ +#line 756 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(AdminInfo.name); + DupString(AdminInfo.name, yylval.string); + } +} + break; + + case 98: +/* Line 1787 of yacc.c */ +#line 765 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(AdminInfo.email); + DupString(AdminInfo.email, yylval.string); + } +} + break; + + case 99: +/* Line 1787 of yacc.c */ +#line 774 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(AdminInfo.description); + DupString(AdminInfo.description, yylval.string); + } +} + break; + + case 106: +/* Line 1787 of yacc.c */ +#line 792 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ConfigLoggingEntry.use_logging = yylval.number; +} + break; + + case 107: +/* Line 1787 of yacc.c */ +#line 798 "conf_parser.y" + { + lfile[0] = '\0'; + ltype = 0; + lsize = 0; +} + break; + + case 108: +/* Line 1787 of yacc.c */ +#line 803 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2 && ltype > 0) + log_add_file(ltype, lsize, lfile); +} + break; + + case 115: +/* Line 1787 of yacc.c */ +#line 815 "conf_parser.y" + { + strlcpy(lfile, yylval.string, sizeof(lfile)); +} + break; + + case 116: +/* Line 1787 of yacc.c */ +#line 820 "conf_parser.y" + { + lsize = (yyvsp[(3) - (4)].number); +} + break; + + case 117: +/* Line 1787 of yacc.c */ +#line 823 "conf_parser.y" + { + lsize = 0; +} + break; + + case 118: +/* Line 1787 of yacc.c */ +#line 828 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ltype = 0; +} + break; + + case 122: +/* Line 1787 of yacc.c */ +#line 835 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_USER; +} + break; + + case 123: +/* Line 1787 of yacc.c */ +#line 839 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_OPER; +} + break; + + case 124: +/* Line 1787 of yacc.c */ +#line 843 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_GLINE; +} + break; + + case 125: +/* Line 1787 of yacc.c */ +#line 847 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_DLINE; +} + break; + + case 126: +/* Line 1787 of yacc.c */ +#line 851 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_KLINE; +} + break; + + case 127: +/* Line 1787 of yacc.c */ +#line 855 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_KILL; +} + break; + + case 128: +/* Line 1787 of yacc.c */ +#line 859 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_DEBUG; +} + break; + + case 129: +/* Line 1787 of yacc.c */ +#line 869 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + yy_conf = make_conf_item(OPER_TYPE); + yy_aconf = map_to_conf(yy_conf); + SetConfEncrypted(yy_aconf); /* Yes, the default is encrypted */ + } + else + { + MyFree(class_name); + class_name = NULL; + } +} + break; + + case 130: +/* Line 1787 of yacc.c */ +#line 882 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + struct CollectItem *yy_tmp; + dlink_node *ptr; + dlink_node *next_ptr; + + conf_add_class_to_conf(yy_conf, class_name); + + /* Now, make sure there is a copy of the "base" given oper + * block in each of the collected copies + */ + + DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head) + { + struct AccessItem *new_aconf; + struct ConfItem *new_conf; + yy_tmp = ptr->data; + + new_conf = make_conf_item(OPER_TYPE); + new_aconf = (struct AccessItem *)map_to_conf(new_conf); + + new_aconf->flags = yy_aconf->flags; + + if (yy_conf->name != NULL) + DupString(new_conf->name, yy_conf->name); + if (yy_tmp->user != NULL) + DupString(new_aconf->user, yy_tmp->user); + else + DupString(new_aconf->user, "*"); + if (yy_tmp->host != NULL) + DupString(new_aconf->host, yy_tmp->host); + else + DupString(new_aconf->host, "*"); + + new_aconf->type = parse_netmask(new_aconf->host, &new_aconf->addr, + &new_aconf->bits); + + conf_add_class_to_conf(new_conf, class_name); + if (yy_aconf->passwd != NULL) + DupString(new_aconf->passwd, yy_aconf->passwd); + + new_aconf->port = yy_aconf->port; +#ifdef HAVE_LIBCRYPTO + if (yy_aconf->rsa_public_key_file != NULL) + { + BIO *file; + + DupString(new_aconf->rsa_public_key_file, + yy_aconf->rsa_public_key_file); + + file = BIO_new_file(yy_aconf->rsa_public_key_file, "r"); + new_aconf->rsa_public_key = PEM_read_bio_RSA_PUBKEY(file, + NULL, 0, NULL); + BIO_set_close(file, BIO_CLOSE); + BIO_free(file); + } +#endif + +#ifdef HAVE_LIBCRYPTO + if (yy_tmp->name && (yy_tmp->passwd || yy_aconf->rsa_public_key) + && yy_tmp->host) +#else + if (yy_tmp->name && yy_tmp->passwd && yy_tmp->host) +#endif + { + conf_add_class_to_conf(new_conf, class_name); + if (yy_tmp->name != NULL) + DupString(new_conf->name, yy_tmp->name); + } + + dlinkDelete(&yy_tmp->node, &col_conf_list); + free_collect_item(yy_tmp); + } + + yy_conf = NULL; + yy_aconf = NULL; + + + MyFree(class_name); + class_name = NULL; + } +} + break; + + case 142: +/* Line 1787 of yacc.c */ +#line 972 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(yy_conf->name); + DupString(yy_conf->name, yylval.string); + } +} + break; + + case 143: +/* Line 1787 of yacc.c */ +#line 981 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + struct split_nuh_item nuh; + + nuh.nuhmask = yylval.string; + nuh.nickptr = NULL; + nuh.userptr = userbuf; + nuh.hostptr = hostbuf; + + nuh.nicksize = 0; + nuh.usersize = sizeof(userbuf); + nuh.hostsize = sizeof(hostbuf); + + split_nuh(&nuh); + + if (yy_aconf->user == NULL) + { + DupString(yy_aconf->user, userbuf); + DupString(yy_aconf->host, hostbuf); + + yy_aconf->type = parse_netmask(yy_aconf->host, &yy_aconf->addr, + &yy_aconf->bits); + } + else + { + struct CollectItem *yy_tmp = MyMalloc(sizeof(struct CollectItem)); + + DupString(yy_tmp->user, userbuf); + DupString(yy_tmp->host, hostbuf); + + dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list); + } + } +} + break; + + case 144: +/* Line 1787 of yacc.c */ +#line 1018 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (yy_aconf->passwd != NULL) + memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd)); + + MyFree(yy_aconf->passwd); + DupString(yy_aconf->passwd, yylval.string); + } +} + break; + + case 145: +/* Line 1787 of yacc.c */ +#line 1030 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (yylval.number) + SetConfEncrypted(yy_aconf); + else + ClearConfEncrypted(yy_aconf); + } +} + break; + + case 146: +/* Line 1787 of yacc.c */ +#line 1041 "conf_parser.y" + { +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2) + { + BIO *file; + + if (yy_aconf->rsa_public_key != NULL) + { + RSA_free(yy_aconf->rsa_public_key); + yy_aconf->rsa_public_key = NULL; + } + + if (yy_aconf->rsa_public_key_file != NULL) + { + MyFree(yy_aconf->rsa_public_key_file); + yy_aconf->rsa_public_key_file = NULL; + } + + DupString(yy_aconf->rsa_public_key_file, yylval.string); + file = BIO_new_file(yylval.string, "r"); + + if (file == NULL) + { + yyerror("Ignoring rsa_public_key_file -- file doesn't exist"); + break; + } + + yy_aconf->rsa_public_key = PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL); + + if (yy_aconf->rsa_public_key == NULL) + { + yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax."); + break; + } + + BIO_set_close(file, BIO_CLOSE); + BIO_free(file); + } +#endif /* HAVE_LIBCRYPTO */ +} + break; + + case 147: +/* Line 1787 of yacc.c */ +#line 1083 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(class_name); + DupString(class_name, yylval.string); + } +} + break; + + case 148: +/* Line 1787 of yacc.c */ +#line 1092 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes = 0; +} + break; + + case 152: +/* Line 1787 of yacc.c */ +#line 1099 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_BOTS; +} + break; + + case 153: +/* Line 1787 of yacc.c */ +#line 1103 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_CCONN; +} + break; + + case 154: +/* Line 1787 of yacc.c */ +#line 1107 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_CCONN_FULL; +} + break; + + case 155: +/* Line 1787 of yacc.c */ +#line 1111 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_DEAF; +} + break; + + case 156: +/* Line 1787 of yacc.c */ +#line 1115 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_DEBUG; +} + break; + + case 157: +/* Line 1787 of yacc.c */ +#line 1119 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_FULL; +} + break; + + case 158: +/* Line 1787 of yacc.c */ +#line 1123 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_HIDDEN; +} + break; + + case 159: +/* Line 1787 of yacc.c */ +#line 1127 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_SKILL; +} + break; + + case 160: +/* Line 1787 of yacc.c */ +#line 1131 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_NCHANGE; +} + break; + + case 161: +/* Line 1787 of yacc.c */ +#line 1135 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_REJ; +} + break; + + case 162: +/* Line 1787 of yacc.c */ +#line 1139 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_UNAUTH; +} + break; + + case 163: +/* Line 1787 of yacc.c */ +#line 1143 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_SPY; +} + break; + + case 164: +/* Line 1787 of yacc.c */ +#line 1147 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_EXTERNAL; +} + break; + + case 165: +/* Line 1787 of yacc.c */ +#line 1151 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_OPERWALL; +} + break; + + case 166: +/* Line 1787 of yacc.c */ +#line 1155 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_SERVNOTICE; +} + break; + + case 167: +/* Line 1787 of yacc.c */ +#line 1159 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_INVISIBLE; +} + break; + + case 168: +/* Line 1787 of yacc.c */ +#line 1163 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_WALLOP; +} + break; + + case 169: +/* Line 1787 of yacc.c */ +#line 1167 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_SOFTCALLERID; +} + break; + + case 170: +/* Line 1787 of yacc.c */ +#line 1171 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_CALLERID; +} + break; + + case 171: +/* Line 1787 of yacc.c */ +#line 1175 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_LOCOPS; +} + break; + + case 172: +/* Line 1787 of yacc.c */ +#line 1181 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port = 0; +} + break; + + case 176: +/* Line 1787 of yacc.c */ +#line 1188 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_GLOBAL_KILL; +} + break; + + case 177: +/* Line 1787 of yacc.c */ +#line 1192 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_REMOTE; +} + break; + + case 178: +/* Line 1787 of yacc.c */ +#line 1196 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_K; +} + break; + + case 179: +/* Line 1787 of yacc.c */ +#line 1200 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_UNKLINE; +} + break; + + case 180: +/* Line 1787 of yacc.c */ +#line 1204 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_DLINE; +} + break; + + case 181: +/* Line 1787 of yacc.c */ +#line 1208 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_UNDLINE; +} + break; + + case 182: +/* Line 1787 of yacc.c */ +#line 1212 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_X; +} + break; + + case 183: +/* Line 1787 of yacc.c */ +#line 1216 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_GLINE; +} + break; + + case 184: +/* Line 1787 of yacc.c */ +#line 1220 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_DIE; +} + break; + + case 185: +/* Line 1787 of yacc.c */ +#line 1224 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_RESTART; +} + break; + + case 186: +/* Line 1787 of yacc.c */ +#line 1228 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_REHASH; +} + break; + + case 187: +/* Line 1787 of yacc.c */ +#line 1232 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_ADMIN; +} + break; + + case 188: +/* Line 1787 of yacc.c */ +#line 1236 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_N; +} + break; + + case 189: +/* Line 1787 of yacc.c */ +#line 1240 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_OPERWALL; +} + break; + + case 190: +/* Line 1787 of yacc.c */ +#line 1244 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_GLOBOPS; +} + break; + + case 191: +/* Line 1787 of yacc.c */ +#line 1248 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_OPER_SPY; +} + break; + + case 192: +/* Line 1787 of yacc.c */ +#line 1252 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_REMOTEBAN; +} + break; + + case 193: +/* Line 1787 of yacc.c */ +#line 1256 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_SET; +} + break; + + case 194: +/* Line 1787 of yacc.c */ +#line 1260 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_MODULE; +} + break; + + case 195: +/* Line 1787 of yacc.c */ +#line 1270 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + { + yy_conf = make_conf_item(CLASS_TYPE); + yy_class = map_to_conf(yy_conf); + } +} + break; + + case 196: +/* Line 1787 of yacc.c */ +#line 1277 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + { + struct ConfItem *cconf = NULL; + struct ClassItem *class = NULL; + + if (yy_class_name == NULL) + delete_conf_item(yy_conf); + else + { + cconf = find_exact_name_conf(CLASS_TYPE, NULL, yy_class_name, NULL, NULL); + + if (cconf != NULL) /* The class existed already */ + { + int user_count = 0; + + rebuild_cidr_class(cconf, yy_class); + + class = map_to_conf(cconf); + + user_count = class->curr_user_count; + memcpy(class, yy_class, sizeof(*class)); + class->curr_user_count = user_count; + class->active = 1; + + delete_conf_item(yy_conf); + + MyFree(cconf->name); /* Allows case change of class name */ + cconf->name = yy_class_name; + } + else /* Brand new class */ + { + MyFree(yy_conf->name); /* just in case it was allocated */ + yy_conf->name = yy_class_name; + yy_class->active = 1; + } + } + + yy_class_name = NULL; + } +} + break; + + case 214: +/* Line 1787 of yacc.c */ +#line 1335 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + { + MyFree(yy_class_name); + DupString(yy_class_name, yylval.string); + } +} + break; + + case 215: +/* Line 1787 of yacc.c */ +#line 1344 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + yy_class->ping_freq = (yyvsp[(3) - (4)].number); +} + break; + + case 216: +/* Line 1787 of yacc.c */ +#line 1350 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + yy_class->ping_warning = (yyvsp[(3) - (4)].number); +} + break; + + case 217: +/* Line 1787 of yacc.c */ +#line 1356 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + yy_class->max_perip = (yyvsp[(3) - (4)].number); +} + break; + + case 218: +/* Line 1787 of yacc.c */ +#line 1362 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + yy_class->con_freq = (yyvsp[(3) - (4)].number); +} + break; + + case 219: +/* Line 1787 of yacc.c */ +#line 1368 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + yy_class->max_total = (yyvsp[(3) - (4)].number); +} + break; + + case 220: +/* Line 1787 of yacc.c */ +#line 1374 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + yy_class->max_global = (yyvsp[(3) - (4)].number); +} + break; + + case 221: +/* Line 1787 of yacc.c */ +#line 1380 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + yy_class->max_local = (yyvsp[(3) - (4)].number); +} + break; + + case 222: +/* Line 1787 of yacc.c */ +#line 1386 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + yy_class->max_ident = (yyvsp[(3) - (4)].number); +} + break; + + case 223: +/* Line 1787 of yacc.c */ +#line 1392 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + yy_class->max_sendq = (yyvsp[(3) - (4)].number); +} + break; + + case 224: +/* Line 1787 of yacc.c */ +#line 1398 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + if ((yyvsp[(3) - (4)].number) >= CLIENT_FLOOD_MIN && (yyvsp[(3) - (4)].number) <= CLIENT_FLOOD_MAX) + yy_class->max_recvq = (yyvsp[(3) - (4)].number); +} + break; + + case 225: +/* Line 1787 of yacc.c */ +#line 1405 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + yy_class->cidr_bitlen_ipv4 = (yyvsp[(3) - (4)].number) > 32 ? 32 : (yyvsp[(3) - (4)].number); +} + break; + + case 226: +/* Line 1787 of yacc.c */ +#line 1411 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + yy_class->cidr_bitlen_ipv6 = (yyvsp[(3) - (4)].number) > 128 ? 128 : (yyvsp[(3) - (4)].number); +} + break; + + case 227: +/* Line 1787 of yacc.c */ +#line 1417 "conf_parser.y" + { + if (conf_parser_ctx.pass == 1) + yy_class->number_per_cidr = (yyvsp[(3) - (4)].number); +} + break; + + case 228: +/* Line 1787 of yacc.c */ +#line 1426 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + listener_address = NULL; + listener_flags = 0; + } +} + break; + + case 229: +/* Line 1787 of yacc.c */ +#line 1433 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(listener_address); + listener_address = NULL; + } +} + break; + + case 230: +/* Line 1787 of yacc.c */ +#line 1442 "conf_parser.y" + { + listener_flags = 0; +} + break; + + case 234: +/* Line 1787 of yacc.c */ +#line 1448 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + listener_flags |= LISTENER_SSL; +} + break; + + case 235: +/* Line 1787 of yacc.c */ +#line 1452 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + listener_flags |= LISTENER_HIDDEN; +} + break; + + case 236: +/* Line 1787 of yacc.c */ +#line 1456 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + listener_flags |= LISTENER_SERVER; +} + break; + + case 244: +/* Line 1787 of yacc.c */ +#line 1466 "conf_parser.y" + { listener_flags = 0; } + break; + + case 248: +/* Line 1787 of yacc.c */ +#line 1471 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if ((listener_flags & LISTENER_SSL)) +#ifdef HAVE_LIBCRYPTO + if (!ServerInfo.server_ctx) +#endif + { + yyerror("SSL not available - port closed"); + break; + } + add_listener((yyvsp[(1) - (1)].number), listener_address, listener_flags); + } +} + break; + + case 249: +/* Line 1787 of yacc.c */ +#line 1485 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + int i; + + if ((listener_flags & LISTENER_SSL)) +#ifdef HAVE_LIBCRYPTO + if (!ServerInfo.server_ctx) +#endif + { + yyerror("SSL not available - port closed"); + break; + } + + for (i = (yyvsp[(1) - (3)].number); i <= (yyvsp[(3) - (3)].number); ++i) + add_listener(i, listener_address, listener_flags); + } +} + break; + + case 250: +/* Line 1787 of yacc.c */ +#line 1505 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(listener_address); + DupString(listener_address, yylval.string); + } +} + break; + + case 251: +/* Line 1787 of yacc.c */ +#line 1514 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(listener_address); + DupString(listener_address, yylval.string); + } +} + break; + + case 252: +/* Line 1787 of yacc.c */ +#line 1526 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + yy_conf = make_conf_item(CLIENT_TYPE); + yy_aconf = map_to_conf(yy_conf); + } + else + { + MyFree(class_name); + class_name = NULL; + } +} + break; + + case 253: +/* Line 1787 of yacc.c */ +#line 1538 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + struct CollectItem *yy_tmp = NULL; + dlink_node *ptr = NULL, *next_ptr = NULL; + + if (yy_aconf->user && yy_aconf->host) + { + conf_add_class_to_conf(yy_conf, class_name); + add_conf_by_address(CONF_CLIENT, yy_aconf); + } + else + delete_conf_item(yy_conf); + + /* copy over settings from first struct */ + DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head) + { + struct AccessItem *new_aconf; + struct ConfItem *new_conf; + + new_conf = make_conf_item(CLIENT_TYPE); + new_aconf = map_to_conf(new_conf); + + yy_tmp = ptr->data; + + assert(yy_tmp->user && yy_tmp->host); + + if (yy_aconf->passwd != NULL) + DupString(new_aconf->passwd, yy_aconf->passwd); + if (yy_conf->name != NULL) + DupString(new_conf->name, yy_conf->name); + if (yy_aconf->passwd != NULL) + DupString(new_aconf->passwd, yy_aconf->passwd); + + new_aconf->flags = yy_aconf->flags; + new_aconf->port = yy_aconf->port; + + DupString(new_aconf->user, yy_tmp->user); + collapse(new_aconf->user); + + DupString(new_aconf->host, yy_tmp->host); + collapse(new_aconf->host); + + conf_add_class_to_conf(new_conf, class_name); + add_conf_by_address(CONF_CLIENT, new_aconf); + dlinkDelete(&yy_tmp->node, &col_conf_list); + free_collect_item(yy_tmp); + } + + MyFree(class_name); + class_name = NULL; + yy_conf = NULL; + yy_aconf = NULL; + } +} + break; + + case 265: +/* Line 1787 of yacc.c */ +#line 1600 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + struct CollectItem *yy_tmp = NULL; + struct split_nuh_item nuh; + + nuh.nuhmask = yylval.string; + nuh.nickptr = NULL; + nuh.userptr = userbuf; + nuh.hostptr = hostbuf; + + nuh.nicksize = 0; + nuh.usersize = sizeof(userbuf); + nuh.hostsize = sizeof(hostbuf); + + split_nuh(&nuh); + + if (yy_aconf->user == NULL) + { + DupString(yy_aconf->user, userbuf); + DupString(yy_aconf->host, hostbuf); + } + else + { + yy_tmp = MyMalloc(sizeof(struct CollectItem)); + + DupString(yy_tmp->user, userbuf); + DupString(yy_tmp->host, hostbuf); + + dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list); + } + } +} + break; + + case 266: +/* Line 1787 of yacc.c */ +#line 1635 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + /* be paranoid */ + if (yy_aconf->passwd != NULL) + memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd)); + + MyFree(yy_aconf->passwd); + DupString(yy_aconf->passwd, yylval.string); + } +} + break; + + case 267: +/* Line 1787 of yacc.c */ +#line 1648 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(class_name); + DupString(class_name, yylval.string); + } +} + break; + + case 268: +/* Line 1787 of yacc.c */ +#line 1657 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (yylval.number) + SetConfEncrypted(yy_aconf); + else + ClearConfEncrypted(yy_aconf); + } +} + break; + + case 269: +/* Line 1787 of yacc.c */ +#line 1668 "conf_parser.y" + { +} + break; + + case 273: +/* Line 1787 of yacc.c */ +#line 1673 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE; +} + break; + + case 274: +/* Line 1787 of yacc.c */ +#line 1677 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_NOLIMIT; +} + break; + + case 275: +/* Line 1787 of yacc.c */ +#line 1681 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE; +} + break; + + case 276: +/* Line 1787 of yacc.c */ +#line 1685 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD; +} + break; + + case 277: +/* Line 1787 of yacc.c */ +#line 1689 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD; +} + break; + + case 278: +/* Line 1787 of yacc.c */ +#line 1693 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_NO_TILDE; +} + break; + + case 279: +/* Line 1787 of yacc.c */ +#line 1697 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE; +} + break; + + case 280: +/* Line 1787 of yacc.c */ +#line 1701 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_EXEMPTRESV; +} + break; + + case 281: +/* Line 1787 of yacc.c */ +#line 1705 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD; +} + break; + + case 282: +/* Line 1787 of yacc.c */ +#line 1711 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(yy_conf->name); + + if (strlen(yylval.string) <= HOSTLEN && valid_hostname(yylval.string)) + { + DupString(yy_conf->name, yylval.string); + yy_aconf->flags |= CONF_FLAGS_SPOOF_IP; + } + else + { + ilog(LOG_TYPE_IRCD, "Spoof either is too long or contains invalid characters. Ignoring it."); + yy_conf->name = NULL; + } + } +} + break; + + case 283: +/* Line 1787 of yacc.c */ +#line 1730 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + yy_aconf->flags |= CONF_FLAGS_REDIR; + MyFree(yy_conf->name); + DupString(yy_conf->name, yylval.string); + } +} + break; + + case 284: +/* Line 1787 of yacc.c */ +#line 1740 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + yy_aconf->flags |= CONF_FLAGS_REDIR; + yy_aconf->port = (yyvsp[(3) - (4)].number); + } +} + break; + + case 285: +/* Line 1787 of yacc.c */ +#line 1753 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(resv_reason); + resv_reason = NULL; + } +} + break; + + case 286: +/* Line 1787 of yacc.c */ +#line 1760 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(resv_reason); + resv_reason = NULL; + } +} + break; + + case 293: +/* Line 1787 of yacc.c */ +#line 1772 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(resv_reason); + DupString(resv_reason, yylval.string); + } +} + break; + + case 294: +/* Line 1787 of yacc.c */ +#line 1781 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (IsChanPrefix(*yylval.string)) + { + char def_reason[] = "No reason"; + + create_channel_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1); + } + } + /* ignore it for now.. but we really should make a warning if + * its an erroneous name --fl_ */ +} + break; + + case 295: +/* Line 1787 of yacc.c */ +#line 1796 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + char def_reason[] = "No reason"; + + create_nick_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1); + } +} + break; + + case 301: +/* Line 1787 of yacc.c */ +#line 1814 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (valid_servname(yylval.string)) + { + yy_conf = make_conf_item(SERVICE_TYPE); + DupString(yy_conf->name, yylval.string); + } + } +} + break; + + case 302: +/* Line 1787 of yacc.c */ +#line 1829 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + yy_conf = make_conf_item(ULINE_TYPE); + yy_match_item = map_to_conf(yy_conf); + yy_match_item->action = SHARED_ALL; + } +} + break; + + case 303: +/* Line 1787 of yacc.c */ +#line 1837 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + yy_conf = NULL; + } +} + break; + + case 310: +/* Line 1787 of yacc.c */ +#line 1848 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(yy_conf->name); + DupString(yy_conf->name, yylval.string); + } +} + break; + + case 311: +/* Line 1787 of yacc.c */ +#line 1857 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + struct split_nuh_item nuh; + + nuh.nuhmask = yylval.string; + nuh.nickptr = NULL; + nuh.userptr = userbuf; + nuh.hostptr = hostbuf; + + nuh.nicksize = 0; + nuh.usersize = sizeof(userbuf); + nuh.hostsize = sizeof(hostbuf); + + split_nuh(&nuh); + + DupString(yy_match_item->user, userbuf); + DupString(yy_match_item->host, hostbuf); + } +} + break; + + case 312: +/* Line 1787 of yacc.c */ +#line 1879 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_match_item->action = 0; +} + break; + + case 316: +/* Line 1787 of yacc.c */ +#line 1886 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_KLINE; +} + break; + + case 317: +/* Line 1787 of yacc.c */ +#line 1890 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_UNKLINE; +} + break; + + case 318: +/* Line 1787 of yacc.c */ +#line 1894 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_DLINE; +} + break; + + case 319: +/* Line 1787 of yacc.c */ +#line 1898 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_UNDLINE; +} + break; + + case 320: +/* Line 1787 of yacc.c */ +#line 1902 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_XLINE; +} + break; + + case 321: +/* Line 1787 of yacc.c */ +#line 1906 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_UNXLINE; +} + break; + + case 322: +/* Line 1787 of yacc.c */ +#line 1910 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_RESV; +} + break; + + case 323: +/* Line 1787 of yacc.c */ +#line 1914 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_UNRESV; +} + break; + + case 324: +/* Line 1787 of yacc.c */ +#line 1918 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_LOCOPS; +} + break; + + case 325: +/* Line 1787 of yacc.c */ +#line 1922 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_match_item->action = SHARED_ALL; +} + break; + + case 326: +/* Line 1787 of yacc.c */ +#line 1931 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + yy_conf = make_conf_item(CLUSTER_TYPE); + yy_conf->flags = SHARED_ALL; + } +} + break; + + case 327: +/* Line 1787 of yacc.c */ +#line 1938 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (yy_conf->name == NULL) + DupString(yy_conf->name, "*"); + yy_conf = NULL; + } +} + break; + + case 333: +/* Line 1787 of yacc.c */ +#line 1951 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + DupString(yy_conf->name, yylval.string); +} + break; + + case 334: +/* Line 1787 of yacc.c */ +#line 1957 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_conf->flags = 0; +} + break; + + case 338: +/* Line 1787 of yacc.c */ +#line 1964 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_KLINE; +} + break; + + case 339: +/* Line 1787 of yacc.c */ +#line 1968 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_UNKLINE; +} + break; + + case 340: +/* Line 1787 of yacc.c */ +#line 1972 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_DLINE; +} + break; + + case 341: +/* Line 1787 of yacc.c */ +#line 1976 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_UNDLINE; +} + break; + + case 342: +/* Line 1787 of yacc.c */ +#line 1980 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_XLINE; +} + break; + + case 343: +/* Line 1787 of yacc.c */ +#line 1984 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_UNXLINE; +} + break; + + case 344: +/* Line 1787 of yacc.c */ +#line 1988 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_RESV; +} + break; + + case 345: +/* Line 1787 of yacc.c */ +#line 1992 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_UNRESV; +} + break; + + case 346: +/* Line 1787 of yacc.c */ +#line 1996 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_LOCOPS; +} + break; + + case 347: +/* Line 1787 of yacc.c */ +#line 2000 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_conf->flags = SHARED_ALL; +} + break; + + case 348: +/* Line 1787 of yacc.c */ +#line 2009 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + yy_conf = make_conf_item(SERVER_TYPE); + yy_aconf = map_to_conf(yy_conf); + + /* defaults */ + yy_aconf->port = PORTNUM; + } + else + { + MyFree(class_name); + class_name = NULL; + } +} + break; + + case 349: +/* Line 1787 of yacc.c */ +#line 2024 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (yy_aconf->host && yy_aconf->passwd && yy_aconf->spasswd) + { + if (conf_add_server(yy_conf, class_name) == -1) + delete_conf_item(yy_conf); + } + else + { + if (yy_conf->name != NULL) + { + if (yy_aconf->host == NULL) + yyerror("Ignoring connect block -- missing host"); + else if (!yy_aconf->passwd || !yy_aconf->spasswd) + yyerror("Ignoring connect block -- missing password"); + } + + /* XXX + * This fixes a try_connections() core (caused by invalid class_ptr + * pointers) reported by metalrock. That's an ugly fix, but there + * is currently no better way. The entire config subsystem needs an + * rewrite ASAP. make_conf_item() shouldn't really add things onto + * a doubly linked list immediately without any sanity checks! -Michael + */ + delete_conf_item(yy_conf); + } + + MyFree(class_name); + class_name = NULL; + yy_conf = NULL; + yy_aconf = NULL; + } +} + break; + + case 366: +/* Line 1787 of yacc.c */ +#line 2068 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(yy_conf->name); + DupString(yy_conf->name, yylval.string); + } +} + break; + + case 367: +/* Line 1787 of yacc.c */ +#line 2077 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(yy_aconf->host); + DupString(yy_aconf->host, yylval.string); + } +} + break; + + case 368: +/* Line 1787 of yacc.c */ +#line 2086 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + struct addrinfo hints, *res; + + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + + if (getaddrinfo(yylval.string, NULL, &hints, &res)) + ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string); + else + { + assert(res != NULL); + + memcpy(&yy_aconf->bind, res->ai_addr, res->ai_addrlen); + yy_aconf->bind.ss.ss_family = res->ai_family; + yy_aconf->bind.ss_len = res->ai_addrlen; + freeaddrinfo(res); + } + } +} + break; + + case 369: +/* Line 1787 of yacc.c */ +#line 2112 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if ((yyvsp[(3) - (4)].string)[0] == ':') + yyerror("Server passwords cannot begin with a colon"); + else if (strchr((yyvsp[(3) - (4)].string), ' ') != NULL) + yyerror("Server passwords cannot contain spaces"); + else { + if (yy_aconf->spasswd != NULL) + memset(yy_aconf->spasswd, 0, strlen(yy_aconf->spasswd)); + + MyFree(yy_aconf->spasswd); + DupString(yy_aconf->spasswd, yylval.string); + } + } +} + break; + + case 370: +/* Line 1787 of yacc.c */ +#line 2130 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if ((yyvsp[(3) - (4)].string)[0] == ':') + yyerror("Server passwords cannot begin with a colon"); + else if (strchr((yyvsp[(3) - (4)].string), ' ') != NULL) + yyerror("Server passwords cannot contain spaces"); + else { + if (yy_aconf->passwd != NULL) + memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd)); + + MyFree(yy_aconf->passwd); + DupString(yy_aconf->passwd, yylval.string); + } + } +} + break; + + case 371: +/* Line 1787 of yacc.c */ +#line 2148 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->port = (yyvsp[(3) - (4)].number); +} + break; + + case 372: +/* Line 1787 of yacc.c */ +#line 2154 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + yy_aconf->aftype = AF_INET; +} + break; + + case 373: +/* Line 1787 of yacc.c */ +#line 2158 "conf_parser.y" + { +#ifdef IPV6 + if (conf_parser_ctx.pass == 2) + yy_aconf->aftype = AF_INET6; +#endif +} + break; + + case 374: +/* Line 1787 of yacc.c */ +#line 2166 "conf_parser.y" + { +} + break; + + case 378: +/* Line 1787 of yacc.c */ +#line 2171 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + SetConfAllowAutoConn(yy_aconf); +} + break; + + case 379: +/* Line 1787 of yacc.c */ +#line 2175 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + SetConfSSL(yy_aconf); +} + break; + + case 380: +/* Line 1787 of yacc.c */ +#line 2181 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (yylval.number) + yy_aconf->flags |= CONF_FLAGS_ENCRYPTED; + else + yy_aconf->flags &= ~CONF_FLAGS_ENCRYPTED; + } +} + break; + + case 381: +/* Line 1787 of yacc.c */ +#line 2192 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + char *mask; + + DupString(mask, yylval.string); + dlinkAdd(mask, make_dlink_node(), &yy_aconf->hub_list); + } +} + break; + + case 382: +/* Line 1787 of yacc.c */ +#line 2203 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + char *mask; + + DupString(mask, yylval.string); + dlinkAdd(mask, make_dlink_node(), &yy_aconf->leaf_list); + } +} + break; + + case 383: +/* Line 1787 of yacc.c */ +#line 2214 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(class_name); + DupString(class_name, yylval.string); + } +} + break; + + case 384: +/* Line 1787 of yacc.c */ +#line 2223 "conf_parser.y" + { +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2) + { + MyFree(yy_aconf->cipher_list); + DupString(yy_aconf->cipher_list, yylval.string); + } +#else + if (conf_parser_ctx.pass == 2) + yyerror("Ignoring connect::ciphers -- no OpenSSL support"); +#endif +} + break; + + case 385: +/* Line 1787 of yacc.c */ +#line 2241 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + userbuf[0] = hostbuf[0] = reasonbuf[0] = '\0'; + regex_ban = 0; + } +} + break; + + case 386: +/* Line 1787 of yacc.c */ +#line 2248 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (userbuf[0] && hostbuf[0]) + { + if (regex_ban) + { +#ifdef HAVE_LIBPCRE + void *exp_user = NULL; + void *exp_host = NULL; + const char *errptr = NULL; + + if (!(exp_user = ircd_pcre_compile(userbuf, &errptr)) || + !(exp_host = ircd_pcre_compile(hostbuf, &errptr))) + { + ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: %s", + errptr); + break; + } + + yy_aconf = map_to_conf(make_conf_item(RKLINE_TYPE)); + yy_aconf->regexuser = exp_user; + yy_aconf->regexhost = exp_host; + + DupString(yy_aconf->user, userbuf); + DupString(yy_aconf->host, hostbuf); + + if (reasonbuf[0]) + DupString(yy_aconf->reason, reasonbuf); + else + DupString(yy_aconf->reason, "No reason"); +#else + ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: no PCRE support"); + break; +#endif + } + else + { + find_and_delete_temporary(userbuf, hostbuf, CONF_KLINE); + + yy_aconf = map_to_conf(make_conf_item(KLINE_TYPE)); + + DupString(yy_aconf->user, userbuf); + DupString(yy_aconf->host, hostbuf); + + if (reasonbuf[0]) + DupString(yy_aconf->reason, reasonbuf); + else + DupString(yy_aconf->reason, "No reason"); + add_conf_by_address(CONF_KLINE, yy_aconf); + } + } + + yy_aconf = NULL; + } +} + break; + + case 387: +/* Line 1787 of yacc.c */ +#line 2306 "conf_parser.y" + { +} + break; + + case 391: +/* Line 1787 of yacc.c */ +#line 2311 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + regex_ban = 1; +} + break; + + case 398: +/* Line 1787 of yacc.c */ +#line 2320 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + struct split_nuh_item nuh; + + nuh.nuhmask = yylval.string; + nuh.nickptr = NULL; + nuh.userptr = userbuf; + nuh.hostptr = hostbuf; + + nuh.nicksize = 0; + nuh.usersize = sizeof(userbuf); + nuh.hostsize = sizeof(hostbuf); + + split_nuh(&nuh); + } +} + break; + + case 399: +/* Line 1787 of yacc.c */ +#line 2339 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf)); +} + break; + + case 400: +/* Line 1787 of yacc.c */ +#line 2348 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + hostbuf[0] = reasonbuf[0] = '\0'; +} + break; + + case 401: +/* Line 1787 of yacc.c */ +#line 2352 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (hostbuf[0] && parse_netmask(hostbuf, NULL, NULL) != HM_HOST) + { + find_and_delete_temporary(NULL, hostbuf, CONF_DLINE); + + yy_aconf = map_to_conf(make_conf_item(DLINE_TYPE)); + DupString(yy_aconf->host, hostbuf); + + if (reasonbuf[0]) + DupString(yy_aconf->reason, reasonbuf); + else + DupString(yy_aconf->reason, "No reason"); + add_conf_by_address(CONF_DLINE, yy_aconf); + yy_aconf = NULL; + } + } +} + break; + + case 407: +/* Line 1787 of yacc.c */ +#line 2376 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + strlcpy(hostbuf, yylval.string, sizeof(hostbuf)); +} + break; + + case 408: +/* Line 1787 of yacc.c */ +#line 2382 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf)); +} + break; + + case 414: +/* Line 1787 of yacc.c */ +#line 2396 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (yylval.string[0] && parse_netmask(yylval.string, NULL, NULL) != HM_HOST) + { + yy_aconf = map_to_conf(make_conf_item(EXEMPTDLINE_TYPE)); + DupString(yy_aconf->host, yylval.string); + + add_conf_by_address(CONF_EXEMPTDLINE, yy_aconf); + yy_aconf = NULL; + } + } +} + break; + + case 415: +/* Line 1787 of yacc.c */ +#line 2414 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + regex_ban = 0; + reasonbuf[0] = gecos_name[0] = '\0'; + } +} + break; + + case 416: +/* Line 1787 of yacc.c */ +#line 2421 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (gecos_name[0]) + { + if (regex_ban) + { +#ifdef HAVE_LIBPCRE + void *exp_p = NULL; + const char *errptr = NULL; + + if (!(exp_p = ircd_pcre_compile(gecos_name, &errptr))) + { + ilog(LOG_TYPE_IRCD, "Failed to add regular expression based X-Line: %s", + errptr); + break; + } + + yy_conf = make_conf_item(RXLINE_TYPE); + yy_conf->regexpname = exp_p; +#else + ilog(LOG_TYPE_IRCD, "Failed to add regular expression based X-Line: no PCRE support"); + break; +#endif + } + else + yy_conf = make_conf_item(XLINE_TYPE); + + yy_match_item = map_to_conf(yy_conf); + DupString(yy_conf->name, gecos_name); + + if (reasonbuf[0]) + DupString(yy_match_item->reason, reasonbuf); + else + DupString(yy_match_item->reason, "No reason"); + } + } +} + break; + + case 417: +/* Line 1787 of yacc.c */ +#line 2461 "conf_parser.y" + { +} + break; + + case 421: +/* Line 1787 of yacc.c */ +#line 2466 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + regex_ban = 1; +} + break; + + case 428: +/* Line 1787 of yacc.c */ +#line 2475 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + strlcpy(gecos_name, yylval.string, sizeof(gecos_name)); +} + break; + + case 429: +/* Line 1787 of yacc.c */ +#line 2481 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf)); +} + break; + + case 483: +/* Line 1787 of yacc.c */ +#line 2526 "conf_parser.y" + { + ConfigFileEntry.max_watch = (yyvsp[(3) - (4)].number); +} + break; + + case 484: +/* Line 1787 of yacc.c */ +#line 2531 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ConfigFileEntry.glines = yylval.number; +} + break; + + case 485: +/* Line 1787 of yacc.c */ +#line 2537 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ConfigFileEntry.gline_time = (yyvsp[(3) - (4)].number); +} + break; + + case 486: +/* Line 1787 of yacc.c */ +#line 2543 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ConfigFileEntry.gline_request_time = (yyvsp[(3) - (4)].number); +} + break; + + case 487: +/* Line 1787 of yacc.c */ +#line 2549 "conf_parser.y" + { + ConfigFileEntry.gline_min_cidr = (yyvsp[(3) - (4)].number); +} + break; + + case 488: +/* Line 1787 of yacc.c */ +#line 2554 "conf_parser.y" + { + ConfigFileEntry.gline_min_cidr6 = (yyvsp[(3) - (4)].number); +} + break; + + case 489: +/* Line 1787 of yacc.c */ +#line 2559 "conf_parser.y" + { + ConfigFileEntry.tkline_expire_notices = yylval.number; +} + break; + + case 490: +/* Line 1787 of yacc.c */ +#line 2564 "conf_parser.y" + { + ConfigFileEntry.kill_chase_time_limit = (yyvsp[(3) - (4)].number); +} + break; + + case 491: +/* Line 1787 of yacc.c */ +#line 2569 "conf_parser.y" + { + ConfigFileEntry.hide_spoof_ips = yylval.number; +} + break; + + case 492: +/* Line 1787 of yacc.c */ +#line 2574 "conf_parser.y" + { + ConfigFileEntry.ignore_bogus_ts = yylval.number; +} + break; + + case 493: +/* Line 1787 of yacc.c */ +#line 2579 "conf_parser.y" + { + ConfigFileEntry.disable_remote = yylval.number; +} + break; + + case 494: +/* Line 1787 of yacc.c */ +#line 2584 "conf_parser.y" + { + ConfigFileEntry.failed_oper_notice = yylval.number; +} + break; + + case 495: +/* Line 1787 of yacc.c */ +#line 2589 "conf_parser.y" + { + ConfigFileEntry.anti_nick_flood = yylval.number; +} + break; + + case 496: +/* Line 1787 of yacc.c */ +#line 2594 "conf_parser.y" + { + ConfigFileEntry.max_nick_time = (yyvsp[(3) - (4)].number); +} + break; + + case 497: +/* Line 1787 of yacc.c */ +#line 2599 "conf_parser.y" + { + ConfigFileEntry.max_nick_changes = (yyvsp[(3) - (4)].number); +} + break; + + case 498: +/* Line 1787 of yacc.c */ +#line 2604 "conf_parser.y" + { + ConfigFileEntry.max_accept = (yyvsp[(3) - (4)].number); +} + break; + + case 499: +/* Line 1787 of yacc.c */ +#line 2609 "conf_parser.y" + { + ConfigFileEntry.anti_spam_exit_message_time = (yyvsp[(3) - (4)].number); +} + break; + + case 500: +/* Line 1787 of yacc.c */ +#line 2614 "conf_parser.y" + { + ConfigFileEntry.ts_warn_delta = (yyvsp[(3) - (4)].number); +} + break; + + case 501: +/* Line 1787 of yacc.c */ +#line 2619 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ConfigFileEntry.ts_max_delta = (yyvsp[(3) - (4)].number); +} + break; + + case 502: +/* Line 1787 of yacc.c */ +#line 2625 "conf_parser.y" + { + if (((yyvsp[(3) - (4)].number) > 0) && conf_parser_ctx.pass == 1) + { + ilog(LOG_TYPE_IRCD, "You haven't read your config file properly."); + ilog(LOG_TYPE_IRCD, "There is a line in the example conf that will kill your server if not removed."); + ilog(LOG_TYPE_IRCD, "Consider actually reading/editing the conf file, and removing this line."); + exit(0); + } +} + break; + + case 503: +/* Line 1787 of yacc.c */ +#line 2636 "conf_parser.y" + { + ConfigFileEntry.invisible_on_connect = yylval.number; +} + break; + + case 504: +/* Line 1787 of yacc.c */ +#line 2641 "conf_parser.y" + { + ConfigFileEntry.warn_no_nline = yylval.number; +} + break; + + case 505: +/* Line 1787 of yacc.c */ +#line 2646 "conf_parser.y" + { + ConfigFileEntry.stats_e_disabled = yylval.number; +} + break; + + case 506: +/* Line 1787 of yacc.c */ +#line 2651 "conf_parser.y" + { + ConfigFileEntry.stats_o_oper_only = yylval.number; +} + break; + + case 507: +/* Line 1787 of yacc.c */ +#line 2656 "conf_parser.y" + { + ConfigFileEntry.stats_P_oper_only = yylval.number; +} + break; + + case 508: +/* Line 1787 of yacc.c */ +#line 2661 "conf_parser.y" + { + ConfigFileEntry.stats_k_oper_only = 2 * yylval.number; +} + break; + + case 509: +/* Line 1787 of yacc.c */ +#line 2664 "conf_parser.y" + { + ConfigFileEntry.stats_k_oper_only = 1; +} + break; + + case 510: +/* Line 1787 of yacc.c */ +#line 2669 "conf_parser.y" + { + ConfigFileEntry.stats_i_oper_only = 2 * yylval.number; +} + break; + + case 511: +/* Line 1787 of yacc.c */ +#line 2672 "conf_parser.y" + { + ConfigFileEntry.stats_i_oper_only = 1; +} + break; + + case 512: +/* Line 1787 of yacc.c */ +#line 2677 "conf_parser.y" + { + ConfigFileEntry.pace_wait = (yyvsp[(3) - (4)].number); +} + break; + + case 513: +/* Line 1787 of yacc.c */ +#line 2682 "conf_parser.y" + { + ConfigFileEntry.caller_id_wait = (yyvsp[(3) - (4)].number); +} + break; + + case 514: +/* Line 1787 of yacc.c */ +#line 2687 "conf_parser.y" + { + ConfigFileEntry.opers_bypass_callerid = yylval.number; +} + break; + + case 515: +/* Line 1787 of yacc.c */ +#line 2692 "conf_parser.y" + { + ConfigFileEntry.pace_wait_simple = (yyvsp[(3) - (4)].number); +} + break; + + case 516: +/* Line 1787 of yacc.c */ +#line 2697 "conf_parser.y" + { + ConfigFileEntry.short_motd = yylval.number; +} + break; + + case 517: +/* Line 1787 of yacc.c */ +#line 2702 "conf_parser.y" + { + ConfigFileEntry.no_oper_flood = yylval.number; +} + break; + + case 518: +/* Line 1787 of yacc.c */ +#line 2707 "conf_parser.y" + { + ConfigFileEntry.true_no_oper_flood = yylval.number; +} + break; + + case 519: +/* Line 1787 of yacc.c */ +#line 2712 "conf_parser.y" + { + ConfigFileEntry.oper_pass_resv = yylval.number; +} + break; + + case 520: +/* Line 1787 of yacc.c */ +#line 2717 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (strlen(yylval.string) > LOCALE_LENGTH-2) + yylval.string[LOCALE_LENGTH-1] = '\0'; + + set_locale(yylval.string); + } +} + break; + + case 521: +/* Line 1787 of yacc.c */ +#line 2728 "conf_parser.y" + { + ConfigFileEntry.dots_in_ident = (yyvsp[(3) - (4)].number); +} + break; + + case 522: +/* Line 1787 of yacc.c */ +#line 2733 "conf_parser.y" + { + ConfigFileEntry.max_targets = (yyvsp[(3) - (4)].number); +} + break; + + case 523: +/* Line 1787 of yacc.c */ +#line 2738 "conf_parser.y" + { + ConfigFileEntry.use_egd = yylval.number; +} + break; + + case 524: +/* Line 1787 of yacc.c */ +#line 2743 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(ConfigFileEntry.egdpool_path); + DupString(ConfigFileEntry.egdpool_path, yylval.string); + } +} + break; + + case 525: +/* Line 1787 of yacc.c */ +#line 2752 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2 && valid_servname(yylval.string)) + { + MyFree(ConfigFileEntry.service_name); + DupString(ConfigFileEntry.service_name, yylval.string); + } +} + break; + + case 526: +/* Line 1787 of yacc.c */ +#line 2761 "conf_parser.y" + { + ConfigFileEntry.ping_cookie = yylval.number; +} + break; + + case 527: +/* Line 1787 of yacc.c */ +#line 2766 "conf_parser.y" + { + ConfigFileEntry.disable_auth = yylval.number; +} + break; + + case 528: +/* Line 1787 of yacc.c */ +#line 2771 "conf_parser.y" + { + ConfigFileEntry.throttle_time = yylval.number; +} + break; + + case 529: +/* Line 1787 of yacc.c */ +#line 2776 "conf_parser.y" + { + ConfigFileEntry.oper_umodes = 0; +} + break; + + case 533: +/* Line 1787 of yacc.c */ +#line 2782 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_BOTS; +} + break; + + case 534: +/* Line 1787 of yacc.c */ +#line 2785 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_CCONN; +} + break; + + case 535: +/* Line 1787 of yacc.c */ +#line 2788 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_CCONN_FULL; +} + break; + + case 536: +/* Line 1787 of yacc.c */ +#line 2791 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_DEAF; +} + break; + + case 537: +/* Line 1787 of yacc.c */ +#line 2794 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_DEBUG; +} + break; + + case 538: +/* Line 1787 of yacc.c */ +#line 2797 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_FULL; +} + break; + + case 539: +/* Line 1787 of yacc.c */ +#line 2800 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_HIDDEN; +} + break; + + case 540: +/* Line 1787 of yacc.c */ +#line 2803 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_SKILL; +} + break; + + case 541: +/* Line 1787 of yacc.c */ +#line 2806 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_NCHANGE; +} + break; + + case 542: +/* Line 1787 of yacc.c */ +#line 2809 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_REJ; +} + break; + + case 543: +/* Line 1787 of yacc.c */ +#line 2812 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_UNAUTH; +} + break; + + case 544: +/* Line 1787 of yacc.c */ +#line 2815 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_SPY; +} + break; + + case 545: +/* Line 1787 of yacc.c */ +#line 2818 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_EXTERNAL; +} + break; + + case 546: +/* Line 1787 of yacc.c */ +#line 2821 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_OPERWALL; +} + break; + + case 547: +/* Line 1787 of yacc.c */ +#line 2824 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_SERVNOTICE; +} + break; + + case 548: +/* Line 1787 of yacc.c */ +#line 2827 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_INVISIBLE; +} + break; + + case 549: +/* Line 1787 of yacc.c */ +#line 2830 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_WALLOP; +} + break; + + case 550: +/* Line 1787 of yacc.c */ +#line 2833 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_SOFTCALLERID; +} + break; + + case 551: +/* Line 1787 of yacc.c */ +#line 2836 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_CALLERID; +} + break; + + case 552: +/* Line 1787 of yacc.c */ +#line 2839 "conf_parser.y" + { + ConfigFileEntry.oper_umodes |= UMODE_LOCOPS; +} + break; + + case 553: +/* Line 1787 of yacc.c */ +#line 2844 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes = 0; +} + break; + + case 557: +/* Line 1787 of yacc.c */ +#line 2850 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_BOTS; +} + break; + + case 558: +/* Line 1787 of yacc.c */ +#line 2853 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_CCONN; +} + break; + + case 559: +/* Line 1787 of yacc.c */ +#line 2856 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_CCONN_FULL; +} + break; + + case 560: +/* Line 1787 of yacc.c */ +#line 2859 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_DEAF; +} + break; + + case 561: +/* Line 1787 of yacc.c */ +#line 2862 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_DEBUG; +} + break; + + case 562: +/* Line 1787 of yacc.c */ +#line 2865 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_FULL; +} + break; + + case 563: +/* Line 1787 of yacc.c */ +#line 2868 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_SKILL; +} + break; + + case 564: +/* Line 1787 of yacc.c */ +#line 2871 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_HIDDEN; +} + break; + + case 565: +/* Line 1787 of yacc.c */ +#line 2874 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_NCHANGE; +} + break; + + case 566: +/* Line 1787 of yacc.c */ +#line 2877 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_REJ; +} + break; + + case 567: +/* Line 1787 of yacc.c */ +#line 2880 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_UNAUTH; +} + break; + + case 568: +/* Line 1787 of yacc.c */ +#line 2883 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_SPY; +} + break; + + case 569: +/* Line 1787 of yacc.c */ +#line 2886 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_EXTERNAL; +} + break; + + case 570: +/* Line 1787 of yacc.c */ +#line 2889 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_OPERWALL; +} + break; + + case 571: +/* Line 1787 of yacc.c */ +#line 2892 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_SERVNOTICE; +} + break; + + case 572: +/* Line 1787 of yacc.c */ +#line 2895 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_INVISIBLE; +} + break; + + case 573: +/* Line 1787 of yacc.c */ +#line 2898 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_WALLOP; +} + break; + + case 574: +/* Line 1787 of yacc.c */ +#line 2901 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_SOFTCALLERID; +} + break; + + case 575: +/* Line 1787 of yacc.c */ +#line 2904 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_CALLERID; +} + break; + + case 576: +/* Line 1787 of yacc.c */ +#line 2907 "conf_parser.y" + { + ConfigFileEntry.oper_only_umodes |= UMODE_LOCOPS; +} + break; + + case 577: +/* Line 1787 of yacc.c */ +#line 2912 "conf_parser.y" + { + ConfigFileEntry.min_nonwildcard = (yyvsp[(3) - (4)].number); +} + break; + + case 578: +/* Line 1787 of yacc.c */ +#line 2917 "conf_parser.y" + { + ConfigFileEntry.min_nonwildcard_simple = (yyvsp[(3) - (4)].number); +} + break; + + case 579: +/* Line 1787 of yacc.c */ +#line 2922 "conf_parser.y" + { + ConfigFileEntry.default_floodcount = (yyvsp[(3) - (4)].number); +} + break; + + case 598: +/* Line 1787 of yacc.c */ +#line 2945 "conf_parser.y" + { + ConfigChannel.disable_fake_channels = yylval.number; +} + break; + + case 599: +/* Line 1787 of yacc.c */ +#line 2950 "conf_parser.y" + { + ConfigChannel.restrict_channels = yylval.number; +} + break; + + case 600: +/* Line 1787 of yacc.c */ +#line 2955 "conf_parser.y" + { + ConfigChannel.knock_delay = (yyvsp[(3) - (4)].number); +} + break; + + case 601: +/* Line 1787 of yacc.c */ +#line 2960 "conf_parser.y" + { + ConfigChannel.knock_delay_channel = (yyvsp[(3) - (4)].number); +} + break; + + case 602: +/* Line 1787 of yacc.c */ +#line 2965 "conf_parser.y" + { + ConfigChannel.max_chans_per_user = (yyvsp[(3) - (4)].number); +} + break; + + case 603: +/* Line 1787 of yacc.c */ +#line 2970 "conf_parser.y" + { + ConfigChannel.max_chans_per_oper = (yyvsp[(3) - (4)].number); +} + break; + + case 604: +/* Line 1787 of yacc.c */ +#line 2975 "conf_parser.y" + { + ConfigChannel.quiet_on_ban = yylval.number; +} + break; + + case 605: +/* Line 1787 of yacc.c */ +#line 2980 "conf_parser.y" + { + ConfigChannel.max_bans = (yyvsp[(3) - (4)].number); +} + break; + + case 606: +/* Line 1787 of yacc.c */ +#line 2985 "conf_parser.y" + { + ConfigChannel.default_split_user_count = (yyvsp[(3) - (4)].number); +} + break; + + case 607: +/* Line 1787 of yacc.c */ +#line 2990 "conf_parser.y" + { + ConfigChannel.default_split_server_count = (yyvsp[(3) - (4)].number); +} + break; + + case 608: +/* Line 1787 of yacc.c */ +#line 2995 "conf_parser.y" + { + ConfigChannel.no_create_on_split = yylval.number; +} + break; + + case 609: +/* Line 1787 of yacc.c */ +#line 3000 "conf_parser.y" + { + ConfigChannel.no_join_on_split = yylval.number; +} + break; + + case 610: +/* Line 1787 of yacc.c */ +#line 3005 "conf_parser.y" + { + GlobalSetOptions.joinfloodcount = yylval.number; +} + break; + + case 611: +/* Line 1787 of yacc.c */ +#line 3010 "conf_parser.y" + { + GlobalSetOptions.joinfloodtime = yylval.number; +} + break; + + case 622: +/* Line 1787 of yacc.c */ +#line 3028 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ConfigServerHide.flatten_links = yylval.number; +} + break; + + case 623: +/* Line 1787 of yacc.c */ +#line 3034 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ConfigServerHide.hide_servers = yylval.number; +} + break; + + case 624: +/* Line 1787 of yacc.c */ +#line 3040 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + MyFree(ConfigServerHide.hidden_name); + DupString(ConfigServerHide.hidden_name, yylval.string); + } +} + break; + + case 625: +/* Line 1787 of yacc.c */ +#line 3049 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + { + if (((yyvsp[(3) - (4)].number) > 0) && ConfigServerHide.links_disabled == 1) + { + eventAddIsh("write_links_file", write_links_file, NULL, (yyvsp[(3) - (4)].number)); + ConfigServerHide.links_disabled = 0; + } + + ConfigServerHide.links_delay = (yyvsp[(3) - (4)].number); + } +} + break; + + case 626: +/* Line 1787 of yacc.c */ +#line 3063 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ConfigServerHide.hidden = yylval.number; +} + break; + + case 627: +/* Line 1787 of yacc.c */ +#line 3069 "conf_parser.y" + { + if (conf_parser_ctx.pass == 2) + ConfigServerHide.hide_server_ips = yylval.number; +} + break; + + +/* Line 1787 of yacc.c */ +#line 6844 "conf_parser.c" + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + diff --git a/src/conf_parser.h b/src/conf_parser.h new file mode 100644 index 0000000..89bb943 --- /dev/null +++ b/src/conf_parser.h @@ -0,0 +1,513 @@ +/* A Bison parser, made by GNU Bison 2.6.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef YY_Y_TAB_H +# define YY_Y_TAB_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ACCEPT_PASSWORD = 258, + ADMIN = 259, + AFTYPE = 260, + ANTI_NICK_FLOOD = 261, + ANTI_SPAM_EXIT_MESSAGE_TIME = 262, + AUTOCONN = 263, + BYTES = 264, + KBYTES = 265, + MBYTES = 266, + CALLER_ID_WAIT = 267, + CAN_FLOOD = 268, + CHANNEL = 269, + CIDR_BITLEN_IPV4 = 270, + CIDR_BITLEN_IPV6 = 271, + CLASS = 272, + CONNECT = 273, + CONNECTFREQ = 274, + DEFAULT_FLOODCOUNT = 275, + DEFAULT_SPLIT_SERVER_COUNT = 276, + DEFAULT_SPLIT_USER_COUNT = 277, + DENY = 278, + DESCRIPTION = 279, + DIE = 280, + DISABLE_AUTH = 281, + DISABLE_FAKE_CHANNELS = 282, + DISABLE_REMOTE_COMMANDS = 283, + DOTS_IN_IDENT = 284, + EGDPOOL_PATH = 285, + EMAIL = 286, + ENCRYPTED = 287, + EXCEED_LIMIT = 288, + EXEMPT = 289, + FAILED_OPER_NOTICE = 290, + IRCD_FLAGS = 291, + FLATTEN_LINKS = 292, + GECOS = 293, + GENERAL = 294, + GLINE = 295, + GLINE_DURATION = 296, + GLINE_ENABLE = 297, + GLINE_EXEMPT = 298, + GLINE_REQUEST_DURATION = 299, + GLINE_MIN_CIDR = 300, + GLINE_MIN_CIDR6 = 301, + GLOBAL_KILL = 302, + IRCD_AUTH = 303, + NEED_IDENT = 304, + HAVENT_READ_CONF = 305, + HIDDEN = 306, + HIDDEN_NAME = 307, + HIDE_SERVER_IPS = 308, + HIDE_SERVERS = 309, + HIDE_SPOOF_IPS = 310, + HOST = 311, + HUB = 312, + HUB_MASK = 313, + IGNORE_BOGUS_TS = 314, + INVISIBLE_ON_CONNECT = 315, + IP = 316, + KILL = 317, + KILL_CHASE_TIME_LIMIT = 318, + KLINE = 319, + KLINE_EXEMPT = 320, + KNOCK_DELAY = 321, + KNOCK_DELAY_CHANNEL = 322, + LEAF_MASK = 323, + LINKS_DELAY = 324, + LISTEN = 325, + T_LOG = 326, + MAX_ACCEPT = 327, + MAX_BANS = 328, + MAX_CHANS_PER_OPER = 329, + MAX_CHANS_PER_USER = 330, + MAX_GLOBAL = 331, + MAX_IDENT = 332, + MAX_LOCAL = 333, + MAX_NICK_CHANGES = 334, + MAX_NICK_TIME = 335, + MAX_NUMBER = 336, + MAX_TARGETS = 337, + MAX_WATCH = 338, + MESSAGE_LOCALE = 339, + MIN_NONWILDCARD = 340, + MIN_NONWILDCARD_SIMPLE = 341, + MODULE = 342, + MODULES = 343, + NAME = 344, + NEED_PASSWORD = 345, + NETWORK_DESC = 346, + NETWORK_NAME = 347, + NICK = 348, + NICK_CHANGES = 349, + NO_CREATE_ON_SPLIT = 350, + NO_JOIN_ON_SPLIT = 351, + NO_OPER_FLOOD = 352, + NO_TILDE = 353, + NUMBER = 354, + NUMBER_PER_CIDR = 355, + NUMBER_PER_IP = 356, + OPERATOR = 357, + OPERS_BYPASS_CALLERID = 358, + OPER_ONLY_UMODES = 359, + OPER_PASS_RESV = 360, + OPER_SPY_T = 361, + OPER_UMODES = 362, + JOIN_FLOOD_COUNT = 363, + JOIN_FLOOD_TIME = 364, + PACE_WAIT = 365, + PACE_WAIT_SIMPLE = 366, + PASSWORD = 367, + PATH = 368, + PING_COOKIE = 369, + PING_TIME = 370, + PING_WARNING = 371, + PORT = 372, + QSTRING = 373, + QUIET_ON_BAN = 374, + REASON = 375, + REDIRPORT = 376, + REDIRSERV = 377, + REGEX_T = 378, + REHASH = 379, + REMOTE = 380, + REMOTEBAN = 381, + RESTRICT_CHANNELS = 382, + RSA_PRIVATE_KEY_FILE = 383, + RSA_PUBLIC_KEY_FILE = 384, + SSL_CERTIFICATE_FILE = 385, + SSL_DH_PARAM_FILE = 386, + T_SSL_CLIENT_METHOD = 387, + T_SSL_SERVER_METHOD = 388, + T_SSLV3 = 389, + T_TLSV1 = 390, + RESV = 391, + RESV_EXEMPT = 392, + SECONDS = 393, + MINUTES = 394, + HOURS = 395, + DAYS = 396, + WEEKS = 397, + SENDQ = 398, + SEND_PASSWORD = 399, + SERVERHIDE = 400, + SERVERINFO = 401, + IRCD_SID = 402, + TKLINE_EXPIRE_NOTICES = 403, + T_SHARED = 404, + T_CLUSTER = 405, + TYPE = 406, + SHORT_MOTD = 407, + SPOOF = 408, + SPOOF_NOTICE = 409, + STATS_E_DISABLED = 410, + STATS_I_OPER_ONLY = 411, + STATS_K_OPER_ONLY = 412, + STATS_O_OPER_ONLY = 413, + STATS_P_OPER_ONLY = 414, + TBOOL = 415, + TMASKED = 416, + TS_MAX_DELTA = 417, + TS_WARN_DELTA = 418, + TWODOTS = 419, + T_ALL = 420, + T_BOTS = 421, + T_SOFTCALLERID = 422, + T_CALLERID = 423, + T_CCONN = 424, + T_CCONN_FULL = 425, + T_SSL_CIPHER_LIST = 426, + T_DEAF = 427, + T_DEBUG = 428, + T_DLINE = 429, + T_EXTERNAL = 430, + T_FULL = 431, + T_INVISIBLE = 432, + T_IPV4 = 433, + T_IPV6 = 434, + T_LOCOPS = 435, + T_MAX_CLIENTS = 436, + T_NCHANGE = 437, + T_OPERWALL = 438, + T_RECVQ = 439, + T_REJ = 440, + T_SERVER = 441, + T_SERVNOTICE = 442, + T_SET = 443, + T_SKILL = 444, + T_SPY = 445, + T_SSL = 446, + T_UMODES = 447, + T_UNAUTH = 448, + T_UNDLINE = 449, + T_UNLIMITED = 450, + T_UNRESV = 451, + T_UNXLINE = 452, + T_GLOBOPS = 453, + T_WALLOP = 454, + T_RESTART = 455, + T_SERVICE = 456, + T_SERVICES_NAME = 457, + THROTTLE_TIME = 458, + TRUE_NO_OPER_FLOOD = 459, + UNKLINE = 460, + USER = 461, + USE_EGD = 462, + USE_LOGGING = 463, + VHOST = 464, + VHOST6 = 465, + XLINE = 466, + WARN_NO_NLINE = 467, + T_SIZE = 468, + T_FILE = 469 + }; +#endif +/* Tokens. */ +#define ACCEPT_PASSWORD 258 +#define ADMIN 259 +#define AFTYPE 260 +#define ANTI_NICK_FLOOD 261 +#define ANTI_SPAM_EXIT_MESSAGE_TIME 262 +#define AUTOCONN 263 +#define BYTES 264 +#define KBYTES 265 +#define MBYTES 266 +#define CALLER_ID_WAIT 267 +#define CAN_FLOOD 268 +#define CHANNEL 269 +#define CIDR_BITLEN_IPV4 270 +#define CIDR_BITLEN_IPV6 271 +#define CLASS 272 +#define CONNECT 273 +#define CONNECTFREQ 274 +#define DEFAULT_FLOODCOUNT 275 +#define DEFAULT_SPLIT_SERVER_COUNT 276 +#define DEFAULT_SPLIT_USER_COUNT 277 +#define DENY 278 +#define DESCRIPTION 279 +#define DIE 280 +#define DISABLE_AUTH 281 +#define DISABLE_FAKE_CHANNELS 282 +#define DISABLE_REMOTE_COMMANDS 283 +#define DOTS_IN_IDENT 284 +#define EGDPOOL_PATH 285 +#define EMAIL 286 +#define ENCRYPTED 287 +#define EXCEED_LIMIT 288 +#define EXEMPT 289 +#define FAILED_OPER_NOTICE 290 +#define IRCD_FLAGS 291 +#define FLATTEN_LINKS 292 +#define GECOS 293 +#define GENERAL 294 +#define GLINE 295 +#define GLINE_DURATION 296 +#define GLINE_ENABLE 297 +#define GLINE_EXEMPT 298 +#define GLINE_REQUEST_DURATION 299 +#define GLINE_MIN_CIDR 300 +#define GLINE_MIN_CIDR6 301 +#define GLOBAL_KILL 302 +#define IRCD_AUTH 303 +#define NEED_IDENT 304 +#define HAVENT_READ_CONF 305 +#define HIDDEN 306 +#define HIDDEN_NAME 307 +#define HIDE_SERVER_IPS 308 +#define HIDE_SERVERS 309 +#define HIDE_SPOOF_IPS 310 +#define HOST 311 +#define HUB 312 +#define HUB_MASK 313 +#define IGNORE_BOGUS_TS 314 +#define INVISIBLE_ON_CONNECT 315 +#define IP 316 +#define KILL 317 +#define KILL_CHASE_TIME_LIMIT 318 +#define KLINE 319 +#define KLINE_EXEMPT 320 +#define KNOCK_DELAY 321 +#define KNOCK_DELAY_CHANNEL 322 +#define LEAF_MASK 323 +#define LINKS_DELAY 324 +#define LISTEN 325 +#define T_LOG 326 +#define MAX_ACCEPT 327 +#define MAX_BANS 328 +#define MAX_CHANS_PER_OPER 329 +#define MAX_CHANS_PER_USER 330 +#define MAX_GLOBAL 331 +#define MAX_IDENT 332 +#define MAX_LOCAL 333 +#define MAX_NICK_CHANGES 334 +#define MAX_NICK_TIME 335 +#define MAX_NUMBER 336 +#define MAX_TARGETS 337 +#define MAX_WATCH 338 +#define MESSAGE_LOCALE 339 +#define MIN_NONWILDCARD 340 +#define MIN_NONWILDCARD_SIMPLE 341 +#define MODULE 342 +#define MODULES 343 +#define NAME 344 +#define NEED_PASSWORD 345 +#define NETWORK_DESC 346 +#define NETWORK_NAME 347 +#define NICK 348 +#define NICK_CHANGES 349 +#define NO_CREATE_ON_SPLIT 350 +#define NO_JOIN_ON_SPLIT 351 +#define NO_OPER_FLOOD 352 +#define NO_TILDE 353 +#define NUMBER 354 +#define NUMBER_PER_CIDR 355 +#define NUMBER_PER_IP 356 +#define OPERATOR 357 +#define OPERS_BYPASS_CALLERID 358 +#define OPER_ONLY_UMODES 359 +#define OPER_PASS_RESV 360 +#define OPER_SPY_T 361 +#define OPER_UMODES 362 +#define JOIN_FLOOD_COUNT 363 +#define JOIN_FLOOD_TIME 364 +#define PACE_WAIT 365 +#define PACE_WAIT_SIMPLE 366 +#define PASSWORD 367 +#define PATH 368 +#define PING_COOKIE 369 +#define PING_TIME 370 +#define PING_WARNING 371 +#define PORT 372 +#define QSTRING 373 +#define QUIET_ON_BAN 374 +#define REASON 375 +#define REDIRPORT 376 +#define REDIRSERV 377 +#define REGEX_T 378 +#define REHASH 379 +#define REMOTE 380 +#define REMOTEBAN 381 +#define RESTRICT_CHANNELS 382 +#define RSA_PRIVATE_KEY_FILE 383 +#define RSA_PUBLIC_KEY_FILE 384 +#define SSL_CERTIFICATE_FILE 385 +#define SSL_DH_PARAM_FILE 386 +#define T_SSL_CLIENT_METHOD 387 +#define T_SSL_SERVER_METHOD 388 +#define T_SSLV3 389 +#define T_TLSV1 390 +#define RESV 391 +#define RESV_EXEMPT 392 +#define SECONDS 393 +#define MINUTES 394 +#define HOURS 395 +#define DAYS 396 +#define WEEKS 397 +#define SENDQ 398 +#define SEND_PASSWORD 399 +#define SERVERHIDE 400 +#define SERVERINFO 401 +#define IRCD_SID 402 +#define TKLINE_EXPIRE_NOTICES 403 +#define T_SHARED 404 +#define T_CLUSTER 405 +#define TYPE 406 +#define SHORT_MOTD 407 +#define SPOOF 408 +#define SPOOF_NOTICE 409 +#define STATS_E_DISABLED 410 +#define STATS_I_OPER_ONLY 411 +#define STATS_K_OPER_ONLY 412 +#define STATS_O_OPER_ONLY 413 +#define STATS_P_OPER_ONLY 414 +#define TBOOL 415 +#define TMASKED 416 +#define TS_MAX_DELTA 417 +#define TS_WARN_DELTA 418 +#define TWODOTS 419 +#define T_ALL 420 +#define T_BOTS 421 +#define T_SOFTCALLERID 422 +#define T_CALLERID 423 +#define T_CCONN 424 +#define T_CCONN_FULL 425 +#define T_SSL_CIPHER_LIST 426 +#define T_DEAF 427 +#define T_DEBUG 428 +#define T_DLINE 429 +#define T_EXTERNAL 430 +#define T_FULL 431 +#define T_INVISIBLE 432 +#define T_IPV4 433 +#define T_IPV6 434 +#define T_LOCOPS 435 +#define T_MAX_CLIENTS 436 +#define T_NCHANGE 437 +#define T_OPERWALL 438 +#define T_RECVQ 439 +#define T_REJ 440 +#define T_SERVER 441 +#define T_SERVNOTICE 442 +#define T_SET 443 +#define T_SKILL 444 +#define T_SPY 445 +#define T_SSL 446 +#define T_UMODES 447 +#define T_UNAUTH 448 +#define T_UNDLINE 449 +#define T_UNLIMITED 450 +#define T_UNRESV 451 +#define T_UNXLINE 452 +#define T_GLOBOPS 453 +#define T_WALLOP 454 +#define T_RESTART 455 +#define T_SERVICE 456 +#define T_SERVICES_NAME 457 +#define THROTTLE_TIME 458 +#define TRUE_NO_OPER_FLOOD 459 +#define UNKLINE 460 +#define USER 461 +#define USE_EGD 462 +#define USE_LOGGING 463 +#define VHOST 464 +#define VHOST6 465 +#define XLINE 466 +#define WARN_NO_NLINE 467 +#define T_SIZE 468 +#define T_FILE 469 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 2049 of yacc.c */ +#line 110 "conf_parser.y" + + int number; + char *string; + + +/* Line 2049 of yacc.c */ +#line 491 "conf_parser.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE yylval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !YY_Y_TAB_H */ diff --git a/src/conf_parser.y b/src/conf_parser.y new file mode 100644 index 0000000..1e5096b --- /dev/null +++ b/src/conf_parser.y @@ -0,0 +1,3072 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * conf_parser.y: Parses the ircd configuration file. + * + * Copyright (C) 2005 by the past and present ircd coders, and others. + * + * 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$ + */ + +%{ + +#define YY_NO_UNPUT +#include <sys/types.h> +#include <string.h> + +#include "config.h" +#include "stdinc.h" +#include "ircd.h" +#include "list.h" +#include "conf.h" +#include "event.h" +#include "log.h" +#include "client.h" /* for UMODE_ALL only */ +#include "irc_string.h" +#include "sprintf_irc.h" +#include "memory.h" +#include "modules.h" +#include "s_serv.h" +#include "hostmask.h" +#include "send.h" +#include "listener.h" +#include "resv.h" +#include "numeric.h" +#include "s_user.h" + +#ifdef HAVE_LIBCRYPTO +#include <openssl/rsa.h> +#include <openssl/bio.h> +#include <openssl/pem.h> +#include <openssl/dh.h> +#endif + +int yylex(void); + +static char *class_name = NULL; +static struct ConfItem *yy_conf = NULL; +static struct AccessItem *yy_aconf = NULL; +static struct MatchItem *yy_match_item = NULL; +static struct ClassItem *yy_class = NULL; +static char *yy_class_name = NULL; + +static dlink_list col_conf_list = { NULL, NULL, 0 }; +static unsigned int listener_flags = 0; +static unsigned int regex_ban = 0; +static char userbuf[IRCD_BUFSIZE]; +static char hostbuf[IRCD_BUFSIZE]; +static char reasonbuf[REASONLEN + 1]; +static char gecos_name[REALLEN * 4]; +static char lfile[IRCD_BUFSIZE]; +static unsigned int ltype = 0; +static unsigned int lsize = 0; +static char *resv_reason = NULL; +static char *listener_address = NULL; + +struct CollectItem +{ + dlink_node node; + char *name; + char *user; + char *host; + char *passwd; + int port; + int flags; +#ifdef HAVE_LIBCRYPTO + char *rsa_public_key_file; + RSA *rsa_public_key; +#endif +}; + +static void +free_collect_item(struct CollectItem *item) +{ + MyFree(item->name); + MyFree(item->user); + MyFree(item->host); + MyFree(item->passwd); +#ifdef HAVE_LIBCRYPTO + MyFree(item->rsa_public_key_file); +#endif + MyFree(item); +} + +%} + +%union { + int number; + char *string; +} + +%token ACCEPT_PASSWORD +%token ADMIN +%token AFTYPE +%token ANTI_NICK_FLOOD +%token ANTI_SPAM_EXIT_MESSAGE_TIME +%token AUTOCONN +%token BYTES KBYTES MBYTES +%token CALLER_ID_WAIT +%token CAN_FLOOD +%token CHANNEL +%token CIDR_BITLEN_IPV4 +%token CIDR_BITLEN_IPV6 +%token CLASS +%token CONNECT +%token CONNECTFREQ +%token DEFAULT_FLOODCOUNT +%token DEFAULT_SPLIT_SERVER_COUNT +%token DEFAULT_SPLIT_USER_COUNT +%token DENY +%token DESCRIPTION +%token DIE +%token DISABLE_AUTH +%token DISABLE_FAKE_CHANNELS +%token DISABLE_REMOTE_COMMANDS +%token DOTS_IN_IDENT +%token EGDPOOL_PATH +%token EMAIL +%token ENCRYPTED +%token EXCEED_LIMIT +%token EXEMPT +%token FAILED_OPER_NOTICE +%token IRCD_FLAGS +%token FLATTEN_LINKS +%token GECOS +%token GENERAL +%token GLINE +%token GLINE_DURATION +%token GLINE_ENABLE +%token GLINE_EXEMPT +%token GLINE_REQUEST_DURATION +%token GLINE_MIN_CIDR +%token GLINE_MIN_CIDR6 +%token GLOBAL_KILL +%token IRCD_AUTH +%token NEED_IDENT +%token HAVENT_READ_CONF +%token HIDDEN +%token HIDDEN_NAME +%token HIDE_SERVER_IPS +%token HIDE_SERVERS +%token HIDE_SPOOF_IPS +%token HOST +%token HUB +%token HUB_MASK +%token IGNORE_BOGUS_TS +%token INVISIBLE_ON_CONNECT +%token IP +%token KILL +%token KILL_CHASE_TIME_LIMIT +%token KLINE +%token KLINE_EXEMPT +%token KNOCK_DELAY +%token KNOCK_DELAY_CHANNEL +%token LEAF_MASK +%token LINKS_DELAY +%token LISTEN +%token T_LOG +%token MAX_ACCEPT +%token MAX_BANS +%token MAX_CHANS_PER_OPER +%token MAX_CHANS_PER_USER +%token MAX_GLOBAL +%token MAX_IDENT +%token MAX_LOCAL +%token MAX_NICK_CHANGES +%token MAX_NICK_TIME +%token MAX_NUMBER +%token MAX_TARGETS +%token MAX_WATCH +%token MESSAGE_LOCALE +%token MIN_NONWILDCARD +%token MIN_NONWILDCARD_SIMPLE +%token MODULE +%token MODULES +%token NAME +%token NEED_PASSWORD +%token NETWORK_DESC +%token NETWORK_NAME +%token NICK +%token NICK_CHANGES +%token NO_CREATE_ON_SPLIT +%token NO_JOIN_ON_SPLIT +%token NO_OPER_FLOOD +%token NO_TILDE +%token NUMBER +%token NUMBER_PER_CIDR +%token NUMBER_PER_IP +%token OPERATOR +%token OPERS_BYPASS_CALLERID +%token OPER_ONLY_UMODES +%token OPER_PASS_RESV +%token OPER_SPY_T +%token OPER_UMODES +%token JOIN_FLOOD_COUNT +%token JOIN_FLOOD_TIME +%token PACE_WAIT +%token PACE_WAIT_SIMPLE +%token PASSWORD +%token PATH +%token PING_COOKIE +%token PING_TIME +%token PING_WARNING +%token PORT +%token QSTRING +%token QUIET_ON_BAN +%token REASON +%token REDIRPORT +%token REDIRSERV +%token REGEX_T +%token REHASH +%token REMOTE +%token REMOTEBAN +%token RESTRICT_CHANNELS +%token RSA_PRIVATE_KEY_FILE +%token RSA_PUBLIC_KEY_FILE +%token SSL_CERTIFICATE_FILE +%token SSL_DH_PARAM_FILE +%token T_SSL_CLIENT_METHOD +%token T_SSL_SERVER_METHOD +%token T_SSLV3 +%token T_TLSV1 +%token RESV +%token RESV_EXEMPT +%token SECONDS MINUTES HOURS DAYS WEEKS +%token SENDQ +%token SEND_PASSWORD +%token SERVERHIDE +%token SERVERINFO +%token IRCD_SID +%token TKLINE_EXPIRE_NOTICES +%token T_SHARED +%token T_CLUSTER +%token TYPE +%token SHORT_MOTD +%token SPOOF +%token SPOOF_NOTICE +%token STATS_E_DISABLED +%token STATS_I_OPER_ONLY +%token STATS_K_OPER_ONLY +%token STATS_O_OPER_ONLY +%token STATS_P_OPER_ONLY +%token TBOOL +%token TMASKED +%token TS_MAX_DELTA +%token TS_WARN_DELTA +%token TWODOTS +%token T_ALL +%token T_BOTS +%token T_SOFTCALLERID +%token T_CALLERID +%token T_CCONN +%token T_CCONN_FULL +%token T_SSL_CIPHER_LIST +%token T_DEAF +%token T_DEBUG +%token T_DLINE +%token T_EXTERNAL +%token T_FULL +%token T_INVISIBLE +%token T_IPV4 +%token T_IPV6 +%token T_LOCOPS +%token T_MAX_CLIENTS +%token T_NCHANGE +%token T_OPERWALL +%token T_RECVQ +%token T_REJ +%token T_SERVER +%token T_SERVNOTICE +%token T_SET +%token T_SKILL +%token T_SPY +%token T_SSL +%token T_UMODES +%token T_UNAUTH +%token T_UNDLINE +%token T_UNLIMITED +%token T_UNRESV +%token T_UNXLINE +%token T_GLOBOPS +%token T_WALLOP +%token T_RESTART +%token T_SERVICE +%token T_SERVICES_NAME +%token THROTTLE_TIME +%token TRUE_NO_OPER_FLOOD +%token UNKLINE +%token USER +%token USE_EGD +%token USE_LOGGING +%token VHOST +%token VHOST6 +%token XLINE +%token WARN_NO_NLINE +%token T_SIZE +%token T_FILE + +%type <string> QSTRING +%type <number> NUMBER +%type <number> timespec +%type <number> timespec_ +%type <number> sizespec +%type <number> sizespec_ + +%% +conf: + | conf conf_item + ; + +conf_item: admin_entry + | logging_entry + | oper_entry + | channel_entry + | class_entry + | listen_entry + | auth_entry + | serverinfo_entry + | serverhide_entry + | resv_entry + | service_entry + | shared_entry + | cluster_entry + | connect_entry + | kill_entry + | deny_entry + | exempt_entry + | general_entry + | gecos_entry + | modules_entry + | error ';' + | error '}' + ; + + +timespec_: { $$ = 0; } | timespec; +timespec: NUMBER timespec_ + { + $$ = $1 + $2; + } + | NUMBER SECONDS timespec_ + { + $$ = $1 + $3; + } + | NUMBER MINUTES timespec_ + { + $$ = $1 * 60 + $3; + } + | NUMBER HOURS timespec_ + { + $$ = $1 * 60 * 60 + $3; + } + | NUMBER DAYS timespec_ + { + $$ = $1 * 60 * 60 * 24 + $3; + } + | NUMBER WEEKS timespec_ + { + $$ = $1 * 60 * 60 * 24 * 7 + $3; + } + ; + +sizespec_: { $$ = 0; } | sizespec; +sizespec: NUMBER sizespec_ { $$ = $1 + $2; } + | NUMBER BYTES sizespec_ { $$ = $1 + $3; } + | NUMBER KBYTES sizespec_ { $$ = $1 * 1024 + $3; } + | NUMBER MBYTES sizespec_ { $$ = $1 * 1024 * 1024 + $3; } + ; + + +/*************************************************************************** + * section modules + ***************************************************************************/ +modules_entry: MODULES + '{' modules_items '}' ';'; + +modules_items: modules_items modules_item | modules_item; +modules_item: modules_module | modules_path | error ';' ; + +modules_module: MODULE '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + add_conf_module(libio_basename(yylval.string)); +}; + +modules_path: PATH '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + mod_add_path(yylval.string); +}; + + +serverinfo_entry: SERVERINFO '{' serverinfo_items '}' ';'; + +serverinfo_items: serverinfo_items serverinfo_item | serverinfo_item ; +serverinfo_item: serverinfo_name | serverinfo_vhost | + serverinfo_hub | serverinfo_description | + serverinfo_network_name | serverinfo_network_desc | + serverinfo_max_clients | serverinfo_ssl_dh_param_file | + serverinfo_rsa_private_key_file | serverinfo_vhost6 | + serverinfo_sid | serverinfo_ssl_certificate_file | + serverinfo_ssl_client_method | serverinfo_ssl_server_method | + serverinfo_ssl_cipher_list | + error ';' ; + + +serverinfo_ssl_client_method: T_SSL_CLIENT_METHOD '=' client_method_types ';' ; +serverinfo_ssl_server_method: T_SSL_SERVER_METHOD '=' server_method_types ';' ; + +client_method_types: client_method_types ',' client_method_type_item | client_method_type_item; +client_method_type_item: T_SSLV3 +{ +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx) + SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv3); +#endif +} | T_TLSV1 +{ +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx) + SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_TLSv1); +#endif +}; + +server_method_types: server_method_types ',' server_method_type_item | server_method_type_item; +server_method_type_item: T_SSLV3 +{ +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) + SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv3); +#endif +} | T_TLSV1 +{ +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) + SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_TLSv1); +#endif +}; + +serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';' +{ +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) + { + if (!ServerInfo.rsa_private_key_file) + { + yyerror("No rsa_private_key_file specified, SSL disabled"); + break; + } + + if (SSL_CTX_use_certificate_file(ServerInfo.server_ctx, yylval.string, + SSL_FILETYPE_PEM) <= 0 || + SSL_CTX_use_certificate_file(ServerInfo.client_ctx, yylval.string, + SSL_FILETYPE_PEM) <= 0) + { + yyerror(ERR_lib_error_string(ERR_get_error())); + break; + } + + if (SSL_CTX_use_PrivateKey_file(ServerInfo.server_ctx, ServerInfo.rsa_private_key_file, + SSL_FILETYPE_PEM) <= 0 || + SSL_CTX_use_PrivateKey_file(ServerInfo.client_ctx, ServerInfo.rsa_private_key_file, + SSL_FILETYPE_PEM) <= 0) + { + yyerror(ERR_lib_error_string(ERR_get_error())); + break; + } + + if (!SSL_CTX_check_private_key(ServerInfo.server_ctx) || + !SSL_CTX_check_private_key(ServerInfo.client_ctx)) + { + yyerror(ERR_lib_error_string(ERR_get_error())); + break; + } + } +#endif +}; + +serverinfo_rsa_private_key_file: RSA_PRIVATE_KEY_FILE '=' QSTRING ';' +{ +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 1) + { + BIO *file; + + if (ServerInfo.rsa_private_key) + { + RSA_free(ServerInfo.rsa_private_key); + ServerInfo.rsa_private_key = NULL; + } + + if (ServerInfo.rsa_private_key_file) + { + MyFree(ServerInfo.rsa_private_key_file); + ServerInfo.rsa_private_key_file = NULL; + } + + DupString(ServerInfo.rsa_private_key_file, yylval.string); + + if ((file = BIO_new_file(yylval.string, "r")) == NULL) + { + yyerror("File open failed, ignoring"); + break; + } + + ServerInfo.rsa_private_key = PEM_read_bio_RSAPrivateKey(file, NULL, 0, NULL); + + BIO_set_close(file, BIO_CLOSE); + BIO_free(file); + + if (ServerInfo.rsa_private_key == NULL) + { + yyerror("Couldn't extract key, ignoring"); + break; + } + + if (!RSA_check_key(ServerInfo.rsa_private_key)) + { + RSA_free(ServerInfo.rsa_private_key); + ServerInfo.rsa_private_key = NULL; + + yyerror("Invalid key, ignoring"); + break; + } + + /* require 2048 bit (256 byte) key */ + if (RSA_size(ServerInfo.rsa_private_key) != 256) + { + RSA_free(ServerInfo.rsa_private_key); + ServerInfo.rsa_private_key = NULL; + + yyerror("Not a 2048 bit key, ignoring"); + } + } +#endif +}; + +serverinfo_ssl_dh_param_file: SSL_DH_PARAM_FILE '=' QSTRING ';' +{ +/* TBD - XXX: error reporting */ +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) + { + BIO *file = BIO_new_file(yylval.string, "r"); + + if (file) + { + DH *dh = PEM_read_bio_DHparams(file, NULL, NULL, NULL); + + BIO_free(file); + + if (dh) + { + if (DH_size(dh) < 128) + ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::ssl_dh_param_file -- need at least a 1024 bit DH prime size"); + else + SSL_CTX_set_tmp_dh(ServerInfo.server_ctx, dh); + + DH_free(dh); + } + } + } +#endif +}; + +serverinfo_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';' +{ +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) + SSL_CTX_set_cipher_list(ServerInfo.server_ctx, yylval.string); +#endif +}; + +serverinfo_name: NAME '=' QSTRING ';' +{ + /* this isn't rehashable */ + if (conf_parser_ctx.pass == 2 && !ServerInfo.name) + { + if (valid_servname(yylval.string)) + DupString(ServerInfo.name, yylval.string); + else + { + ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::name -- invalid name. Aborting."); + exit(0); + } + } +}; + +serverinfo_sid: IRCD_SID '=' QSTRING ';' +{ + /* this isn't rehashable */ + if (conf_parser_ctx.pass == 2 && !ServerInfo.sid) + { + if (valid_sid(yylval.string)) + DupString(ServerInfo.sid, yylval.string); + else + { + ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::sid -- invalid SID. Aborting."); + exit(0); + } + } +}; + +serverinfo_description: DESCRIPTION '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(ServerInfo.description); + DupString(ServerInfo.description,yylval.string); + } +}; + +serverinfo_network_name: NETWORK_NAME '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + char *p; + + if ((p = strchr(yylval.string, ' ')) != NULL) + p = '\0'; + + MyFree(ServerInfo.network_name); + DupString(ServerInfo.network_name, yylval.string); + } +}; + +serverinfo_network_desc: NETWORK_DESC '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(ServerInfo.network_desc); + DupString(ServerInfo.network_desc, yylval.string); + } +}; + +serverinfo_vhost: VHOST '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2 && *yylval.string != '*') + { + struct addrinfo hints, *res; + + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + + if (getaddrinfo(yylval.string, NULL, &hints, &res)) + ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string); + else + { + assert(res != NULL); + + memcpy(&ServerInfo.ip, res->ai_addr, res->ai_addrlen); + ServerInfo.ip.ss.ss_family = res->ai_family; + ServerInfo.ip.ss_len = res->ai_addrlen; + freeaddrinfo(res); + + ServerInfo.specific_ipv4_vhost = 1; + } + } +}; + +serverinfo_vhost6: VHOST6 '=' QSTRING ';' +{ +#ifdef IPV6 + if (conf_parser_ctx.pass == 2 && *yylval.string != '*') + { + struct addrinfo hints, *res; + + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + + if (getaddrinfo(yylval.string, NULL, &hints, &res)) + ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost6(%s)", yylval.string); + else + { + assert(res != NULL); + + memcpy(&ServerInfo.ip6, res->ai_addr, res->ai_addrlen); + ServerInfo.ip6.ss.ss_family = res->ai_family; + ServerInfo.ip6.ss_len = res->ai_addrlen; + freeaddrinfo(res); + + ServerInfo.specific_ipv6_vhost = 1; + } + } +#endif +}; + +serverinfo_max_clients: T_MAX_CLIENTS '=' NUMBER ';' +{ + if (conf_parser_ctx.pass == 2) + { + recalc_fdlimit(NULL); + + if ($3 < MAXCLIENTS_MIN) + { + char buf[IRCD_BUFSIZE]; + ircsprintf(buf, "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN); + yyerror(buf); + } + else if ($3 > MAXCLIENTS_MAX) + { + char buf[IRCD_BUFSIZE]; + ircsprintf(buf, "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX); + yyerror(buf); + } + else + ServerInfo.max_clients = $3; + } +}; + +serverinfo_hub: HUB '=' TBOOL ';' +{ + if (conf_parser_ctx.pass == 2) + ServerInfo.hub = yylval.number; +}; + +/*************************************************************************** + * admin section + ***************************************************************************/ +admin_entry: ADMIN '{' admin_items '}' ';' ; + +admin_items: admin_items admin_item | admin_item; +admin_item: admin_name | admin_description | + admin_email | error ';' ; + +admin_name: NAME '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(AdminInfo.name); + DupString(AdminInfo.name, yylval.string); + } +}; + +admin_email: EMAIL '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(AdminInfo.email); + DupString(AdminInfo.email, yylval.string); + } +}; + +admin_description: DESCRIPTION '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(AdminInfo.description); + DupString(AdminInfo.description, yylval.string); + } +}; + +/*************************************************************************** + * section logging + ***************************************************************************/ +logging_entry: T_LOG '{' logging_items '}' ';' ; +logging_items: logging_items logging_item | logging_item ; + +logging_item: logging_use_logging | logging_file_entry | + error ';' ; + +logging_use_logging: USE_LOGGING '=' TBOOL ';' +{ + if (conf_parser_ctx.pass == 2) + ConfigLoggingEntry.use_logging = yylval.number; +}; + +logging_file_entry: +{ + lfile[0] = '\0'; + ltype = 0; + lsize = 0; +} T_FILE '{' logging_file_items '}' ';' +{ + if (conf_parser_ctx.pass == 2 && ltype > 0) + log_add_file(ltype, lsize, lfile); +}; + +logging_file_items: logging_file_items logging_file_item | + logging_file_item ; + +logging_file_item: logging_file_name | logging_file_type | + logging_file_size | error ';' ; + +logging_file_name: NAME '=' QSTRING ';' +{ + strlcpy(lfile, yylval.string, sizeof(lfile)); +} + +logging_file_size: T_SIZE '=' sizespec ';' +{ + lsize = $3; +} | T_SIZE '=' T_UNLIMITED ';' +{ + lsize = 0; +}; + +logging_file_type: TYPE +{ + if (conf_parser_ctx.pass == 2) + ltype = 0; +} '=' logging_file_type_items ';' ; + +logging_file_type_items: logging_file_type_items ',' logging_file_type_item | logging_file_type_item; +logging_file_type_item: USER +{ + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_USER; +} | OPERATOR +{ + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_OPER; +} | GLINE +{ + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_GLINE; +} | T_DLINE +{ + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_DLINE; +} | KLINE +{ + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_KLINE; +} | KILL +{ + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_KILL; +} | T_DEBUG +{ + if (conf_parser_ctx.pass == 2) + ltype = LOG_TYPE_DEBUG; +}; + + +/*************************************************************************** + * section oper + ***************************************************************************/ +oper_entry: OPERATOR +{ + if (conf_parser_ctx.pass == 2) + { + yy_conf = make_conf_item(OPER_TYPE); + yy_aconf = map_to_conf(yy_conf); + SetConfEncrypted(yy_aconf); /* Yes, the default is encrypted */ + } + else + { + MyFree(class_name); + class_name = NULL; + } +} '{' oper_items '}' ';' +{ + if (conf_parser_ctx.pass == 2) + { + struct CollectItem *yy_tmp; + dlink_node *ptr; + dlink_node *next_ptr; + + conf_add_class_to_conf(yy_conf, class_name); + + /* Now, make sure there is a copy of the "base" given oper + * block in each of the collected copies + */ + + DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head) + { + struct AccessItem *new_aconf; + struct ConfItem *new_conf; + yy_tmp = ptr->data; + + new_conf = make_conf_item(OPER_TYPE); + new_aconf = (struct AccessItem *)map_to_conf(new_conf); + + new_aconf->flags = yy_aconf->flags; + + if (yy_conf->name != NULL) + DupString(new_conf->name, yy_conf->name); + if (yy_tmp->user != NULL) + DupString(new_aconf->user, yy_tmp->user); + else + DupString(new_aconf->user, "*"); + if (yy_tmp->host != NULL) + DupString(new_aconf->host, yy_tmp->host); + else + DupString(new_aconf->host, "*"); + + new_aconf->type = parse_netmask(new_aconf->host, &new_aconf->addr, + &new_aconf->bits); + + conf_add_class_to_conf(new_conf, class_name); + if (yy_aconf->passwd != NULL) + DupString(new_aconf->passwd, yy_aconf->passwd); + + new_aconf->port = yy_aconf->port; +#ifdef HAVE_LIBCRYPTO + if (yy_aconf->rsa_public_key_file != NULL) + { + BIO *file; + + DupString(new_aconf->rsa_public_key_file, + yy_aconf->rsa_public_key_file); + + file = BIO_new_file(yy_aconf->rsa_public_key_file, "r"); + new_aconf->rsa_public_key = PEM_read_bio_RSA_PUBKEY(file, + NULL, 0, NULL); + BIO_set_close(file, BIO_CLOSE); + BIO_free(file); + } +#endif + +#ifdef HAVE_LIBCRYPTO + if (yy_tmp->name && (yy_tmp->passwd || yy_aconf->rsa_public_key) + && yy_tmp->host) +#else + if (yy_tmp->name && yy_tmp->passwd && yy_tmp->host) +#endif + { + conf_add_class_to_conf(new_conf, class_name); + if (yy_tmp->name != NULL) + DupString(new_conf->name, yy_tmp->name); + } + + dlinkDelete(&yy_tmp->node, &col_conf_list); + free_collect_item(yy_tmp); + } + + yy_conf = NULL; + yy_aconf = NULL; + + + MyFree(class_name); + class_name = NULL; + } +}; + +oper_items: oper_items oper_item | oper_item; +oper_item: oper_name | oper_user | oper_password | + oper_umodes | oper_class | oper_encrypted | + oper_rsa_public_key_file | oper_flags | error ';' ; + +oper_name: NAME '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(yy_conf->name); + DupString(yy_conf->name, yylval.string); + } +}; + +oper_user: USER '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + struct split_nuh_item nuh; + + nuh.nuhmask = yylval.string; + nuh.nickptr = NULL; + nuh.userptr = userbuf; + nuh.hostptr = hostbuf; + + nuh.nicksize = 0; + nuh.usersize = sizeof(userbuf); + nuh.hostsize = sizeof(hostbuf); + + split_nuh(&nuh); + + if (yy_aconf->user == NULL) + { + DupString(yy_aconf->user, userbuf); + DupString(yy_aconf->host, hostbuf); + + yy_aconf->type = parse_netmask(yy_aconf->host, &yy_aconf->addr, + &yy_aconf->bits); + } + else + { + struct CollectItem *yy_tmp = MyMalloc(sizeof(struct CollectItem)); + + DupString(yy_tmp->user, userbuf); + DupString(yy_tmp->host, hostbuf); + + dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list); + } + } +}; + +oper_password: PASSWORD '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (yy_aconf->passwd != NULL) + memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd)); + + MyFree(yy_aconf->passwd); + DupString(yy_aconf->passwd, yylval.string); + } +}; + +oper_encrypted: ENCRYPTED '=' TBOOL ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (yylval.number) + SetConfEncrypted(yy_aconf); + else + ClearConfEncrypted(yy_aconf); + } +}; + +oper_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';' +{ +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2) + { + BIO *file; + + if (yy_aconf->rsa_public_key != NULL) + { + RSA_free(yy_aconf->rsa_public_key); + yy_aconf->rsa_public_key = NULL; + } + + if (yy_aconf->rsa_public_key_file != NULL) + { + MyFree(yy_aconf->rsa_public_key_file); + yy_aconf->rsa_public_key_file = NULL; + } + + DupString(yy_aconf->rsa_public_key_file, yylval.string); + file = BIO_new_file(yylval.string, "r"); + + if (file == NULL) + { + yyerror("Ignoring rsa_public_key_file -- file doesn't exist"); + break; + } + + yy_aconf->rsa_public_key = PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL); + + if (yy_aconf->rsa_public_key == NULL) + { + yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax."); + break; + } + + BIO_set_close(file, BIO_CLOSE); + BIO_free(file); + } +#endif /* HAVE_LIBCRYPTO */ +}; + +oper_class: CLASS '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(class_name); + DupString(class_name, yylval.string); + } +}; + +oper_umodes: T_UMODES +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes = 0; +} '=' oper_umodes_items ';' ; + +oper_umodes_items: oper_umodes_items ',' oper_umodes_item | oper_umodes_item; +oper_umodes_item: T_BOTS +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_BOTS; +} | T_CCONN +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_CCONN; +} | T_CCONN_FULL +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_CCONN_FULL; +} | T_DEAF +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_DEAF; +} | T_DEBUG +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_DEBUG; +} | T_FULL +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_FULL; +} | HIDDEN +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_HIDDEN; +} | T_SKILL +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_SKILL; +} | T_NCHANGE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_NCHANGE; +} | T_REJ +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_REJ; +} | T_UNAUTH +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_UNAUTH; +} | T_SPY +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_SPY; +} | T_EXTERNAL +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_EXTERNAL; +} | T_OPERWALL +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_OPERWALL; +} | T_SERVNOTICE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_SERVNOTICE; +} | T_INVISIBLE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_INVISIBLE; +} | T_WALLOP +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_WALLOP; +} | T_SOFTCALLERID +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_SOFTCALLERID; +} | T_CALLERID +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_CALLERID; +} | T_LOCOPS +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->modes |= UMODE_LOCOPS; +}; + +oper_flags: IRCD_FLAGS +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port = 0; +} '=' oper_flags_items ';'; + +oper_flags_items: oper_flags_items ',' oper_flags_item | oper_flags_item; +oper_flags_item: GLOBAL_KILL +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_GLOBAL_KILL; +} | REMOTE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_REMOTE; +} | KLINE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_K; +} | UNKLINE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_UNKLINE; +} | T_DLINE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_DLINE; +} | T_UNDLINE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_UNDLINE; +} | XLINE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_X; +} | GLINE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_GLINE; +} | DIE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_DIE; +} | T_RESTART +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_RESTART; +} | REHASH +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_REHASH; +} | ADMIN +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_ADMIN; +} | NICK_CHANGES +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_N; +} | T_OPERWALL +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_OPERWALL; +} | T_GLOBOPS +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_GLOBOPS; +} | OPER_SPY_T +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_OPER_SPY; +} | REMOTEBAN +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_REMOTEBAN; +} | T_SET +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_SET; +} | MODULE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port |= OPER_FLAG_MODULE; +}; + + +/*************************************************************************** + * section class + ***************************************************************************/ +class_entry: CLASS +{ + if (conf_parser_ctx.pass == 1) + { + yy_conf = make_conf_item(CLASS_TYPE); + yy_class = map_to_conf(yy_conf); + } +} '{' class_items '}' ';' +{ + if (conf_parser_ctx.pass == 1) + { + struct ConfItem *cconf = NULL; + struct ClassItem *class = NULL; + + if (yy_class_name == NULL) + delete_conf_item(yy_conf); + else + { + cconf = find_exact_name_conf(CLASS_TYPE, NULL, yy_class_name, NULL, NULL); + + if (cconf != NULL) /* The class existed already */ + { + int user_count = 0; + + rebuild_cidr_class(cconf, yy_class); + + class = map_to_conf(cconf); + + user_count = class->curr_user_count; + memcpy(class, yy_class, sizeof(*class)); + class->curr_user_count = user_count; + class->active = 1; + + delete_conf_item(yy_conf); + + MyFree(cconf->name); /* Allows case change of class name */ + cconf->name = yy_class_name; + } + else /* Brand new class */ + { + MyFree(yy_conf->name); /* just in case it was allocated */ + yy_conf->name = yy_class_name; + yy_class->active = 1; + } + } + + yy_class_name = NULL; + } +}; + +class_items: class_items class_item | class_item; +class_item: class_name | + class_cidr_bitlen_ipv4 | class_cidr_bitlen_ipv6 | + class_ping_time | + class_ping_warning | + class_number_per_cidr | + class_number_per_ip | + class_connectfreq | + class_max_number | + class_max_global | + class_max_local | + class_max_ident | + class_sendq | class_recvq | + error ';' ; + +class_name: NAME '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 1) + { + MyFree(yy_class_name); + DupString(yy_class_name, yylval.string); + } +}; + +class_ping_time: PING_TIME '=' timespec ';' +{ + if (conf_parser_ctx.pass == 1) + yy_class->ping_freq = $3; +}; + +class_ping_warning: PING_WARNING '=' timespec ';' +{ + if (conf_parser_ctx.pass == 1) + yy_class->ping_warning = $3; +}; + +class_number_per_ip: NUMBER_PER_IP '=' NUMBER ';' +{ + if (conf_parser_ctx.pass == 1) + yy_class->max_perip = $3; +}; + +class_connectfreq: CONNECTFREQ '=' timespec ';' +{ + if (conf_parser_ctx.pass == 1) + yy_class->con_freq = $3; +}; + +class_max_number: MAX_NUMBER '=' NUMBER ';' +{ + if (conf_parser_ctx.pass == 1) + yy_class->max_total = $3; +}; + +class_max_global: MAX_GLOBAL '=' NUMBER ';' +{ + if (conf_parser_ctx.pass == 1) + yy_class->max_global = $3; +}; + +class_max_local: MAX_LOCAL '=' NUMBER ';' +{ + if (conf_parser_ctx.pass == 1) + yy_class->max_local = $3; +}; + +class_max_ident: MAX_IDENT '=' NUMBER ';' +{ + if (conf_parser_ctx.pass == 1) + yy_class->max_ident = $3; +}; + +class_sendq: SENDQ '=' sizespec ';' +{ + if (conf_parser_ctx.pass == 1) + yy_class->max_sendq = $3; +}; + +class_recvq: T_RECVQ '=' sizespec ';' +{ + if (conf_parser_ctx.pass == 1) + if ($3 >= CLIENT_FLOOD_MIN && $3 <= CLIENT_FLOOD_MAX) + yy_class->max_recvq = $3; +}; + +class_cidr_bitlen_ipv4: CIDR_BITLEN_IPV4 '=' NUMBER ';' +{ + if (conf_parser_ctx.pass == 1) + yy_class->cidr_bitlen_ipv4 = $3 > 32 ? 32 : $3; +}; + +class_cidr_bitlen_ipv6: CIDR_BITLEN_IPV6 '=' NUMBER ';' +{ + if (conf_parser_ctx.pass == 1) + yy_class->cidr_bitlen_ipv6 = $3 > 128 ? 128 : $3; +}; + +class_number_per_cidr: NUMBER_PER_CIDR '=' NUMBER ';' +{ + if (conf_parser_ctx.pass == 1) + yy_class->number_per_cidr = $3; +}; + +/*************************************************************************** + * section listen + ***************************************************************************/ +listen_entry: LISTEN +{ + if (conf_parser_ctx.pass == 2) + { + listener_address = NULL; + listener_flags = 0; + } +} '{' listen_items '}' ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(listener_address); + listener_address = NULL; + } +}; + +listen_flags: IRCD_FLAGS +{ + listener_flags = 0; +} '=' listen_flags_items ';'; + +listen_flags_items: listen_flags_items ',' listen_flags_item | listen_flags_item; +listen_flags_item: T_SSL +{ + if (conf_parser_ctx.pass == 2) + listener_flags |= LISTENER_SSL; +} | HIDDEN +{ + if (conf_parser_ctx.pass == 2) + listener_flags |= LISTENER_HIDDEN; +} | T_SERVER +{ + if (conf_parser_ctx.pass == 2) + listener_flags |= LISTENER_SERVER; +}; + + + +listen_items: listen_items listen_item | listen_item; +listen_item: listen_port | listen_flags | listen_address | listen_host | error ';'; + +listen_port: PORT '=' port_items { listener_flags = 0; } ';'; + +port_items: port_items ',' port_item | port_item; + +port_item: NUMBER +{ + if (conf_parser_ctx.pass == 2) + { + if ((listener_flags & LISTENER_SSL)) +#ifdef HAVE_LIBCRYPTO + if (!ServerInfo.server_ctx) +#endif + { + yyerror("SSL not available - port closed"); + break; + } + add_listener($1, listener_address, listener_flags); + } +} | NUMBER TWODOTS NUMBER +{ + if (conf_parser_ctx.pass == 2) + { + int i; + + if ((listener_flags & LISTENER_SSL)) +#ifdef HAVE_LIBCRYPTO + if (!ServerInfo.server_ctx) +#endif + { + yyerror("SSL not available - port closed"); + break; + } + + for (i = $1; i <= $3; ++i) + add_listener(i, listener_address, listener_flags); + } +}; + +listen_address: IP '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(listener_address); + DupString(listener_address, yylval.string); + } +}; + +listen_host: HOST '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(listener_address); + DupString(listener_address, yylval.string); + } +}; + +/*************************************************************************** + * section auth + ***************************************************************************/ +auth_entry: IRCD_AUTH +{ + if (conf_parser_ctx.pass == 2) + { + yy_conf = make_conf_item(CLIENT_TYPE); + yy_aconf = map_to_conf(yy_conf); + } + else + { + MyFree(class_name); + class_name = NULL; + } +} '{' auth_items '}' ';' +{ + if (conf_parser_ctx.pass == 2) + { + struct CollectItem *yy_tmp = NULL; + dlink_node *ptr = NULL, *next_ptr = NULL; + + if (yy_aconf->user && yy_aconf->host) + { + conf_add_class_to_conf(yy_conf, class_name); + add_conf_by_address(CONF_CLIENT, yy_aconf); + } + else + delete_conf_item(yy_conf); + + /* copy over settings from first struct */ + DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head) + { + struct AccessItem *new_aconf; + struct ConfItem *new_conf; + + new_conf = make_conf_item(CLIENT_TYPE); + new_aconf = map_to_conf(new_conf); + + yy_tmp = ptr->data; + + assert(yy_tmp->user && yy_tmp->host); + + if (yy_aconf->passwd != NULL) + DupString(new_aconf->passwd, yy_aconf->passwd); + if (yy_conf->name != NULL) + DupString(new_conf->name, yy_conf->name); + if (yy_aconf->passwd != NULL) + DupString(new_aconf->passwd, yy_aconf->passwd); + + new_aconf->flags = yy_aconf->flags; + new_aconf->port = yy_aconf->port; + + DupString(new_aconf->user, yy_tmp->user); + collapse(new_aconf->user); + + DupString(new_aconf->host, yy_tmp->host); + collapse(new_aconf->host); + + conf_add_class_to_conf(new_conf, class_name); + add_conf_by_address(CONF_CLIENT, new_aconf); + dlinkDelete(&yy_tmp->node, &col_conf_list); + free_collect_item(yy_tmp); + } + + MyFree(class_name); + class_name = NULL; + yy_conf = NULL; + yy_aconf = NULL; + } +}; + +auth_items: auth_items auth_item | auth_item; +auth_item: auth_user | auth_passwd | auth_class | auth_flags | + auth_spoof | auth_redir_serv | auth_redir_port | + auth_encrypted | error ';' ; + +auth_user: USER '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + struct CollectItem *yy_tmp = NULL; + struct split_nuh_item nuh; + + nuh.nuhmask = yylval.string; + nuh.nickptr = NULL; + nuh.userptr = userbuf; + nuh.hostptr = hostbuf; + + nuh.nicksize = 0; + nuh.usersize = sizeof(userbuf); + nuh.hostsize = sizeof(hostbuf); + + split_nuh(&nuh); + + if (yy_aconf->user == NULL) + { + DupString(yy_aconf->user, userbuf); + DupString(yy_aconf->host, hostbuf); + } + else + { + yy_tmp = MyMalloc(sizeof(struct CollectItem)); + + DupString(yy_tmp->user, userbuf); + DupString(yy_tmp->host, hostbuf); + + dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list); + } + } +}; + +auth_passwd: PASSWORD '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + /* be paranoid */ + if (yy_aconf->passwd != NULL) + memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd)); + + MyFree(yy_aconf->passwd); + DupString(yy_aconf->passwd, yylval.string); + } +}; + +auth_class: CLASS '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(class_name); + DupString(class_name, yylval.string); + } +}; + +auth_encrypted: ENCRYPTED '=' TBOOL ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (yylval.number) + SetConfEncrypted(yy_aconf); + else + ClearConfEncrypted(yy_aconf); + } +}; + +auth_flags: IRCD_FLAGS +{ +} '=' auth_flags_items ';'; + +auth_flags_items: auth_flags_items ',' auth_flags_item | auth_flags_item; +auth_flags_item: SPOOF_NOTICE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE; +} | EXCEED_LIMIT +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_NOLIMIT; +} | KLINE_EXEMPT +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE; +} | NEED_IDENT +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD; +} | CAN_FLOOD +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD; +} | NO_TILDE +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_NO_TILDE; +} | GLINE_EXEMPT +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE; +} | RESV_EXEMPT +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_EXEMPTRESV; +} | NEED_PASSWORD +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD; +}; + +auth_spoof: SPOOF '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(yy_conf->name); + + if (strlen(yylval.string) <= HOSTLEN && valid_hostname(yylval.string)) + { + DupString(yy_conf->name, yylval.string); + yy_aconf->flags |= CONF_FLAGS_SPOOF_IP; + } + else + { + ilog(LOG_TYPE_IRCD, "Spoof either is too long or contains invalid characters. Ignoring it."); + yy_conf->name = NULL; + } + } +}; + +auth_redir_serv: REDIRSERV '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + yy_aconf->flags |= CONF_FLAGS_REDIR; + MyFree(yy_conf->name); + DupString(yy_conf->name, yylval.string); + } +}; + +auth_redir_port: REDIRPORT '=' NUMBER ';' +{ + if (conf_parser_ctx.pass == 2) + { + yy_aconf->flags |= CONF_FLAGS_REDIR; + yy_aconf->port = $3; + } +}; + + +/*************************************************************************** + * section resv + ***************************************************************************/ +resv_entry: RESV +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(resv_reason); + resv_reason = NULL; + } +} '{' resv_items '}' ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(resv_reason); + resv_reason = NULL; + } +}; + +resv_items: resv_items resv_item | resv_item; +resv_item: resv_creason | resv_channel | resv_nick | error ';' ; + +resv_creason: REASON '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(resv_reason); + DupString(resv_reason, yylval.string); + } +}; + +resv_channel: CHANNEL '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (IsChanPrefix(*yylval.string)) + { + char def_reason[] = "No reason"; + + create_channel_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1); + } + } + /* ignore it for now.. but we really should make a warning if + * its an erroneous name --fl_ */ +}; + +resv_nick: NICK '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + char def_reason[] = "No reason"; + + create_nick_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1); + } +}; + +/*************************************************************************** + * section service + ***************************************************************************/ +service_entry: T_SERVICE '{' service_items '}' ';'; + +service_items: service_items service_item | service_item; +service_item: service_name | error; + +service_name: NAME '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (valid_servname(yylval.string)) + { + yy_conf = make_conf_item(SERVICE_TYPE); + DupString(yy_conf->name, yylval.string); + } + } +}; + +/*************************************************************************** + * section shared, for sharing remote klines etc. + ***************************************************************************/ +shared_entry: T_SHARED +{ + if (conf_parser_ctx.pass == 2) + { + yy_conf = make_conf_item(ULINE_TYPE); + yy_match_item = map_to_conf(yy_conf); + yy_match_item->action = SHARED_ALL; + } +} '{' shared_items '}' ';' +{ + if (conf_parser_ctx.pass == 2) + { + yy_conf = NULL; + } +}; + +shared_items: shared_items shared_item | shared_item; +shared_item: shared_name | shared_user | shared_type | error ';' ; + +shared_name: NAME '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(yy_conf->name); + DupString(yy_conf->name, yylval.string); + } +}; + +shared_user: USER '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + struct split_nuh_item nuh; + + nuh.nuhmask = yylval.string; + nuh.nickptr = NULL; + nuh.userptr = userbuf; + nuh.hostptr = hostbuf; + + nuh.nicksize = 0; + nuh.usersize = sizeof(userbuf); + nuh.hostsize = sizeof(hostbuf); + + split_nuh(&nuh); + + DupString(yy_match_item->user, userbuf); + DupString(yy_match_item->host, hostbuf); + } +}; + +shared_type: TYPE +{ + if (conf_parser_ctx.pass == 2) + yy_match_item->action = 0; +} '=' shared_types ';' ; + +shared_types: shared_types ',' shared_type_item | shared_type_item; +shared_type_item: KLINE +{ + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_KLINE; +} | UNKLINE +{ + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_UNKLINE; +} | T_DLINE +{ + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_DLINE; +} | T_UNDLINE +{ + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_UNDLINE; +} | XLINE +{ + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_XLINE; +} | T_UNXLINE +{ + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_UNXLINE; +} | RESV +{ + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_RESV; +} | T_UNRESV +{ + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_UNRESV; +} | T_LOCOPS +{ + if (conf_parser_ctx.pass == 2) + yy_match_item->action |= SHARED_LOCOPS; +} | T_ALL +{ + if (conf_parser_ctx.pass == 2) + yy_match_item->action = SHARED_ALL; +}; + +/*************************************************************************** + * section cluster + ***************************************************************************/ +cluster_entry: T_CLUSTER +{ + if (conf_parser_ctx.pass == 2) + { + yy_conf = make_conf_item(CLUSTER_TYPE); + yy_conf->flags = SHARED_ALL; + } +} '{' cluster_items '}' ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (yy_conf->name == NULL) + DupString(yy_conf->name, "*"); + yy_conf = NULL; + } +}; + +cluster_items: cluster_items cluster_item | cluster_item; +cluster_item: cluster_name | cluster_type | error ';' ; + +cluster_name: NAME '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + DupString(yy_conf->name, yylval.string); +}; + +cluster_type: TYPE +{ + if (conf_parser_ctx.pass == 2) + yy_conf->flags = 0; +} '=' cluster_types ';' ; + +cluster_types: cluster_types ',' cluster_type_item | cluster_type_item; +cluster_type_item: KLINE +{ + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_KLINE; +} | UNKLINE +{ + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_UNKLINE; +} | T_DLINE +{ + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_DLINE; +} | T_UNDLINE +{ + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_UNDLINE; +} | XLINE +{ + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_XLINE; +} | T_UNXLINE +{ + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_UNXLINE; +} | RESV +{ + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_RESV; +} | T_UNRESV +{ + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_UNRESV; +} | T_LOCOPS +{ + if (conf_parser_ctx.pass == 2) + yy_conf->flags |= SHARED_LOCOPS; +} | T_ALL +{ + if (conf_parser_ctx.pass == 2) + yy_conf->flags = SHARED_ALL; +}; + +/*************************************************************************** + * section connect + ***************************************************************************/ +connect_entry: CONNECT +{ + if (conf_parser_ctx.pass == 2) + { + yy_conf = make_conf_item(SERVER_TYPE); + yy_aconf = map_to_conf(yy_conf); + + /* defaults */ + yy_aconf->port = PORTNUM; + } + else + { + MyFree(class_name); + class_name = NULL; + } +} '{' connect_items '}' ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (yy_aconf->host && yy_aconf->passwd && yy_aconf->spasswd) + { + if (conf_add_server(yy_conf, class_name) == -1) + delete_conf_item(yy_conf); + } + else + { + if (yy_conf->name != NULL) + { + if (yy_aconf->host == NULL) + yyerror("Ignoring connect block -- missing host"); + else if (!yy_aconf->passwd || !yy_aconf->spasswd) + yyerror("Ignoring connect block -- missing password"); + } + + /* XXX + * This fixes a try_connections() core (caused by invalid class_ptr + * pointers) reported by metalrock. That's an ugly fix, but there + * is currently no better way. The entire config subsystem needs an + * rewrite ASAP. make_conf_item() shouldn't really add things onto + * a doubly linked list immediately without any sanity checks! -Michael + */ + delete_conf_item(yy_conf); + } + + MyFree(class_name); + class_name = NULL; + yy_conf = NULL; + yy_aconf = NULL; + } +}; + +connect_items: connect_items connect_item | connect_item; +connect_item: connect_name | connect_host | connect_vhost | + connect_send_password | connect_accept_password | + connect_aftype | connect_port | connect_ssl_cipher_list | + connect_flags | connect_hub_mask | connect_leaf_mask | + connect_class | connect_encrypted | + error ';' ; + +connect_name: NAME '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(yy_conf->name); + DupString(yy_conf->name, yylval.string); + } +}; + +connect_host: HOST '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(yy_aconf->host); + DupString(yy_aconf->host, yylval.string); + } +}; + +connect_vhost: VHOST '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + struct addrinfo hints, *res; + + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + + if (getaddrinfo(yylval.string, NULL, &hints, &res)) + ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string); + else + { + assert(res != NULL); + + memcpy(&yy_aconf->bind, res->ai_addr, res->ai_addrlen); + yy_aconf->bind.ss.ss_family = res->ai_family; + yy_aconf->bind.ss_len = res->ai_addrlen; + freeaddrinfo(res); + } + } +}; + +connect_send_password: SEND_PASSWORD '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + if ($3[0] == ':') + yyerror("Server passwords cannot begin with a colon"); + else if (strchr($3, ' ') != NULL) + yyerror("Server passwords cannot contain spaces"); + else { + if (yy_aconf->spasswd != NULL) + memset(yy_aconf->spasswd, 0, strlen(yy_aconf->spasswd)); + + MyFree(yy_aconf->spasswd); + DupString(yy_aconf->spasswd, yylval.string); + } + } +}; + +connect_accept_password: ACCEPT_PASSWORD '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + if ($3[0] == ':') + yyerror("Server passwords cannot begin with a colon"); + else if (strchr($3, ' ') != NULL) + yyerror("Server passwords cannot contain spaces"); + else { + if (yy_aconf->passwd != NULL) + memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd)); + + MyFree(yy_aconf->passwd); + DupString(yy_aconf->passwd, yylval.string); + } + } +}; + +connect_port: PORT '=' NUMBER ';' +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->port = $3; +}; + +connect_aftype: AFTYPE '=' T_IPV4 ';' +{ + if (conf_parser_ctx.pass == 2) + yy_aconf->aftype = AF_INET; +} | AFTYPE '=' T_IPV6 ';' +{ +#ifdef IPV6 + if (conf_parser_ctx.pass == 2) + yy_aconf->aftype = AF_INET6; +#endif +}; + +connect_flags: IRCD_FLAGS +{ +} '=' connect_flags_items ';'; + +connect_flags_items: connect_flags_items ',' connect_flags_item | connect_flags_item; +connect_flags_item: AUTOCONN +{ + if (conf_parser_ctx.pass == 2) + SetConfAllowAutoConn(yy_aconf); +} | T_SSL +{ + if (conf_parser_ctx.pass == 2) + SetConfSSL(yy_aconf); +}; + +connect_encrypted: ENCRYPTED '=' TBOOL ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (yylval.number) + yy_aconf->flags |= CONF_FLAGS_ENCRYPTED; + else + yy_aconf->flags &= ~CONF_FLAGS_ENCRYPTED; + } +}; + +connect_hub_mask: HUB_MASK '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + char *mask; + + DupString(mask, yylval.string); + dlinkAdd(mask, make_dlink_node(), &yy_aconf->hub_list); + } +}; + +connect_leaf_mask: LEAF_MASK '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + char *mask; + + DupString(mask, yylval.string); + dlinkAdd(mask, make_dlink_node(), &yy_aconf->leaf_list); + } +}; + +connect_class: CLASS '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(class_name); + DupString(class_name, yylval.string); + } +}; + +connect_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';' +{ +#ifdef HAVE_LIBCRYPTO + if (conf_parser_ctx.pass == 2) + { + MyFree(yy_aconf->cipher_list); + DupString(yy_aconf->cipher_list, yylval.string); + } +#else + if (conf_parser_ctx.pass == 2) + yyerror("Ignoring connect::ciphers -- no OpenSSL support"); +#endif +}; + + +/*************************************************************************** + * section kill + ***************************************************************************/ +kill_entry: KILL +{ + if (conf_parser_ctx.pass == 2) + { + userbuf[0] = hostbuf[0] = reasonbuf[0] = '\0'; + regex_ban = 0; + } +} '{' kill_items '}' ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (userbuf[0] && hostbuf[0]) + { + if (regex_ban) + { +#ifdef HAVE_LIBPCRE + void *exp_user = NULL; + void *exp_host = NULL; + const char *errptr = NULL; + + if (!(exp_user = ircd_pcre_compile(userbuf, &errptr)) || + !(exp_host = ircd_pcre_compile(hostbuf, &errptr))) + { + ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: %s", + errptr); + break; + } + + yy_aconf = map_to_conf(make_conf_item(RKLINE_TYPE)); + yy_aconf->regexuser = exp_user; + yy_aconf->regexhost = exp_host; + + DupString(yy_aconf->user, userbuf); + DupString(yy_aconf->host, hostbuf); + + if (reasonbuf[0]) + DupString(yy_aconf->reason, reasonbuf); + else + DupString(yy_aconf->reason, "No reason"); +#else + ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: no PCRE support"); + break; +#endif + } + else + { + find_and_delete_temporary(userbuf, hostbuf, CONF_KLINE); + + yy_aconf = map_to_conf(make_conf_item(KLINE_TYPE)); + + DupString(yy_aconf->user, userbuf); + DupString(yy_aconf->host, hostbuf); + + if (reasonbuf[0]) + DupString(yy_aconf->reason, reasonbuf); + else + DupString(yy_aconf->reason, "No reason"); + add_conf_by_address(CONF_KLINE, yy_aconf); + } + } + + yy_aconf = NULL; + } +}; + +kill_type: TYPE +{ +} '=' kill_type_items ';'; + +kill_type_items: kill_type_items ',' kill_type_item | kill_type_item; +kill_type_item: REGEX_T +{ + if (conf_parser_ctx.pass == 2) + regex_ban = 1; +}; + +kill_items: kill_items kill_item | kill_item; +kill_item: kill_user | kill_reason | kill_type | error; + +kill_user: USER '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + struct split_nuh_item nuh; + + nuh.nuhmask = yylval.string; + nuh.nickptr = NULL; + nuh.userptr = userbuf; + nuh.hostptr = hostbuf; + + nuh.nicksize = 0; + nuh.usersize = sizeof(userbuf); + nuh.hostsize = sizeof(hostbuf); + + split_nuh(&nuh); + } +}; + +kill_reason: REASON '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf)); +}; + +/*************************************************************************** + * section deny + ***************************************************************************/ +deny_entry: DENY +{ + if (conf_parser_ctx.pass == 2) + hostbuf[0] = reasonbuf[0] = '\0'; +} '{' deny_items '}' ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (hostbuf[0] && parse_netmask(hostbuf, NULL, NULL) != HM_HOST) + { + find_and_delete_temporary(NULL, hostbuf, CONF_DLINE); + + yy_aconf = map_to_conf(make_conf_item(DLINE_TYPE)); + DupString(yy_aconf->host, hostbuf); + + if (reasonbuf[0]) + DupString(yy_aconf->reason, reasonbuf); + else + DupString(yy_aconf->reason, "No reason"); + add_conf_by_address(CONF_DLINE, yy_aconf); + yy_aconf = NULL; + } + } +}; + +deny_items: deny_items deny_item | deny_item; +deny_item: deny_ip | deny_reason | error; + +deny_ip: IP '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + strlcpy(hostbuf, yylval.string, sizeof(hostbuf)); +}; + +deny_reason: REASON '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf)); +}; + +/*************************************************************************** + * section exempt + ***************************************************************************/ +exempt_entry: EXEMPT '{' exempt_items '}' ';'; + +exempt_items: exempt_items exempt_item | exempt_item; +exempt_item: exempt_ip | error; + +exempt_ip: IP '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (yylval.string[0] && parse_netmask(yylval.string, NULL, NULL) != HM_HOST) + { + yy_aconf = map_to_conf(make_conf_item(EXEMPTDLINE_TYPE)); + DupString(yy_aconf->host, yylval.string); + + add_conf_by_address(CONF_EXEMPTDLINE, yy_aconf); + yy_aconf = NULL; + } + } +}; + +/*************************************************************************** + * section gecos + ***************************************************************************/ +gecos_entry: GECOS +{ + if (conf_parser_ctx.pass == 2) + { + regex_ban = 0; + reasonbuf[0] = gecos_name[0] = '\0'; + } +} '{' gecos_items '}' ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (gecos_name[0]) + { + if (regex_ban) + { +#ifdef HAVE_LIBPCRE + void *exp_p = NULL; + const char *errptr = NULL; + + if (!(exp_p = ircd_pcre_compile(gecos_name, &errptr))) + { + ilog(LOG_TYPE_IRCD, "Failed to add regular expression based X-Line: %s", + errptr); + break; + } + + yy_conf = make_conf_item(RXLINE_TYPE); + yy_conf->regexpname = exp_p; +#else + ilog(LOG_TYPE_IRCD, "Failed to add regular expression based X-Line: no PCRE support"); + break; +#endif + } + else + yy_conf = make_conf_item(XLINE_TYPE); + + yy_match_item = map_to_conf(yy_conf); + DupString(yy_conf->name, gecos_name); + + if (reasonbuf[0]) + DupString(yy_match_item->reason, reasonbuf); + else + DupString(yy_match_item->reason, "No reason"); + } + } +}; + +gecos_flags: TYPE +{ +} '=' gecos_flags_items ';'; + +gecos_flags_items: gecos_flags_items ',' gecos_flags_item | gecos_flags_item; +gecos_flags_item: REGEX_T +{ + if (conf_parser_ctx.pass == 2) + regex_ban = 1; +}; + +gecos_items: gecos_items gecos_item | gecos_item; +gecos_item: gecos_name | gecos_reason | gecos_flags | error; + +gecos_name: NAME '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + strlcpy(gecos_name, yylval.string, sizeof(gecos_name)); +}; + +gecos_reason: REASON '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf)); +}; + +/*************************************************************************** + * section general + ***************************************************************************/ +general_entry: GENERAL + '{' general_items '}' ';'; + +general_items: general_items general_item | general_item; +general_item: general_hide_spoof_ips | general_ignore_bogus_ts | + general_failed_oper_notice | general_anti_nick_flood | + general_max_nick_time | general_max_nick_changes | + general_max_accept | general_anti_spam_exit_message_time | + general_ts_warn_delta | general_ts_max_delta | + general_kill_chase_time_limit | + general_invisible_on_connect | + general_warn_no_nline | general_dots_in_ident | + general_stats_o_oper_only | general_stats_k_oper_only | + general_pace_wait | general_stats_i_oper_only | + general_pace_wait_simple | general_stats_P_oper_only | + general_short_motd | general_no_oper_flood | + general_true_no_oper_flood | general_oper_pass_resv | + general_message_locale | + general_oper_only_umodes | general_max_targets | + general_use_egd | general_egdpool_path | + general_oper_umodes | general_caller_id_wait | + general_opers_bypass_callerid | general_default_floodcount | + general_min_nonwildcard | general_min_nonwildcard_simple | + general_disable_remote_commands | + general_throttle_time | general_havent_read_conf | + general_ping_cookie | + general_disable_auth | + general_tkline_expire_notices | general_gline_enable | + general_gline_duration | general_gline_request_duration | + general_gline_min_cidr | + general_gline_min_cidr6 | + general_stats_e_disabled | + general_max_watch | general_services_name | + error; + + +general_max_watch: MAX_WATCH '=' NUMBER ';' +{ + ConfigFileEntry.max_watch = $3; +}; + +general_gline_enable: GLINE_ENABLE '=' TBOOL ';' +{ + if (conf_parser_ctx.pass == 2) + ConfigFileEntry.glines = yylval.number; +}; + +general_gline_duration: GLINE_DURATION '=' timespec ';' +{ + if (conf_parser_ctx.pass == 2) + ConfigFileEntry.gline_time = $3; +}; + +general_gline_request_duration: GLINE_REQUEST_DURATION '=' timespec ';' +{ + if (conf_parser_ctx.pass == 2) + ConfigFileEntry.gline_request_time = $3; +}; + +general_gline_min_cidr: GLINE_MIN_CIDR '=' NUMBER ';' +{ + ConfigFileEntry.gline_min_cidr = $3; +}; + +general_gline_min_cidr6: GLINE_MIN_CIDR6 '=' NUMBER ';' +{ + ConfigFileEntry.gline_min_cidr6 = $3; +}; + +general_tkline_expire_notices: TKLINE_EXPIRE_NOTICES '=' TBOOL ';' +{ + ConfigFileEntry.tkline_expire_notices = yylval.number; +}; + +general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' timespec ';' +{ + ConfigFileEntry.kill_chase_time_limit = $3; +}; + +general_hide_spoof_ips: HIDE_SPOOF_IPS '=' TBOOL ';' +{ + ConfigFileEntry.hide_spoof_ips = yylval.number; +}; + +general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';' +{ + ConfigFileEntry.ignore_bogus_ts = yylval.number; +}; + +general_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';' +{ + ConfigFileEntry.disable_remote = yylval.number; +}; + +general_failed_oper_notice: FAILED_OPER_NOTICE '=' TBOOL ';' +{ + ConfigFileEntry.failed_oper_notice = yylval.number; +}; + +general_anti_nick_flood: ANTI_NICK_FLOOD '=' TBOOL ';' +{ + ConfigFileEntry.anti_nick_flood = yylval.number; +}; + +general_max_nick_time: MAX_NICK_TIME '=' timespec ';' +{ + ConfigFileEntry.max_nick_time = $3; +}; + +general_max_nick_changes: MAX_NICK_CHANGES '=' NUMBER ';' +{ + ConfigFileEntry.max_nick_changes = $3; +}; + +general_max_accept: MAX_ACCEPT '=' NUMBER ';' +{ + ConfigFileEntry.max_accept = $3; +}; + +general_anti_spam_exit_message_time: ANTI_SPAM_EXIT_MESSAGE_TIME '=' timespec ';' +{ + ConfigFileEntry.anti_spam_exit_message_time = $3; +}; + +general_ts_warn_delta: TS_WARN_DELTA '=' timespec ';' +{ + ConfigFileEntry.ts_warn_delta = $3; +}; + +general_ts_max_delta: TS_MAX_DELTA '=' timespec ';' +{ + if (conf_parser_ctx.pass == 2) + ConfigFileEntry.ts_max_delta = $3; +}; + +general_havent_read_conf: HAVENT_READ_CONF '=' NUMBER ';' +{ + if (($3 > 0) && conf_parser_ctx.pass == 1) + { + ilog(LOG_TYPE_IRCD, "You haven't read your config file properly."); + ilog(LOG_TYPE_IRCD, "There is a line in the example conf that will kill your server if not removed."); + ilog(LOG_TYPE_IRCD, "Consider actually reading/editing the conf file, and removing this line."); + exit(0); + } +}; + +general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';' +{ + ConfigFileEntry.invisible_on_connect = yylval.number; +}; + +general_warn_no_nline: WARN_NO_NLINE '=' TBOOL ';' +{ + ConfigFileEntry.warn_no_nline = yylval.number; +}; + +general_stats_e_disabled: STATS_E_DISABLED '=' TBOOL ';' +{ + ConfigFileEntry.stats_e_disabled = yylval.number; +}; + +general_stats_o_oper_only: STATS_O_OPER_ONLY '=' TBOOL ';' +{ + ConfigFileEntry.stats_o_oper_only = yylval.number; +}; + +general_stats_P_oper_only: STATS_P_OPER_ONLY '=' TBOOL ';' +{ + ConfigFileEntry.stats_P_oper_only = yylval.number; +}; + +general_stats_k_oper_only: STATS_K_OPER_ONLY '=' TBOOL ';' +{ + ConfigFileEntry.stats_k_oper_only = 2 * yylval.number; +} | STATS_K_OPER_ONLY '=' TMASKED ';' +{ + ConfigFileEntry.stats_k_oper_only = 1; +}; + +general_stats_i_oper_only: STATS_I_OPER_ONLY '=' TBOOL ';' +{ + ConfigFileEntry.stats_i_oper_only = 2 * yylval.number; +} | STATS_I_OPER_ONLY '=' TMASKED ';' +{ + ConfigFileEntry.stats_i_oper_only = 1; +}; + +general_pace_wait: PACE_WAIT '=' timespec ';' +{ + ConfigFileEntry.pace_wait = $3; +}; + +general_caller_id_wait: CALLER_ID_WAIT '=' timespec ';' +{ + ConfigFileEntry.caller_id_wait = $3; +}; + +general_opers_bypass_callerid: OPERS_BYPASS_CALLERID '=' TBOOL ';' +{ + ConfigFileEntry.opers_bypass_callerid = yylval.number; +}; + +general_pace_wait_simple: PACE_WAIT_SIMPLE '=' timespec ';' +{ + ConfigFileEntry.pace_wait_simple = $3; +}; + +general_short_motd: SHORT_MOTD '=' TBOOL ';' +{ + ConfigFileEntry.short_motd = yylval.number; +}; + +general_no_oper_flood: NO_OPER_FLOOD '=' TBOOL ';' +{ + ConfigFileEntry.no_oper_flood = yylval.number; +}; + +general_true_no_oper_flood: TRUE_NO_OPER_FLOOD '=' TBOOL ';' +{ + ConfigFileEntry.true_no_oper_flood = yylval.number; +}; + +general_oper_pass_resv: OPER_PASS_RESV '=' TBOOL ';' +{ + ConfigFileEntry.oper_pass_resv = yylval.number; +}; + +general_message_locale: MESSAGE_LOCALE '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (strlen(yylval.string) > LOCALE_LENGTH-2) + yylval.string[LOCALE_LENGTH-1] = '\0'; + + set_locale(yylval.string); + } +}; + +general_dots_in_ident: DOTS_IN_IDENT '=' NUMBER ';' +{ + ConfigFileEntry.dots_in_ident = $3; +}; + +general_max_targets: MAX_TARGETS '=' NUMBER ';' +{ + ConfigFileEntry.max_targets = $3; +}; + +general_use_egd: USE_EGD '=' TBOOL ';' +{ + ConfigFileEntry.use_egd = yylval.number; +}; + +general_egdpool_path: EGDPOOL_PATH '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(ConfigFileEntry.egdpool_path); + DupString(ConfigFileEntry.egdpool_path, yylval.string); + } +}; + +general_services_name: T_SERVICES_NAME '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2 && valid_servname(yylval.string)) + { + MyFree(ConfigFileEntry.service_name); + DupString(ConfigFileEntry.service_name, yylval.string); + } +}; + +general_ping_cookie: PING_COOKIE '=' TBOOL ';' +{ + ConfigFileEntry.ping_cookie = yylval.number; +}; + +general_disable_auth: DISABLE_AUTH '=' TBOOL ';' +{ + ConfigFileEntry.disable_auth = yylval.number; +}; + +general_throttle_time: THROTTLE_TIME '=' timespec ';' +{ + ConfigFileEntry.throttle_time = yylval.number; +}; + +general_oper_umodes: OPER_UMODES +{ + ConfigFileEntry.oper_umodes = 0; +} '=' umode_oitems ';' ; + +umode_oitems: umode_oitems ',' umode_oitem | umode_oitem; +umode_oitem: T_BOTS +{ + ConfigFileEntry.oper_umodes |= UMODE_BOTS; +} | T_CCONN +{ + ConfigFileEntry.oper_umodes |= UMODE_CCONN; +} | T_CCONN_FULL +{ + ConfigFileEntry.oper_umodes |= UMODE_CCONN_FULL; +} | T_DEAF +{ + ConfigFileEntry.oper_umodes |= UMODE_DEAF; +} | T_DEBUG +{ + ConfigFileEntry.oper_umodes |= UMODE_DEBUG; +} | T_FULL +{ + ConfigFileEntry.oper_umodes |= UMODE_FULL; +} | HIDDEN +{ + ConfigFileEntry.oper_umodes |= UMODE_HIDDEN; +} | T_SKILL +{ + ConfigFileEntry.oper_umodes |= UMODE_SKILL; +} | T_NCHANGE +{ + ConfigFileEntry.oper_umodes |= UMODE_NCHANGE; +} | T_REJ +{ + ConfigFileEntry.oper_umodes |= UMODE_REJ; +} | T_UNAUTH +{ + ConfigFileEntry.oper_umodes |= UMODE_UNAUTH; +} | T_SPY +{ + ConfigFileEntry.oper_umodes |= UMODE_SPY; +} | T_EXTERNAL +{ + ConfigFileEntry.oper_umodes |= UMODE_EXTERNAL; +} | T_OPERWALL +{ + ConfigFileEntry.oper_umodes |= UMODE_OPERWALL; +} | T_SERVNOTICE +{ + ConfigFileEntry.oper_umodes |= UMODE_SERVNOTICE; +} | T_INVISIBLE +{ + ConfigFileEntry.oper_umodes |= UMODE_INVISIBLE; +} | T_WALLOP +{ + ConfigFileEntry.oper_umodes |= UMODE_WALLOP; +} | T_SOFTCALLERID +{ + ConfigFileEntry.oper_umodes |= UMODE_SOFTCALLERID; +} | T_CALLERID +{ + ConfigFileEntry.oper_umodes |= UMODE_CALLERID; +} | T_LOCOPS +{ + ConfigFileEntry.oper_umodes |= UMODE_LOCOPS; +}; + +general_oper_only_umodes: OPER_ONLY_UMODES +{ + ConfigFileEntry.oper_only_umodes = 0; +} '=' umode_items ';' ; + +umode_items: umode_items ',' umode_item | umode_item; +umode_item: T_BOTS +{ + ConfigFileEntry.oper_only_umodes |= UMODE_BOTS; +} | T_CCONN +{ + ConfigFileEntry.oper_only_umodes |= UMODE_CCONN; +} | T_CCONN_FULL +{ + ConfigFileEntry.oper_only_umodes |= UMODE_CCONN_FULL; +} | T_DEAF +{ + ConfigFileEntry.oper_only_umodes |= UMODE_DEAF; +} | T_DEBUG +{ + ConfigFileEntry.oper_only_umodes |= UMODE_DEBUG; +} | T_FULL +{ + ConfigFileEntry.oper_only_umodes |= UMODE_FULL; +} | T_SKILL +{ + ConfigFileEntry.oper_only_umodes |= UMODE_SKILL; +} | HIDDEN +{ + ConfigFileEntry.oper_only_umodes |= UMODE_HIDDEN; +} | T_NCHANGE +{ + ConfigFileEntry.oper_only_umodes |= UMODE_NCHANGE; +} | T_REJ +{ + ConfigFileEntry.oper_only_umodes |= UMODE_REJ; +} | T_UNAUTH +{ + ConfigFileEntry.oper_only_umodes |= UMODE_UNAUTH; +} | T_SPY +{ + ConfigFileEntry.oper_only_umodes |= UMODE_SPY; +} | T_EXTERNAL +{ + ConfigFileEntry.oper_only_umodes |= UMODE_EXTERNAL; +} | T_OPERWALL +{ + ConfigFileEntry.oper_only_umodes |= UMODE_OPERWALL; +} | T_SERVNOTICE +{ + ConfigFileEntry.oper_only_umodes |= UMODE_SERVNOTICE; +} | T_INVISIBLE +{ + ConfigFileEntry.oper_only_umodes |= UMODE_INVISIBLE; +} | T_WALLOP +{ + ConfigFileEntry.oper_only_umodes |= UMODE_WALLOP; +} | T_SOFTCALLERID +{ + ConfigFileEntry.oper_only_umodes |= UMODE_SOFTCALLERID; +} | T_CALLERID +{ + ConfigFileEntry.oper_only_umodes |= UMODE_CALLERID; +} | T_LOCOPS +{ + ConfigFileEntry.oper_only_umodes |= UMODE_LOCOPS; +}; + +general_min_nonwildcard: MIN_NONWILDCARD '=' NUMBER ';' +{ + ConfigFileEntry.min_nonwildcard = $3; +}; + +general_min_nonwildcard_simple: MIN_NONWILDCARD_SIMPLE '=' NUMBER ';' +{ + ConfigFileEntry.min_nonwildcard_simple = $3; +}; + +general_default_floodcount: DEFAULT_FLOODCOUNT '=' NUMBER ';' +{ + ConfigFileEntry.default_floodcount = $3; +}; + + +/*************************************************************************** + * section channel + ***************************************************************************/ +channel_entry: CHANNEL + '{' channel_items '}' ';'; + +channel_items: channel_items channel_item | channel_item; +channel_item: channel_max_bans | + channel_knock_delay | channel_knock_delay_channel | + channel_max_chans_per_user | channel_max_chans_per_oper | + channel_quiet_on_ban | channel_default_split_user_count | + channel_default_split_server_count | + channel_no_create_on_split | channel_restrict_channels | + channel_no_join_on_split | + channel_jflood_count | channel_jflood_time | + channel_disable_fake_channels | error; + +channel_disable_fake_channels: DISABLE_FAKE_CHANNELS '=' TBOOL ';' +{ + ConfigChannel.disable_fake_channels = yylval.number; +}; + +channel_restrict_channels: RESTRICT_CHANNELS '=' TBOOL ';' +{ + ConfigChannel.restrict_channels = yylval.number; +}; + +channel_knock_delay: KNOCK_DELAY '=' timespec ';' +{ + ConfigChannel.knock_delay = $3; +}; + +channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';' +{ + ConfigChannel.knock_delay_channel = $3; +}; + +channel_max_chans_per_user: MAX_CHANS_PER_USER '=' NUMBER ';' +{ + ConfigChannel.max_chans_per_user = $3; +}; + +channel_max_chans_per_oper: MAX_CHANS_PER_OPER '=' NUMBER ';' +{ + ConfigChannel.max_chans_per_oper = $3; +}; + +channel_quiet_on_ban: QUIET_ON_BAN '=' TBOOL ';' +{ + ConfigChannel.quiet_on_ban = yylval.number; +}; + +channel_max_bans: MAX_BANS '=' NUMBER ';' +{ + ConfigChannel.max_bans = $3; +}; + +channel_default_split_user_count: DEFAULT_SPLIT_USER_COUNT '=' NUMBER ';' +{ + ConfigChannel.default_split_user_count = $3; +}; + +channel_default_split_server_count: DEFAULT_SPLIT_SERVER_COUNT '=' NUMBER ';' +{ + ConfigChannel.default_split_server_count = $3; +}; + +channel_no_create_on_split: NO_CREATE_ON_SPLIT '=' TBOOL ';' +{ + ConfigChannel.no_create_on_split = yylval.number; +}; + +channel_no_join_on_split: NO_JOIN_ON_SPLIT '=' TBOOL ';' +{ + ConfigChannel.no_join_on_split = yylval.number; +}; + +channel_jflood_count: JOIN_FLOOD_COUNT '=' NUMBER ';' +{ + GlobalSetOptions.joinfloodcount = yylval.number; +}; + +channel_jflood_time: JOIN_FLOOD_TIME '=' timespec ';' +{ + GlobalSetOptions.joinfloodtime = yylval.number; +}; + +/*************************************************************************** + * section serverhide + ***************************************************************************/ +serverhide_entry: SERVERHIDE + '{' serverhide_items '}' ';'; + +serverhide_items: serverhide_items serverhide_item | serverhide_item; +serverhide_item: serverhide_flatten_links | serverhide_hide_servers | + serverhide_links_delay | + serverhide_hidden | serverhide_hidden_name | + serverhide_hide_server_ips | + error; + +serverhide_flatten_links: FLATTEN_LINKS '=' TBOOL ';' +{ + if (conf_parser_ctx.pass == 2) + ConfigServerHide.flatten_links = yylval.number; +}; + +serverhide_hide_servers: HIDE_SERVERS '=' TBOOL ';' +{ + if (conf_parser_ctx.pass == 2) + ConfigServerHide.hide_servers = yylval.number; +}; + +serverhide_hidden_name: HIDDEN_NAME '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + MyFree(ConfigServerHide.hidden_name); + DupString(ConfigServerHide.hidden_name, yylval.string); + } +}; + +serverhide_links_delay: LINKS_DELAY '=' timespec ';' +{ + if (conf_parser_ctx.pass == 2) + { + if (($3 > 0) && ConfigServerHide.links_disabled == 1) + { + eventAddIsh("write_links_file", write_links_file, NULL, $3); + ConfigServerHide.links_disabled = 0; + } + + ConfigServerHide.links_delay = $3; + } +}; + +serverhide_hidden: HIDDEN '=' TBOOL ';' +{ + if (conf_parser_ctx.pass == 2) + ConfigServerHide.hidden = yylval.number; +}; + +serverhide_hide_server_ips: HIDE_SERVER_IPS '=' TBOOL ';' +{ + if (conf_parser_ctx.pass == 2) + ConfigServerHide.hide_server_ips = yylval.number; +}; diff --git a/src/csvlib.c b/src/csvlib.c new file mode 100644 index 0000000..0b6034d --- /dev/null +++ b/src/csvlib.c @@ -0,0 +1,671 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * csvlib.c - set of functions to deal with csv type of conf files + * + * Copyright (C) 2003 by Diane Bruce, Stuart Walsh + * Use it anywhere you like, if you like it buy us a beer. + * If it's broken, don't bother us with the lawyers. + * + * $Id$ + */ + +#include "config.h" +#include "stdinc.h" +#include "list.h" +#include "log.h" +#include "conf.h" +#include "hostmask.h" +#include "client.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "memory.h" +#include "send.h" +#include "resv.h" +#include "s_serv.h" + +/* Fix "statement not reached" warnings on Sun WorkShop C */ +#ifdef __SUNPRO_C +# pragma error_messages(off, E_STATEMENT_NOT_REACHED) +#endif + + +static void parse_csv_line(char *, ...); +static int write_csv_line(FILE *, const char *, ...); +static int flush_write(struct Client *, FILE *, FILE *, + const char *, const char *); +static char *getfield(char *); + +int +find_and_delete_temporary(const char *user, const char *host, int type) +{ + struct irc_ssaddr iphost, *piphost; + struct AccessItem *aconf; + int t; + + if ((t = parse_netmask(host, &iphost, NULL)) != HM_HOST) + { +#ifdef IPV6 + if (t == HM_IPV6) + t = AF_INET6; + else +#endif + t = AF_INET; + piphost = &iphost; + } + else + { + t = 0; + piphost = NULL; + } + + if ((aconf = find_conf_by_address(host, piphost, type, t, user, NULL, 0))) + { + if (IsConfTemporary(aconf)) + { + delete_one_address_conf(host, aconf); + return 1; + } + } + + return 0; +} + +/* parse_csv_file() + * + * inputs - FILE pointer + * - type of conf to parse + * output - none + * side effects - + */ +void +parse_csv_file(FILE *file, ConfType conf_type) +{ + struct ConfItem *conf; + struct AccessItem *aconf; + struct MatchItem *match_item; + char *name_field=NULL; + char *user_field=NULL; + char *reason_field=NULL; + char *oper_reason=NULL; + char *host_field=NULL; + char line[IRCD_BUFSIZE]; + char *p; + + while (fgets(line, sizeof(line), file) != NULL) + { + if ((p = strchr(line, '\n')) != NULL) + *p = '\0'; + + if ((line[0] == '\0') || (line[0] == '#')) + continue; + + switch(conf_type) + { + case KLINE_TYPE: + parse_csv_line(line, &user_field, &host_field, &reason_field, NULL); + + find_and_delete_temporary(user_field, host_field, CONF_KLINE); + + conf = make_conf_item(KLINE_TYPE); + aconf = map_to_conf(conf); + + if (host_field != NULL) + DupString(aconf->host, host_field); + if (reason_field != NULL) + DupString(aconf->reason, reason_field); + if (user_field != NULL) + DupString(aconf->user, user_field); + if (aconf->host != NULL) + add_conf_by_address(CONF_KLINE, aconf); + break; + case DLINE_TYPE: + parse_csv_line(line, &host_field, &reason_field, NULL); + + if (host_field && parse_netmask(host_field, NULL, NULL) != HM_HOST) + { + find_and_delete_temporary(NULL, host_field, CONF_DLINE); + + aconf = map_to_conf(make_conf_item(DLINE_TYPE)); + DupString(aconf->host, host_field); + + if (reason_field != NULL) + DupString(aconf->reason, reason_field); + else + DupString(aconf->reason, "No reason"); + add_conf_by_address(CONF_DLINE, aconf); + } + + break; + + case XLINE_TYPE: + parse_csv_line(line, &name_field, &reason_field, &oper_reason, NULL); + conf = make_conf_item(XLINE_TYPE); + match_item = (struct MatchItem *)map_to_conf(conf); + if (name_field != NULL) + DupString(conf->name, name_field); + if (reason_field != NULL) + DupString(match_item->reason, reason_field); + break; + case CRESV_TYPE: + parse_csv_line(line, &name_field, &reason_field, NULL); + (void)create_channel_resv(name_field, reason_field, 0); + break; + + case NRESV_TYPE: + parse_csv_line(line, &name_field, &reason_field, NULL); + (void)create_nick_resv(name_field, reason_field, 0); + break; + + case GLINE_TYPE: + case CONF_TYPE: + case OPER_TYPE: + case CLIENT_TYPE: + case SERVER_TYPE: + case CLUSTER_TYPE: + case HUB_TYPE: + case LEAF_TYPE: + case ULINE_TYPE: + case EXEMPTDLINE_TYPE: + case CLASS_TYPE: + default: + break; + } + } +} + +/* + * parse_csv_line() + * + * inputs - pointer to line to parse + * output - + * side effects - + */ + +static void +parse_csv_line(char *line, ...) +{ + va_list args; + char **dest; + char *field = NULL; + + va_start(args, line); + + for (; ;) + { + dest = va_arg(args, char **); + if ((dest == NULL) || ((field = getfield(field ? NULL : line)) == NULL)) + { + va_end(args); + return; + } + *dest = field; + } +} + +/* write_conf_line() + * + * inputs - pointer to struct AccessItem + * - string current_date (small date) + * - time_t cur_time + * output - NONE + * side effects - This function takes care of + * finding right conf file, writing + * the right lines to this file, + * notifying the oper that their kline/dline etc. is in place + * notifying the opers on the server about the k/d etc. line + * + * - Dianora + */ +void +write_conf_line(struct Client *source_p, struct ConfItem *conf, + const char *current_date, time_t cur_time) +{ + FILE *out; + const char *filename, *from, *to; + struct AccessItem *aconf; + struct MatchItem *xconf; + struct ResvChannel *cresv_p=NULL; + struct MatchItem *nresv_p=NULL; + ConfType type; + + type = conf->type; + filename = get_conf_name(type); + + if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p)) + { + from = me.id; + to = source_p->id; + } + else + { + from = me.name; + to = source_p->name; + } + + if ((out = fopen(filename, "a")) == NULL) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "*** Problem opening %s ", filename); + return; + } + + switch(type) + { + case KLINE_TYPE: + aconf = (struct AccessItem *)map_to_conf(conf); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s added K-Line for [%s@%s] [%s]", + get_oper_name(source_p), + aconf->user, aconf->host, aconf->reason); + sendto_one(source_p, ":%s NOTICE %s :Added K-Line [%s@%s]", + from, to, aconf->user, aconf->host); + ilog(LOG_TYPE_KLINE, "%s added K-Line for [%s@%s] [%s]", + source_p->name, aconf->user, aconf->host, aconf->reason); + write_csv_line(out, "%s%s%s%s%s%s%d", + aconf->user, aconf->host, + aconf->reason, aconf->oper_reason, current_date, + get_oper_name(source_p), cur_time); + break; + case DLINE_TYPE: + aconf = (struct AccessItem *)map_to_conf(conf); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s added D-Line for [%s] [%s]", + get_oper_name(source_p), aconf->host, aconf->reason); + sendto_one(source_p, ":%s NOTICE %s :Added D-Line [%s] to %s", + from, to, aconf->host, filename); + ilog(LOG_TYPE_DLINE, "%s added D-Line for [%s] [%s]", + get_oper_name(source_p), aconf->host, aconf->reason); + write_csv_line(out, "%s%s%s%s%s%d", + aconf->host, aconf->reason, aconf->oper_reason, + current_date, + get_oper_name(source_p), cur_time); + break; + + case XLINE_TYPE: + xconf = (struct MatchItem *)map_to_conf(conf); + sendto_realops_flags(UMODE_ALL, L_ALL, + "%s added X-Line for [%s] [%s]", + get_oper_name(source_p), conf->name, + xconf->reason); + sendto_one(source_p, + ":%s NOTICE %s :Added X-Line [%s] [%d] [%s] to %s", + from, to, conf->name, + xconf->action, xconf->reason, filename); + ilog(LOG_TYPE_IRCD, "%s added X-Line for [%s] [%s]", + get_oper_name(source_p), conf->name, xconf->reason); + write_csv_line(out, "%s%s%s%s%s%d", + conf->name, xconf->reason, xconf->oper_reason, + current_date, get_oper_name(source_p), cur_time); + break; + case CRESV_TYPE: + cresv_p = (struct ResvChannel *)map_to_conf(conf); + + write_csv_line(out, "%s%s", + cresv_p->name, cresv_p->reason); + break; + + case NRESV_TYPE: + nresv_p = (struct MatchItem *)map_to_conf(conf); + + write_csv_line(out, "%s%s", + conf->name, nresv_p->reason); + break; + + default: + fclose(out); + return; + } + + fclose(out); +} + +/* + * write_csv_line() + * + * inputs - pointer to FILE * + * - formatted string + * output - + * side effects - single line is written to csv conf file + */ +static int +write_csv_line(FILE *out, const char *format, ...) +{ + char c; + size_t bytes = 0; + va_list args; + char tmp[1024]; + char *str = tmp; + const char *null_string = ""; + + if (out == NULL) + return(0); + + va_start(args, format); + + while ((c = *format++)) + { + if (c == '%') + { + c = *format++; + if (c == 's') + { + const char *p1 = va_arg(args, const char *); + if (p1 == NULL) + p1 = null_string; + *str++ = '\"'; + ++bytes; + while (*p1 != '\0') + { + *str++ = *p1++; + ++bytes; + } + *str++ = '\"'; + *str++ = ','; + + bytes += 2; + continue; + } + if (c == 'c') + { + *str++ = '\"'; + ++bytes; + *str++ = (char) va_arg(args, int); + ++bytes; + *str++ = '\"'; + *str++ = ','; + + bytes += 2; + continue; + } + + if (c == 'd') + { + int v = va_arg(args, int); + char t[40]; + char *p=t; + + while (v > 10) + { + *p++ = (v % 10) + '0'; + v = v/10; + } + *p++ = (v % 10) + '0'; + + *str++ = '\"'; + ++bytes; + while (p != t) + { + *str++ = *--p; + ++bytes; + } + + *str++ = '\"'; + *str++ = ','; + bytes += 2; + continue; + } + if (c != '%') + { + int ret; + + format -= 2; + ret = vsprintf(str, format, args); + str += ret; + bytes += ret; + *str++ = ','; + + ++bytes; + break; + } + } + *str++ = c; + ++bytes; + } + + if (*(str-1) == ',') + { + *(str-1) = '\n'; + *str = '\0'; + } + else + { + *str++ = '\n'; + ++bytes; + *str = '\0'; + } + + va_end(args); + str = tmp; + fputs(str, out); + + return(bytes); +} + +/* + * getfield + * + * inputs - input buffer + * output - next field + * side effects - field breakup for ircd.conf file. + */ +static char * +getfield(char *newline) +{ + static char *line = NULL; + char *end, *field; + + if (newline != NULL) + line = newline; + + if (line == NULL) + return(NULL); + + field = line; + + /* skip everything that's not a starting quote */ + for(;;) + { + if (*field == '\0') + return(NULL); + else if (*field == '"') + break; + ++field; + } + + /* skip over the beginning " */ + end = ++field; + + for (;;) + { + /* At end of string, mark it as end and return */ + if ((*end == '\0') || (*end == '\n')) + { + line = NULL; + return(NULL); + } + else if (*end == '\\') /* found escape character ? */ + { + end++; + } + else if (*end == '"') /* found terminating " */ + { + *end++ = '\0'; + line = end; + return(field); + } + + end++; + } + + return (NULL); +} + +/* remove_conf_line() + * + * inputs - type of kline to remove + * - pointer to oper removing + * - pat1 pat2 patterns to match + * output - -1 if unsuccessful 0 if no change 1 if change + * side effects - + */ +int +remove_conf_line(ConfType type, struct Client *source_p, const char *pat1, const char *pat2) +{ + const char *filename; + FILE *in, *out; + int pairme=0; + char buf[IRCD_BUFSIZE], buff[IRCD_BUFSIZE], temppath[IRCD_BUFSIZE]; + char *found1; + char *found2; + int oldumask; + + filename = get_conf_name(type); + + if ((in = fopen(filename, "r")) == NULL) + { + sendto_one(source_p, ":%s NOTICE %s :Cannot open %s", me.name, + source_p->name, filename); + return -1; + } + + ircsprintf(temppath, "%s.tmp", filename); + oldumask = umask(0); + + if ((out = fopen(temppath, "w")) == NULL) + { + sendto_one(source_p, ":%s NOTICE %s :Cannot open %s", me.name, + source_p->name, temppath); + fclose(in); + umask(oldumask); + return -1; + } + + umask(oldumask); + oldumask = umask(0); + + while (fgets(buf, sizeof(buf), in) != NULL) + { + if ((*buf == '\0') || (*buf == '#')) + { + if (flush_write(source_p, in, out, buf, temppath) < 0) + return -1; + } + + /* Keep copy of original line, getfield trashes line as it goes */ + strlcpy(buff, buf, sizeof(buff)); + + if ((found1 = getfield(buff)) == NULL) + { + if (flush_write(source_p, in, out, buf, temppath) < 0) + return -1; + continue; + } + + if (pat2 != NULL) + { + if ((found2 = getfield(NULL)) == NULL) + { + if (flush_write(source_p, in, out, buf, temppath) < 0) + return -1; + continue; + } + + if (!irccmp(pat1, found1) && !irccmp(pat2, found2)) + { + pairme = 1; + continue; + } + else + { + if(flush_write(source_p, in, out, buf, temppath) < 0) + return -1; + continue; + } + } + else + { + if (!irccmp(pat1, found1)) + { + pairme = 1; + continue; + } + else + { + if(flush_write(source_p, in, out, buf, temppath) < 0) + return -1; + continue; + } + } + } + + fclose(in); + fclose(out); + +/* The result of the rename should be checked too... oh well */ +/* If there was an error on a write above, then its been reported + * and I am not going to trash the original kline /conf file + */ + + if (pairme == 0) + { + if(temppath != NULL) + (void)unlink(temppath); + return 0; + } + else + { + (void)rename(temppath, filename); + + /* XXX + * This is a very inefficient way of removing a kline/xline etc. + * This next function call forces a complete re-read of all conf + * files, instead of a re-read of the kline/dline etc. files modified + * But, consider how often an /quote unkline etc. is done compared + * to how often a /quote kline is done. Its not a biggie in + * the grand scheme of things. If it does become a biggie, + * we will rewrite it - Dianora + */ + + rehash(0); + return 1; + } +} + +/* + * flush_write() + * + * inputs - pointer to client structure of oper requesting unkline + * - in is the input file descriptor + * - out is the output file descriptor + * - buf is the buffer to write + * - ntowrite is the expected number of character to be written + * - temppath is the temporary file name to be written + * output - -1 for error on write + * - 0 for ok + * side effects - if successful, the buf is written to output file + * if a write failure happesn, and the file pointed to + * by temppath, if its non NULL, is removed. + * + * The idea here is, to be as robust as possible when writing to the + * kline file. + * + * -Dianora + */ +static int +flush_write(struct Client *source_p, FILE *in, FILE* out, + const char *buf, const char *temppath) +{ + int error_on_write = fputs(buf, out) < 0 ? (-1) : (0); + + if (error_on_write) + { + sendto_one(source_p,":%s NOTICE %s :Unable to write to %s aborting", + me.name, source_p->name, temppath); + if(temppath != NULL) + (void)unlink(temppath); + fclose(in); + fclose(out); + } + + return (error_on_write); +} diff --git a/src/dbuf.c b/src/dbuf.c new file mode 100644 index 0000000..1271b86 --- /dev/null +++ b/src/dbuf.c @@ -0,0 +1,112 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * dbuf.c: Supports dynamic data buffers. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "balloc.h" +#include "dbuf.h" +#include "memory.h" + +static BlockHeap *dbuf_heap; + +void +dbuf_init(void) +{ + dbuf_heap = BlockHeapCreate("dbuf", sizeof(struct dbuf_block), DBUF_HEAP_SIZE); +} + +static struct dbuf_block * +dbuf_alloc(struct dbuf_queue *qptr) +{ + struct dbuf_block *block = BlockHeapAlloc(dbuf_heap); + + dlinkAddTail(block, make_dlink_node(), &qptr->blocks); + return block; +} + +void +dbuf_put(struct dbuf_queue *qptr, char *data, size_t count) +{ + struct dbuf_block *last; + size_t amount; + + assert(count > 0); + if (qptr->blocks.tail == NULL) + dbuf_alloc(qptr); + + do { + last = qptr->blocks.tail->data; + + amount = DBUF_BLOCK_SIZE - last->size; + if (!amount) + { + last = dbuf_alloc(qptr); + amount = DBUF_BLOCK_SIZE; + } + if (amount > count) + amount = count; + + memcpy((void *) &last->data[last->size], data, amount); + count -= amount; + last->size += amount; + qptr->total_size += amount; + + data += amount; + + } while (count > 0); +} + +void +dbuf_delete(struct dbuf_queue *qptr, size_t count) +{ + dlink_node *ptr; + struct dbuf_block *first; + + assert(qptr->total_size >= count); + if (count == 0) + return; + + /* free whole blocks first.. */ + while (1) + { + if (!count) + return; + ptr = qptr->blocks.head; + first = ptr->data; + if (count < first->size) + break; + + qptr->total_size -= first->size; + count -= first->size; + dlinkDelete(ptr, &qptr->blocks); + free_dlink_node(ptr); + BlockHeapFree(dbuf_heap, first); + } + + /* ..then remove data from the beginning of the queue */ + first->size -= count; + qptr->total_size -= count; + memmove((void *) &first->data, (void *) &first->data[count], first->size); +} + diff --git a/src/event.c b/src/event.c new file mode 100644 index 0000000..2ddc75d --- /dev/null +++ b/src/event.c @@ -0,0 +1,292 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * event.c: Event functions. + * + * Copyright (C) 1998-2000 Regents of the University of California + * Copyright (C) 2001-2002 Hybrid Development Team + * + * Code borrowed from the squid web cache by Adrian Chadd. + * Original header: + * + * DEBUG: section 41 Event Processing + * AUTHOR: Henrik Nordstrom + * + * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from the + * Internet community. Development is led by Duane Wessels of the + * National Laboratory for Applied Network Research and funded by the + * National Science Foundation. Squid is Copyrighted (C) 1998 by + * the Regents of the University of California. Please see the + * COPYRIGHT file for full details. Squid incorporates software + * developed and/or copyrighted by other sources. Please see the + * CREDITS file for full details. + * + * 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$ + */ + +/* + * How it's used: + * + * Should be pretty self-explanatory. Events are added to the static + * array event_table with a frequency time telling eventRun how often + * to execute it. + */ + +#include "stdinc.h" +#include "list.h" +#include "ircd.h" +#include "event.h" +#include "client.h" +#include "send.h" +#include "memory.h" +#include "log.h" +#include "numeric.h" + +static const char *last_event_ran = NULL; +static struct ev_entry event_table[MAX_EVENTS]; +static time_t event_time_min = -1; +static int eventFind(EVH *func, void *arg); + +/* + * void eventAdd(const char *name, EVH *func, void *arg, time_t when) + * + * Input: Name of event, function to call, arguments to pass, and frequency + * of the event. + * Output: None + * Side Effects: Adds the event to the event list. + */ +void +eventAdd(const char *name, EVH *func, void *arg, time_t when) +{ + int i; + + /* find first inactive index, or use next index */ + for (i = 0; i < MAX_EVENTS; i++) + { + if (event_table[i].active == 0) + { + event_table[i].func = func; + event_table[i].name = name; + event_table[i].arg = arg; + event_table[i].when = CurrentTime + when; + event_table[i].frequency = when; + event_table[i].active = 1; + + if ((event_table[i].when < event_time_min) || (event_time_min == -1)) + event_time_min = event_table[i].when; + + return; + } + } + /* XXX if reach here, its an error */ + ilog(LOG_TYPE_IRCD, "Event table is full! (%d)", i); +} + +/* + * void eventDelete(EVH *func, void *arg) + * + * Input: Function handler, argument that was passed. + * Output: None + * Side Effects: Removes the event from the event list + */ +void +eventDelete(EVH *func, void *arg) +{ + int i = eventFind(func, arg); + + if (i == -1) + return; + + event_table[i].name = NULL; + event_table[i].func = NULL; + event_table[i].arg = NULL; + event_table[i].active = 0; +} + +/* + * void eventAddIsh(const char *name, EVH *func, void *arg, time_t delta_isa) + * + * Input: Name of event, function to call, arguments to pass, and frequency + * of the event. + * Output: None + * Side Effects: Adds the event to the event list within +- 1/3 of the + * specified frequency. + */ +void +eventAddIsh(const char *name, EVH *func, void *arg, time_t delta_ish) +{ + if (delta_ish >= 3.0) + { + const time_t two_third = (2 * delta_ish) / 3; + delta_ish = two_third + ((rand() % 1000) * two_third) / 1000; + /* + * XXX I hate the above magic, I don't even know if its right. + * Grr. -- adrian + */ + } + + eventAdd(name, func, arg, delta_ish); +} + +/* + * void eventRun(void) + * + * Input: None + * Output: None + * Side Effects: Runs pending events in the event list + */ +void +eventRun(void) +{ + int i; + + for (i = 0; i < MAX_EVENTS; i++) + { + if (event_table[i].active && (event_table[i].when <= CurrentTime)) + { + last_event_ran = event_table[i].name; + event_table[i].func(event_table[i].arg); + event_table[i].when = CurrentTime + event_table[i].frequency; + event_time_min = -1; + } + } +} + +/* + * time_t eventNextTime(void) + * + * Input: None + * Output: Specifies the next time eventRun() should be run + * Side Effects: None + */ +time_t +eventNextTime(void) +{ + int i; + + if (event_time_min == -1) + { + for (i = 0; i < MAX_EVENTS; i++) + { + if (event_table[i].active && ((event_table[i].when < event_time_min) || (event_time_min == -1))) + event_time_min = event_table[i].when; + } + } + + return(event_time_min); +} + +/* + * void eventInit(void) + * + * Input: None + * Output: None + * Side Effects: Initializes the event system. + */ +void +eventInit(void) +{ + last_event_ran = NULL; + memset(event_table, 0, sizeof(event_table)); +} + +/* + * int eventFind(EVH *func, void *arg) + * + * Input: Event function and the argument passed to it + * Output: Index to the slow in the event_table + * Side Effects: None + */ +static int +eventFind(EVH *func, void *arg) +{ + int i; + + for (i = 0; i < MAX_EVENTS; i++) + { + if ((event_table[i].func == func) && + (event_table[i].arg == arg) && + event_table[i].active) + return(i); + } + + return(-1); +} + +/* + * void show_events(struct Client *source_p) + * + * Input: Client requesting the event + * Output: List of events + * Side Effects: None + */ +void +show_events(struct Client *source_p) +{ + int i; + + if (last_event_ran) + { + sendto_one(source_p, ":%s %d %s :Last event to run: %s", + me.name, RPL_STATSDEBUG, source_p->name, last_event_ran); + sendto_one(source_p, ":%s %d %s : ", + me.name, RPL_STATSDEBUG, source_p->name); + } + + sendto_one(source_p, + ":%s %d %s : Operation Next Execution", + me.name, RPL_STATSDEBUG, source_p->name); + sendto_one(source_p, + ":%s %d %s : -------------------------------------------", + me.name, RPL_STATSDEBUG, source_p->name); + + for (i = 0; i < MAX_EVENTS; i++) + if (event_table[i].active) + { + sendto_one(source_p, ":%s %d %s : %-28s %-4d seconds", + me.name, RPL_STATSDEBUG, source_p->name, + event_table[i].name, + (int)(event_table[i].when - CurrentTime)); + } + + sendto_one(source_p, ":%s %d %s : ", + me.name, RPL_STATSDEBUG, source_p->name); +} + +/* + * void set_back_events(time_t by) + * Input: Time to set back events by. + * Output: None. + * Side-effects: Sets back all events by "by" seconds. + */ +void +set_back_events(time_t by) +{ + int i; + + for (i = 0; i < MAX_EVENTS; i++) + { + if (event_table[i].when > by) + event_table[i].when -= by; + else + event_table[i].when = 0; + } +} + diff --git a/src/fdlist.c b/src/fdlist.c new file mode 100644 index 0000000..5400ad3 --- /dev/null +++ b/src/fdlist.c @@ -0,0 +1,243 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * fdlist.c: Maintains a list of file descriptors. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "fdlist.h" +#include "client.h" /* struct Client */ +#include "event.h" +#include "ircd.h" /* GlobalSetOptions */ +#include "irc_string.h" +#include "s_bsd.h" /* comm_setselect */ +#include "conf.h" /* ServerInfo */ +#include "send.h" +#include "memory.h" +#include "numeric.h" +#include "s_misc.h" +#include "irc_res.h" + +fde_t *fd_hash[FD_HASH_SIZE]; +fde_t *fd_next_in_loop = NULL; +int number_fd = LEAKED_FDS; +int hard_fdlimit = 0; +struct Callback *fdlimit_cb = NULL; + +static void * +changing_fdlimit(va_list args) +{ + int old_fdlimit = hard_fdlimit; + + hard_fdlimit = va_arg(args, int); + + if (ServerInfo.max_clients > (unsigned int)MAXCLIENTS_MAX) + { + if (old_fdlimit != 0) + sendto_realops_flags(UMODE_ALL, L_ALL, + "HARD_FDLIMIT changed to %d, adjusting MAXCLIENTS to %d", + hard_fdlimit, MAXCLIENTS_MAX); + + ServerInfo.max_clients = MAXCLIENTS_MAX; + } + + return NULL; +} + +void +fdlist_init(void) +{ + memset(&fd_hash, 0, sizeof(fd_hash)); + + fdlimit_cb = register_callback("changing_fdlimit", changing_fdlimit); + eventAddIsh("recalc_fdlimit", recalc_fdlimit, NULL, 58); + recalc_fdlimit(NULL); +} + +void +recalc_fdlimit(void *unused) +{ + int fdmax; + struct rlimit limit; + + if (!getrlimit(RLIMIT_NOFILE, &limit)) + { + limit.rlim_cur = limit.rlim_max; + setrlimit(RLIMIT_NOFILE, &limit); + } + + fdmax = getdtablesize(); + + /* allow MAXCLIENTS_MIN clients even at the cost of MAX_BUFFER and + * some not really LEAKED_FDS */ + fdmax = IRCD_MAX(fdmax, LEAKED_FDS + MAX_BUFFER + MAXCLIENTS_MIN); + + /* under no condition shall this raise over 65536 + * for example user ip heap is sized 2*hard_fdlimit */ + fdmax = IRCD_MIN(fdmax, 65536); + + if (fdmax != hard_fdlimit) + execute_callback(fdlimit_cb, fdmax); +} + +static inline unsigned int +hash_fd(int fd) +{ + return (((unsigned) fd) % FD_HASH_SIZE); +} + +fde_t * +lookup_fd(int fd) +{ + fde_t *F = fd_hash[hash_fd(fd)]; + + while (F) + { + if (F->fd == fd) + return (F); + F = F->hnext; + } + + return (NULL); +} + +/* Called to open a given filedescriptor */ +void +fd_open(fde_t *F, int fd, int is_socket, const char *desc) +{ + unsigned int hashv = hash_fd(fd); + assert(fd >= 0); + + F->fd = fd; + F->comm_index = -1; + if (desc) + strlcpy(F->desc, desc, sizeof(F->desc)); + /* Note: normally we'd have to clear the other flags, + * but currently F is always cleared before calling us.. */ + F->flags.open = 1; + F->flags.is_socket = is_socket; + F->hnext = fd_hash[hashv]; + fd_hash[hashv] = F; + + number_fd++; +} + +/* Called to close a given filedescriptor */ +void +fd_close(fde_t *F) +{ + unsigned int hashv = hash_fd(F->fd); + + if (F == fd_next_in_loop) + fd_next_in_loop = F->hnext; + + if (F->flags.is_socket) + comm_setselect(F, COMM_SELECT_WRITE | COMM_SELECT_READ, NULL, NULL, 0); + + delete_resolver_queries(F); + +#ifdef HAVE_LIBCRYPTO + if (F->ssl) + SSL_free(F->ssl); +#endif + + if (fd_hash[hashv] == F) + fd_hash[hashv] = F->hnext; + else { + fde_t *prev; + + /* let it core if not found */ + for (prev = fd_hash[hashv]; prev->hnext != F; prev = prev->hnext) + ; + prev->hnext = F->hnext; + } + + /* Unlike squid, we're actually closing the FD here! -- adrian */ + close(F->fd); + number_fd--; + + memset(F, 0, sizeof(fde_t)); +} + +/* + * fd_dump() - dump the list of active filedescriptors + */ +void +fd_dump(struct Client *source_p) +{ + int i; + fde_t *F; + + for (i = 0; i < FD_HASH_SIZE; i++) + for (F = fd_hash[i]; F != NULL; F = F->hnext) + sendto_one(source_p, ":%s %d %s :fd %-5d desc '%s'", + me.name, RPL_STATSDEBUG, source_p->name, + F->fd, F->desc); +} + +/* + * fd_note() - set the fd note + * + * Note: must be careful not to overflow fd_table[fd].desc when + * calling. + */ +void +fd_note(fde_t *F, const char *format, ...) +{ + va_list args; + + if (format != NULL) + { + va_start(args, format); + vsnprintf(F->desc, sizeof(F->desc), format, args); + va_end(args); + } + else + F->desc[0] = '\0'; +} + +/* Make sure stdio descriptors (0-2) and profiler descriptor (3) + * always go somewhere harmless. Use -foreground for profiling + * or executing from gdb */ +void +close_standard_fds(void) +{ + int i; + + for (i = 0; i < LOWEST_SAFE_FD; i++) + { + close(i); + if (open("/dev/null", O_RDWR) < 0) + exit(-1); /* we're hosed if we can't even open /dev/null */ + } +} + +void +close_fds(fde_t *one) +{ + int i; + fde_t *F; + + for (i = 0; i < FD_HASH_SIZE; i++) + for (F = fd_hash[i]; F != NULL; F = F->hnext) + if (F != one) + close(F->fd); +} diff --git a/src/getopt.c b/src/getopt.c new file mode 100644 index 0000000..5b863d3 --- /dev/null +++ b/src/getopt.c @@ -0,0 +1,127 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * getopt.c: Uses getopt to fetch the command line options. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "ircd_getopt.h" + +#define OPTCHAR '-' + + +static void +usage(const char *name, const struct lgetopt *opts) +{ + unsigned int i; + + fprintf(stderr, "Usage: %s [options]\n", name); + fprintf(stderr, "Where valid options are:\n"); + + for (i = 0; opts[i].opt; ++i) + fprintf(stderr, "\t%c%-10s %-20s%s\n", OPTCHAR, opts[i].opt, + (opts[i].argtype == YESNO || opts[i].argtype == USAGE) ? "" : + opts[i].argtype == INTEGER ? "<number>" : "<string>", + opts[i].desc); + + exit(EXIT_FAILURE); +} + +void +parseargs(int *argc, char ***argv, struct lgetopt *opts) +{ + unsigned int i; + const char *progname = (*argv)[0]; + + /* loop through each argument */ + while (1) + { + int found = 0; + + (*argc)--; + (*argv)++; + + if (*argc < 1 || (*argv)[0][0] != OPTCHAR) + return; + + (*argv)[0]++; + + /* search through our argument list, and see if it matches */ + for (i = 0; opts[i].opt; i++) + { + if (!strcmp(opts[i].opt, (*argv)[0])) + { + /* found our argument */ + found = 1; + + switch (opts[i].argtype) + { + case YESNO: + *((int *)opts[i].argloc) = 1; + break; + + case INTEGER: + if (*argc < 2) + { + fprintf(stderr, "Error: option '%c%s' requires an argument\n", + OPTCHAR, opts[i].opt); + usage((*argv)[0], opts); + } + + *((int *)opts[i].argloc) = atoi((*argv)[1]); + (*argc)--; + (*argv)++; + break; + + case STRING: + if (*argc < 2) + { + fprintf(stderr, "error: option '%c%s' requires an argument\n", + OPTCHAR, opts[i].opt); + usage(progname, opts); + } + + *((char**)opts[i].argloc) = malloc(strlen((*argv)[1]) + 1); + strcpy(*((char**)opts[i].argloc), (*argv)[1]); + (*argc)--; + (*argv)++; + break; + + case USAGE: + usage(progname, opts); + /* NOTREACHED */ + + default: + fprintf(stderr, "Error: internal error in parseargs() at %s:%d\n", + __FILE__, __LINE__); + exit(EXIT_FAILURE); + } + } + } + + if (!found) + { + fprintf(stderr, "error: unknown argument '%c%s'\n", + OPTCHAR, (*argv)[0]); + usage(progname, opts); + } + } +} diff --git a/src/hash.c b/src/hash.c new file mode 100644 index 0000000..d0b0a55 --- /dev/null +++ b/src/hash.c @@ -0,0 +1,907 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * hash.c: Maintains hashtables. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "balloc.h" +#include "conf.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "modules.h" +#include "hash.h" +#include "resv.h" +#include "rng_mt.h" +#include "userhost.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "send.h" +#include "memory.h" +#include "dbuf.h" +#include "s_user.h" + + +static BlockHeap *userhost_heap = NULL; +static BlockHeap *namehost_heap = NULL; + +static unsigned int hashf_xor_key = 0; + +/* The actual hash tables, They MUST be of the same HASHSIZE, variable + * size tables could be supported but the rehash routine should also + * rebuild the transformation maps, I kept the tables of equal size + * so that I can use one hash function. + */ +static struct Client *idTable[HASHSIZE]; +static struct Client *clientTable[HASHSIZE]; +static struct Channel *channelTable[HASHSIZE]; +static struct UserHost *userhostTable[HASHSIZE]; +static struct ResvChannel *resvchannelTable[HASHSIZE]; + + +/* init_hash() + * + * inputs - NONE + * output - NONE + * side effects - Initialize the maps used by hash + * functions and clear the tables + */ +void +init_hash(void) +{ + /* Default the userhost/namehost sizes to CLIENT_HEAP_SIZE for now, + * should be a good close approximation anyway + * - Dianora + */ + userhost_heap = BlockHeapCreate("userhost", sizeof(struct UserHost), CLIENT_HEAP_SIZE); + namehost_heap = BlockHeapCreate("namehost", sizeof(struct NameHost), CLIENT_HEAP_SIZE); + + hashf_xor_key = genrand_int32() % 256; /* better than nothing --adx */ +} + +/* + * New hash function based on the Fowler/Noll/Vo (FNV) algorithm from + * http://www.isthe.com/chongo/tech/comp/fnv/ + * + * Here, we use the FNV-1 method, which gives slightly better results + * than FNV-1a. -Michael + */ +unsigned int +strhash(const char *name) +{ + const unsigned char *p = (const unsigned char *)name; + unsigned int hval = FNV1_32_INIT; + + if (*p == '\0') + return 0; + for (; *p != '\0'; ++p) + { + hval += (hval << 1) + (hval << 4) + (hval << 7) + + (hval << 8) + (hval << 24); + hval ^= (ToLower(*p) ^ hashf_xor_key); + } + + return (hval >> FNV1_32_BITS) ^ (hval & ((1 << FNV1_32_BITS) - 1)); +} + +/************************** Externally visible functions ********************/ + +/* Optimization note: in these functions I supposed that the CSE optimization + * (Common Subexpression Elimination) does its work decently, this means that + * I avoided introducing new variables to do the work myself and I did let + * the optimizer play with more free registers, actual tests proved this + * solution to be faster than doing things like tmp2=tmp->hnext... and then + * use tmp2 myself which would have given less freedom to the optimizer. + */ + +/* hash_add_client() + * + * inputs - pointer to client + * output - NONE + * side effects - Adds a client's name in the proper hash linked + * list, can't fail, client_p must have a non-null + * name or expect a coredump, the name is infact + * taken from client_p->name + */ +void +hash_add_client(struct Client *client_p) +{ + unsigned int hashv = strhash(client_p->name); + + client_p->hnext = clientTable[hashv]; + clientTable[hashv] = client_p; +} + +/* hash_add_channel() + * + * inputs - pointer to channel + * output - NONE + * side effects - Adds a channel's name in the proper hash linked + * list, can't fail. chptr must have a non-null name + * or expect a coredump. As before the name is taken + * from chptr->name, we do hash its entire lenght + * since this proved to be statistically faster + */ +void +hash_add_channel(struct Channel *chptr) +{ + unsigned int hashv = strhash(chptr->chname); + + chptr->hnextch = channelTable[hashv]; + channelTable[hashv] = chptr; +} + +void +hash_add_resv(struct ResvChannel *chptr) +{ + unsigned int hashv = strhash(chptr->name); + + chptr->hnext = resvchannelTable[hashv]; + resvchannelTable[hashv] = chptr; +} + +void +hash_add_userhost(struct UserHost *userhost) +{ + unsigned int hashv = strhash(userhost->host); + + userhost->next = userhostTable[hashv]; + userhostTable[hashv] = userhost; +} + +void +hash_add_id(struct Client *client_p) +{ + unsigned int hashv = strhash(client_p->id); + + client_p->idhnext = idTable[hashv]; + idTable[hashv] = client_p; +} + +/* hash_del_id() + * + * inputs - pointer to client + * output - NONE + * side effects - Removes an ID from the hash linked list + */ +void +hash_del_id(struct Client *client_p) +{ + unsigned int hashv = strhash(client_p->id); + struct Client *tmp = idTable[hashv]; + + if (tmp != NULL) + { + if (tmp == client_p) + { + idTable[hashv] = client_p->idhnext; + client_p->idhnext = client_p; + } + else + { + while (tmp->idhnext != client_p) + if ((tmp = tmp->idhnext) == NULL) + return; + + tmp->idhnext = tmp->idhnext->idhnext; + client_p->idhnext = client_p; + } + } +} + +/* hash_del_client() + * + * inputs - pointer to client + * output - NONE + * side effects - Removes a Client's name from the hash linked list + */ +void +hash_del_client(struct Client *client_p) +{ + unsigned int hashv = strhash(client_p->name); + struct Client *tmp = clientTable[hashv]; + + if (tmp != NULL) + { + if (tmp == client_p) + { + clientTable[hashv] = client_p->hnext; + client_p->hnext = client_p; + } + else + { + while (tmp->hnext != client_p) + if ((tmp = tmp->hnext) == NULL) + return; + + tmp->hnext = tmp->hnext->hnext; + client_p->hnext = client_p; + } + } +} + +/* hash_del_userhost() + * + * inputs - pointer to userhost + * output - NONE + * side effects - Removes a userhost from the hash linked list + */ +void +hash_del_userhost(struct UserHost *userhost) +{ + unsigned int hashv = strhash(userhost->host); + struct UserHost *tmp = userhostTable[hashv]; + + if (tmp != NULL) + { + if (tmp == userhost) + { + userhostTable[hashv] = userhost->next; + userhost->next = userhost; + } + else + { + while (tmp->next != userhost) + if ((tmp = tmp->next) == NULL) + return; + + tmp->next = tmp->next->next; + userhost->next = userhost; + } + } +} + +/* hash_del_channel() + * + * inputs - pointer to client + * output - NONE + * side effects - Removes the channel's name from the corresponding + * hash linked list + */ +void +hash_del_channel(struct Channel *chptr) +{ + unsigned int hashv = strhash(chptr->chname); + struct Channel *tmp = channelTable[hashv]; + + if (tmp != NULL) + { + if (tmp == chptr) + { + channelTable[hashv] = chptr->hnextch; + chptr->hnextch = chptr; + } + else + { + while (tmp->hnextch != chptr) + if ((tmp = tmp->hnextch) == NULL) + return; + + tmp->hnextch = tmp->hnextch->hnextch; + chptr->hnextch = chptr; + } + } +} + +void +hash_del_resv(struct ResvChannel *chptr) +{ + unsigned int hashv = strhash(chptr->name); + struct ResvChannel *tmp = resvchannelTable[hashv]; + + if (tmp != NULL) + { + if (tmp == chptr) + { + resvchannelTable[hashv] = chptr->hnext; + chptr->hnext = chptr; + } + else + { + while (tmp->hnext != chptr) + if ((tmp = tmp->hnext) == NULL) + return; + + tmp->hnext = tmp->hnext->hnext; + chptr->hnext = chptr; + } + } +} + +/* hash_find_client() + * + * inputs - pointer to name + * output - NONE + * side effects - New semantics: finds a client whose name is 'name' + * if can't find one returns NULL. If it finds one moves + * it to the top of the list and returns it. + */ +struct Client * +hash_find_client(const char *name) +{ + unsigned int hashv = strhash(name); + struct Client *client_p; + + if ((client_p = clientTable[hashv]) != NULL) + { + if (irccmp(name, client_p->name)) + { + struct Client *prev; + + while (prev = client_p, (client_p = client_p->hnext) != NULL) + { + if (!irccmp(name, client_p->name)) + { + prev->hnext = client_p->hnext; + client_p->hnext = clientTable[hashv]; + clientTable[hashv] = client_p; + break; + } + } + } + } + + return client_p; +} + +struct Client * +hash_find_id(const char *name) +{ + unsigned int hashv = strhash(name); + struct Client *client_p; + + if ((client_p = idTable[hashv]) != NULL) + { + if (strcmp(name, client_p->id)) + { + struct Client *prev; + + while (prev = client_p, (client_p = client_p->idhnext) != NULL) + { + if (!strcmp(name, client_p->id)) + { + prev->idhnext = client_p->idhnext; + client_p->idhnext = idTable[hashv]; + idTable[hashv] = client_p; + break; + } + } + } + } + + return client_p; +} + +struct Client * +hash_find_server(const char *name) +{ + unsigned int hashv = strhash(name); + struct Client *client_p = NULL; + + if (IsDigit(*name) && strlen(name) == IRC_MAXSID) + return hash_find_id(name); + + if ((client_p = clientTable[hashv]) != NULL) + { + if ((!IsServer(client_p) && !IsMe(client_p)) || + irccmp(name, client_p->name)) + { + struct Client *prev; + + while (prev = client_p, (client_p = client_p->hnext) != NULL) + { + if ((IsServer(client_p) || IsMe(client_p)) && + !irccmp(name, client_p->name)) + { + prev->hnext = client_p->hnext; + client_p->hnext = clientTable[hashv]; + clientTable[hashv] = client_p; + break; + } + } + } + } + + return client_p; +} + +/* hash_find_channel() + * + * inputs - pointer to name + * output - NONE + * side effects - New semantics: finds a channel whose name is 'name', + * if can't find one returns NULL, if can find it moves + * it to the top of the list and returns it. + */ +struct Channel * +hash_find_channel(const char *name) +{ + unsigned int hashv = strhash(name); + struct Channel *chptr = NULL; + + if ((chptr = channelTable[hashv]) != NULL) + { + if (irccmp(name, chptr->chname)) + { + struct Channel *prev; + + while (prev = chptr, (chptr = chptr->hnextch) != NULL) + { + if (!irccmp(name, chptr->chname)) + { + prev->hnextch = chptr->hnextch; + chptr->hnextch = channelTable[hashv]; + channelTable[hashv] = chptr; + break; + } + } + } + } + + return chptr; +} + +/* hash_get_bucket(int type, unsigned int hashv) + * + * inputs - hash value (must be between 0 and HASHSIZE - 1) + * output - NONE + * returns - pointer to first channel in channelTable[hashv] + * if that exists; + * NULL if there is no channel in that place; + * NULL if hashv is an invalid number. + * side effects - NONE + */ +void * +hash_get_bucket(int type, unsigned int hashv) +{ + assert(hashv < HASHSIZE); + if (hashv >= HASHSIZE) + return NULL; + + switch (type) + { + case HASH_TYPE_ID: + return idTable[hashv]; + break; + case HASH_TYPE_CHANNEL: + return channelTable[hashv]; + break; + case HASH_TYPE_CLIENT: + return clientTable[hashv]; + break; + case HASH_TYPE_USERHOST: + return userhostTable[hashv]; + break; + case HASH_TYPE_RESERVED: + return resvchannelTable[hashv]; + break; + default: + assert(0); + } + + return NULL; +} + +/* hash_find_resv() + * + * inputs - pointer to name + * output - NONE + * side effects - New semantics: finds a reserved channel whose name is 'name', + * if can't find one returns NULL, if can find it moves + * it to the top of the list and returns it. + */ +struct ResvChannel * +hash_find_resv(const char *name) +{ + unsigned int hashv = strhash(name); + struct ResvChannel *chptr; + + if ((chptr = resvchannelTable[hashv]) != NULL) + { + if (irccmp(name, chptr->name)) + { + struct ResvChannel *prev; + + while (prev = chptr, (chptr = chptr->hnext) != NULL) + { + if (!irccmp(name, chptr->name)) + { + prev->hnext = chptr->hnext; + chptr->hnext = resvchannelTable[hashv]; + resvchannelTable[hashv] = chptr; + break; + } + } + } + } + + return chptr; +} + +struct UserHost * +hash_find_userhost(const char *host) +{ + unsigned int hashv = strhash(host); + struct UserHost *userhost; + + if ((userhost = userhostTable[hashv])) + { + if (irccmp(host, userhost->host)) + { + struct UserHost *prev; + + while (prev = userhost, (userhost = userhost->next) != NULL) + { + if (!irccmp(host, userhost->host)) + { + prev->next = userhost->next; + userhost->next = userhostTable[hashv]; + userhostTable[hashv] = userhost; + break; + } + } + } + } + + return userhost; +} + +/* count_user_host() + * + * inputs - user name + * - hostname + * - int flag 1 if global, 0 if local + * - pointer to where global count should go + * - pointer to where local count should go + * - pointer to where identd count should go (local clients only) + * output - none + * side effects - + */ +void +count_user_host(const char *user, const char *host, int *global_p, + int *local_p, int *icount_p) +{ + dlink_node *ptr; + struct UserHost *found_userhost; + struct NameHost *nameh; + + if ((found_userhost = hash_find_userhost(host)) == NULL) + return; + + DLINK_FOREACH(ptr, found_userhost->list.head) + { + nameh = ptr->data; + + if (!irccmp(user, nameh->name)) + { + if (global_p != NULL) + *global_p = nameh->gcount; + if (local_p != NULL) + *local_p = nameh->lcount; + if (icount_p != NULL) + *icount_p = nameh->icount; + return; + } + } +} + +/* find_or_add_userhost() + * + * inputs - host name + * output - none + * side effects - find UserHost * for given host name + */ +static struct UserHost * +find_or_add_userhost(const char *host) +{ + struct UserHost *userhost; + + if ((userhost = hash_find_userhost(host)) != NULL) + return userhost; + + userhost = BlockHeapAlloc(userhost_heap); + strlcpy(userhost->host, host, sizeof(userhost->host)); + hash_add_userhost(userhost); + + return userhost; +} + +/* add_user_host() + * + * inputs - user name + * - hostname + * - int flag 1 if global, 0 if local + * output - none + * side effects - add given user@host to hash tables + */ +void +add_user_host(const char *user, const char *host, int global) +{ + dlink_node *ptr; + struct UserHost *found_userhost; + struct NameHost *nameh; + int hasident = 1; + + if (*user == '~') + { + hasident = 0; + ++user; + } + + if ((found_userhost = find_or_add_userhost(host)) == NULL) + return; + + DLINK_FOREACH(ptr, found_userhost->list.head) + { + nameh = ptr->data; + + if (!irccmp(user, nameh->name)) + { + nameh->gcount++; + + if (!global) + { + if (hasident) + nameh->icount++; + nameh->lcount++; + } + + return; + } + } + + nameh = BlockHeapAlloc(namehost_heap); + strlcpy(nameh->name, user, sizeof(nameh->name)); + + nameh->gcount = 1; + + if (!global) + { + if (hasident) + nameh->icount = 1; + nameh->lcount = 1; + } + + dlinkAdd(nameh, &nameh->node, &found_userhost->list); +} + +/* delete_user_host() + * + * inputs - user name + * - hostname + * - int flag 1 if global, 0 if local + * output - none + * side effects - delete given user@host to hash tables + */ +void +delete_user_host(const char *user, const char *host, int global) +{ + dlink_node *ptr = NULL, *next_ptr = NULL; + struct UserHost *found_userhost; + struct NameHost *nameh; + int hasident = 1; + + if (*user == '~') + { + hasident = 0; + ++user; + } + + if ((found_userhost = hash_find_userhost(host)) == NULL) + return; + + DLINK_FOREACH_SAFE(ptr, next_ptr, found_userhost->list.head) + { + nameh = ptr->data; + + if (!irccmp(user, nameh->name)) + { + if (nameh->gcount > 0) + nameh->gcount--; + if (!global) + { + if (nameh->lcount > 0) + nameh->lcount--; + if (hasident && nameh->icount > 0) + nameh->icount--; + } + + if (nameh->gcount == 0 && nameh->lcount == 0) + { + dlinkDelete(&nameh->node, &found_userhost->list); + BlockHeapFree(namehost_heap, nameh); + } + + if (dlink_list_length(&found_userhost->list) == 0) + { + hash_del_userhost(found_userhost); + BlockHeapFree(userhost_heap, found_userhost); + } + + return; + } + } +} + +/* + * Safe list code. + * + * The idea is really quite simple. As the link lists pointed to in + * each "bucket" of the channel hash table are traversed atomically + * there is no locking needed. Overall, yes, inconsistent reported + * state can still happen, but normally this isn't a big deal. + * I don't like sticking the code into hash.c but oh well. Moreover, + * if a hash isn't used in future, oops. + * + * - Dianora + */ + +/* exceeding_sendq() + * + * inputs - pointer to client to check + * output - 1 if client is in danger of blowing its sendq + * 0 if it is not. + * side effects - + * + * Sendq limit is fairly conservative at 1/2 (In original anyway) + */ +static int +exceeding_sendq(struct Client *to) +{ + if (dbuf_length(&to->localClient->buf_sendq) > (get_sendq(to) / 2)) + return 1; + else + return 0; +} + +void +free_list_task(struct ListTask *lt, struct Client *source_p) +{ + dlink_node *dl, *dln; + + if ((dl = dlinkFindDelete(&listing_client_list, source_p)) != NULL) + free_dlink_node(dl); + + DLINK_FOREACH_SAFE(dl, dln, lt->show_mask.head) + { + MyFree(dl->data); + free_dlink_node(dl); + } + + DLINK_FOREACH_SAFE(dl, dln, lt->hide_mask.head) + { + MyFree(dl->data); + free_dlink_node(dl); + } + + MyFree(lt); + + if (MyConnect(source_p)) + source_p->localClient->list_task = NULL; +} + +/* list_allow_channel() + * + * inputs - channel name + * - pointer to a list task + * output - 1 if the channel is to be displayed + * 0 otherwise + * side effects - + */ +static int +list_allow_channel(const char *chname, struct ListTask *lt) +{ + dlink_node *dl = NULL; + + DLINK_FOREACH(dl, lt->show_mask.head) + if (!match_chan(dl->data, chname)) + return 0; + + DLINK_FOREACH(dl, lt->hide_mask.head) + if (match_chan(dl->data, chname)) + return 0; + + return 1; +} + +/* list_one_channel() + * + * inputs - client pointer to return result to + * - pointer to channel to list + * - pointer to ListTask structure + * output - none + * side effects - + */ +static void +list_one_channel(struct Client *source_p, struct Channel *chptr, + struct ListTask *list_task) +{ + if (SecretChannel(chptr) && !IsMember(source_p, chptr)) + return; + if (dlink_list_length(&chptr->members) < list_task->users_min || + dlink_list_length(&chptr->members) > list_task->users_max || + (chptr->channelts != 0 && + ((unsigned int)chptr->channelts < list_task->created_min || + (unsigned int)chptr->channelts > list_task->created_max)) || + (unsigned int)chptr->topic_time < list_task->topicts_min || + (chptr->topic_time ? (unsigned int)chptr->topic_time : UINT_MAX) > + list_task->topicts_max) + return; + + if (!list_allow_channel(chptr->chname, list_task)) + return; + sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name, + chptr->chname, dlink_list_length(&chptr->members), + chptr->topic); +} + +/* safe_list_channels() + * + * inputs - pointer to client requesting list + * output - 0/1 + * side effects - safely list all channels to source_p + * + * Walk the channel buckets, ensure all pointers in a bucket are + * traversed before blocking on a sendq. This means, no locking is needed. + * + * N.B. This code is "remote" safe, but is not currently used for + * remote clients. + * + * - Dianora + */ +void +safe_list_channels(struct Client *source_p, struct ListTask *list_task, + int only_unmasked_channels) +{ + struct Channel *chptr = NULL; + + if (!only_unmasked_channels) + { + unsigned int i; + + for (i = list_task->hash_index; i < HASHSIZE; ++i) + { + if (exceeding_sendq(source_p->from)) + { + list_task->hash_index = i; + return; /* still more to do */ + } + + for (chptr = channelTable[i]; chptr; chptr = chptr->hnextch) + list_one_channel(source_p, chptr, list_task); + } + } + else + { + dlink_node *dl; + + DLINK_FOREACH(dl, list_task->show_mask.head) + if ((chptr = hash_find_channel(dl->data)) != NULL) + list_one_channel(source_p, chptr, list_task); + } + + free_list_task(list_task, source_p); + sendto_one(source_p, form_str(RPL_LISTEND), + me.name, source_p->name); +} diff --git a/src/hook.c b/src/hook.c new file mode 100644 index 0000000..9b4b1c5 --- /dev/null +++ b/src/hook.c @@ -0,0 +1,216 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2003 Piotr Nizynski, Advanced IRC Services Project Team + * Copyright (C) 2005 Hybrid 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 + * + * $Id$ + */ + +/*! \file hook.c + * \brief Provides a generic event hooking interface. + * \version $Id$ + */ + +#include "stdinc.h" +#include "list.h" +#include "hook.h" +#include "ircd.h" +#include "memory.h" +#include "numeric.h" +#include "irc_string.h" +#include "send.h" +#include "client.h" + +static dlink_list callback_list = { NULL, NULL, 0} ; + +/*! \brief Creates a new callback. + * \param name name used to identify the callback + * (can be NULL for anonymous callbacks) + * \param func initial function attached to the chain + * (can be NULL to create an empty chain) + * \return pointer to Callback structure or NULL if already exists + * \note Once registered, a callback should never be freed! + * That's because there may be modules which depend on it + * (even if no functions are attached). That's also why + * we dynamically allocate the struct here -- we don't want + * to allow anyone to place it in module data, which can be + * unloaded at any time. + */ +struct Callback * +register_callback(const char *name, CBFUNC *func) +{ + struct Callback *cb = NULL; + + if (name != NULL) + { + if ((cb = find_callback(name)) != NULL) + { + if (func != NULL) + dlinkAddTail(func, MyMalloc(sizeof(dlink_node)), &cb->chain); + + return cb; + } + } + + cb = MyMalloc(sizeof(struct Callback)); + if (func != NULL) + dlinkAdd(func, MyMalloc(sizeof(dlink_node)), &cb->chain); + + if (name != NULL) + { + DupString(cb->name, name); + dlinkAdd(cb, &cb->node, &callback_list); + } + + return cb; +} + +/*! \brief Passes control down the callback hook chain. + * \param cb pointer to Callback structure + * \param ... argument to pass + * \return function return value + */ +void * +execute_callback(struct Callback *cb, ...) +{ + void *res; + va_list args; + + cb->called++; + cb->last = CurrentTime; + + if (!is_callback_present(cb)) + return NULL; + + va_start(args, cb); + res = ((CBFUNC *) cb->chain.head->data)(args); + va_end(args); + + return res; +} + +/*! \brief Called by a hook function to pass code flow further + * in the hook chain. + * \param this_hook pointer to dlink_node of the current hook function + * \param ... (original or modified) arguments to be passed + * \return callback return value + */ +void * +pass_callback(dlink_node *this_hook, ...) +{ + void *res; + va_list args; + + if (this_hook->next == NULL) + return NULL; /* reached the last one */ + + va_start(args, this_hook); + res = ((CBFUNC *) this_hook->next->data)(args); + va_end(args); + + return res; +} + +/*! \brief Finds a named callback. + * \param name name of the callback + * \return pointer to Callback structure or NULL if not found + */ +struct Callback * +find_callback(const char *name) +{ + dlink_node *ptr; + + DLINK_FOREACH(ptr, callback_list.head) + { + struct Callback *cb = ptr->data; + + if (!irccmp(cb->name, name)) + return cb; + } + + return NULL; +} + +/*! \brief Installs a hook for the given callback. + * + * The new hook is installed at the beginning of the chain, + * so it has full control over functions installed earlier. + * + * \param cb pointer to Callback structure + * \param hook address of hook function + * \return pointer to dlink_node of the hook (used when passing + * control to the next hook in the chain); + * valid till uninstall_hook() is called + */ +dlink_node * +install_hook(struct Callback *cb, CBFUNC *hook) +{ + dlink_node *node = MyMalloc(sizeof(dlink_node)); + + dlinkAdd(hook, node, &cb->chain); + return node; +} + +/*! \brief Removes a specific hook for the given callback. + * \param cb pointer to Callback structure + * \param hook address of hook function + */ +void +uninstall_hook(struct Callback *cb, CBFUNC *hook) +{ + /* let it core if not found */ + dlink_node *ptr = dlinkFind(&cb->chain, hook); + + dlinkDelete(ptr, &cb->chain); + MyFree(ptr); +} + +/*! \brief Displays registered callbacks and lengths of their hook chains. + * (This is the handler of /stats h) + * \param source_p pointer to struct Client + */ +void +stats_hooks(struct Client *source_p) +{ + dlink_node *ptr; + char lastused[32]; + + sendto_one(source_p, ":%s %d %s : %-20s %-20s Used Hooks", me.name, + RPL_STATSDEBUG, source_p->name, "Callback", "Last Execution"); + sendto_one(source_p, ":%s %d %s : ------------------------------------" + "--------------------", me.name, RPL_STATSDEBUG, source_p->name); + + DLINK_FOREACH(ptr, callback_list.head) + { + struct Callback *cb = ptr->data; + + if (cb->last != 0) + snprintf(lastused, sizeof(lastused), "%d seconds ago", + (int) (CurrentTime - cb->last)); + else + strcpy(lastused, "NEVER"); + + sendto_one(source_p, ":%s %d %s : %-20s %-20s %-8u %d", me.name, + RPL_STATSDEBUG, source_p->name, cb->name, lastused, cb->called, + dlink_list_length(&cb->chain)); + } + + sendto_one(source_p, ":%s %d %s : ", me.name, RPL_STATSDEBUG, + source_p->name); +} diff --git a/src/hostmask.c b/src/hostmask.c new file mode 100644 index 0000000..f7cca41 --- /dev/null +++ b/src/hostmask.c @@ -0,0 +1,820 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * hostmask.c: Code to efficiently find IP & hostmask based configs. + * + * Copyright (C) 2005 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "memory.h" +#include "ircd_defs.h" +#include "list.h" +#include "conf.h" +#include "hostmask.h" +#include "send.h" +#include "irc_string.h" +#include "ircd.h" + + +#define DigitParse(ch) do { \ + if (ch >= '0' && ch <= '9') \ + ch = ch - '0'; \ + else if (ch >= 'A' && ch <= 'F') \ + ch = ch - 'A' + 10; \ + else if (ch >= 'a' && ch <= 'f') \ + ch = ch - 'a' + 10; \ + } while (0); + +/* The mask parser/type determination code... */ + +/* int try_parse_v6_netmask(const char *, struct irc_ssaddr *, int *); + * Input: A possible IPV6 address as a string. + * Output: An integer describing whether it is an IPV6 or hostmask, + * an address(if it is IPV6), a bitlength(if it is IPV6). + * Side effects: None + * Comments: Called from parse_netmask + */ +/* Fixed so ::/0 (any IPv6 address) is valid + Also a bug in DigitParse above. + -Gozem 2002-07-19 gozem@linux.nu +*/ +#ifdef IPV6 +static int +try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b) +{ + const char *p; + char c; + int d[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + int dp = 0; + int nyble = 4; + int finsert = -1; + int bits = 128; + int deficit = 0; + short dc[8]; + struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr; + + for (p = text; (c = *p); p++) + if (IsXDigit(c)) + { + if (nyble == 0) + return HM_HOST; + DigitParse(c); + d[dp] |= c << (4 * --nyble); + } + else if (c == ':') + { + if (p > text && *(p - 1) == ':') + { + if (finsert >= 0) + return HM_HOST; + finsert = dp; + } + else + { + /* If there were less than 4 hex digits, e.g. :ABC: shift right + * so we don't interpret it as ABC0 -A1kmm */ + d[dp] = d[dp] >> 4 * nyble; + nyble = 4; + if (++dp >= 8) + return HM_HOST; + } + } + else if (c == '*') + { + /* * must be last, and * is ambiguous if there is a ::... -A1kmm */ + if (finsert >= 0 || *(p + 1) || dp == 0 || *(p - 1) != ':') + return HM_HOST; + bits = dp * 16; + } + else if (c == '/') + { + char *after; + + d[dp] = d[dp] >> 4 * nyble; + dp++; + bits = strtoul(p + 1, &after, 10); + + if (bits < 0 || *after) + return HM_HOST; + if (bits > dp * 4 && !(finsert >= 0 && bits <= 128)) + return HM_HOST; + break; + } + else + return HM_HOST; + + d[dp] = d[dp] >> 4 * nyble; + + if (c == 0) + dp++; + if (finsert < 0 && bits == 0) + bits = dp * 16; + + /* How many words are missing? -A1kmm */ + deficit = bits / 16 + ((bits % 16) ? 1 : 0) - dp; + + /* Now fill in the gaps(from ::) in the copied table... -A1kmm */ + for (dp = 0, nyble = 0; dp < 8; dp++) + { + if (nyble == finsert && deficit) + { + dc[dp] = 0; + deficit--; + } + else + dc[dp] = d[nyble++]; + } + + /* Set unused bits to 0... -A1kmm */ + if (bits < 128 && (bits % 16 != 0)) + dc[bits / 16] &= ~((1 << (15 - bits % 16)) - 1); + for (dp = bits / 16 + (bits % 16 ? 1 : 0); dp < 8; dp++) + dc[dp] = 0; + + /* And assign... -A1kmm */ + if (addr) + for (dp = 0; dp < 8; dp++) + /* The cast is a kludge to make netbsd work. */ + ((unsigned short *)&v6->sin6_addr)[dp] = htons(dc[dp]); + + if (b != NULL) + *b = bits; + return HM_IPV6; +} +#endif + +/* int try_parse_v4_netmask(const char *, struct irc_ssaddr *, int *); + * Input: A possible IPV4 address as a string. + * Output: An integer describing whether it is an IPV4 or hostmask, + * an address(if it is IPV4), a bitlength(if it is IPV4). + * Side effects: None + * Comments: Called from parse_netmask + */ +static int +try_parse_v4_netmask(const char *text, struct irc_ssaddr *addr, int *b) +{ + const char *p; + const char *digits[4]; + unsigned char addb[4]; + int n = 0, bits = 0; + char c; + struct sockaddr_in *v4 = (struct sockaddr_in *)addr; + + digits[n++] = text; + + for (p = text; (c = *p); p++) + if (c >= '0' && c <= '9') /* empty */ + ; + else if (c == '.') + { + if (n >= 4) + return HM_HOST; + + digits[n++] = p + 1; + } + else if (c == '*') + { + if (*(p + 1) || n == 0 || *(p - 1) != '.') + return HM_HOST; + + bits = (n - 1) * 8; + break; + } + else if (c == '/') + { + char *after; + bits = strtoul(p + 1, &after, 10); + + if (!bits || *after) + return HM_HOST; + if (bits > n * 8) + return HM_HOST; + + break; + } + else + return HM_HOST; + + if (n < 4 && bits == 0) + bits = n * 8; + if (bits) + while (n < 4) + digits[n++] = "0"; + + for (n = 0; n < 4; n++) + addb[n] = strtoul(digits[n], NULL, 10); + + if (bits == 0) + bits = 32; + + /* Set unused bits to 0... -A1kmm */ + if (bits < 32 && bits % 8) + addb[bits / 8] &= ~((1 << (8 - bits % 8)) - 1); + for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; n++) + addb[n] = 0; + if (addr) + v4->sin_addr.s_addr = + htonl(addb[0] << 24 | addb[1] << 16 | addb[2] << 8 | addb[3]); + if (b != NULL) + *b = bits; + return HM_IPV4; +} + +/* int parse_netmask(const char *, struct irc_ssaddr *, int *); + * Input: A hostmask, or an IPV4/6 address. + * Output: An integer describing whether it is an IPV4, IPV6 address or a + * hostmask, an address(if it is an IP mask), + * a bitlength(if it is IP mask). + * Side effects: None + */ +int +parse_netmask(const char *text, struct irc_ssaddr *addr, int *b) +{ +#ifdef IPV6 + if (strchr(text, ':')) + return try_parse_v6_netmask(text, addr, b); +#endif + if (strchr(text, '.')) + return try_parse_v4_netmask(text, addr, b); + return HM_HOST; +} + +/* The address matching stuff... */ +/* int match_ipv6(struct irc_ssaddr *, struct irc_ssaddr *, int) + * Input: An IP address, an IP mask, the number of bits in the mask. + * Output: if match, -1 else 0 + * Side effects: None + */ +#ifdef IPV6 +int +match_ipv6(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits) +{ + int i, m, n = bits / 8; + const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr; + const struct sockaddr_in6 *v6mask = (const struct sockaddr_in6 *)mask; + + for (i = 0; i < n; i++) + if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i]) + return 0; + if ((m = bits % 8) == 0) + return -1; + if ((v6->sin6_addr.s6_addr[n] & ~((1 << (8 - m)) - 1)) == + v6mask->sin6_addr.s6_addr[n]) + return -1; + return 0; +} +#endif + +/* int match_ipv4(struct irc_ssaddr *, struct irc_ssaddr *, int) + * Input: An IP address, an IP mask, the number of bits in the mask. + * Output: if match, -1 else 0 + * Side Effects: None + */ +int +match_ipv4(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits) +{ + const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr; + const struct sockaddr_in *v4mask = (const struct sockaddr_in *)mask; + + if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) != + ntohl(v4mask->sin_addr.s_addr)) + return 0; + return -1; +} + +/* + * mask_addr + * + * inputs - pointer to the ip to mask + * - bitlen + * output - NONE + * side effects - + */ +void +mask_addr(struct irc_ssaddr *ip, int bits) +{ + int mask; +#ifdef IPV6 + struct sockaddr_in6 *v6_base_ip; + int i, m, n; +#endif + struct sockaddr_in *v4_base_ip; + +#ifdef IPV6 + if (ip->ss.ss_family != AF_INET6) +#endif + { + v4_base_ip = (struct sockaddr_in *)ip; + + mask = ~((1 << (32 - bits)) - 1); + v4_base_ip->sin_addr.s_addr = htonl(ntohl(v4_base_ip->sin_addr.s_addr) & mask); + } +#ifdef IPV6 + else + { + n = bits / 8; + m = bits % 8; + v6_base_ip = (struct sockaddr_in6 *)ip; + + mask = ~((1 << (8 - m)) -1 ); + v6_base_ip->sin6_addr.s6_addr[n] = v6_base_ip->sin6_addr.s6_addr[n] & mask; + + for (i = n + 1; i < 16; i++) + v6_base_ip->sin6_addr.s6_addr[i] = 0; + } +#endif +} + +/* Hashtable stuff...now external as its used in m_stats.c */ +dlink_list atable[ATABLE_SIZE]; + +void +init_host_hash(void) +{ + memset(&atable, 0, sizeof(atable)); +} + +/* unsigned long hash_ipv4(struct irc_ssaddr*) + * Input: An IP address. + * Output: A hash value of the IP address. + * Side effects: None + */ +static uint32_t +hash_ipv4(struct irc_ssaddr *addr, int bits) +{ + if (bits != 0) + { + struct sockaddr_in *v4 = (struct sockaddr_in *)addr; + uint32_t av = ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1); + + return (av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1); + } + + return 0; +} + +/* unsigned long hash_ipv6(struct irc_ssaddr*) + * Input: An IP address. + * Output: A hash value of the IP address. + * Side effects: None + */ +#ifdef IPV6 +static uint32_t +hash_ipv6(struct irc_ssaddr *addr, int bits) +{ + uint32_t v = 0, n; + struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr; + + for (n = 0; n < 16; n++) + { + if (bits >= 8) + { + v ^= v6->sin6_addr.s6_addr[n]; + bits -= 8; + } + else if (bits) + { + v ^= v6->sin6_addr.s6_addr[n] & ~((1 << (8 - bits)) - 1); + return v & (ATABLE_SIZE - 1); + } + else + return v & (ATABLE_SIZE - 1); + } + return v & (ATABLE_SIZE - 1); +} +#endif + +/* int hash_text(const char *start) + * Input: The start of the text to hash. + * Output: The hash of the string between 1 and (TH_MAX-1) + * Side-effects: None. + */ +static uint32_t +hash_text(const char *start) +{ + const char *p = start; + uint32_t h = 0; + + for (; *p; ++p) + h = (h << 4) - (h + (unsigned char)ToLower(*p)); + + return h & (ATABLE_SIZE - 1); +} + +/* unsigned long get_hash_mask(const char *) + * Input: The text to hash. + * Output: The hash of the string right of the first '.' past the last + * wildcard in the string. + * Side-effects: None. + */ +static uint32_t +get_mask_hash(const char *text) +{ + const char *hp = "", *p; + + for (p = text + strlen(text) - 1; p >= text; p--) + if (IsMWildChar(*p)) + return hash_text(hp); + else if (*p == '.') + hp = p + 1; + return hash_text(text); +} + +/* struct AccessItem *find_conf_by_address(const char *, struct irc_ssaddr *, + * int type, int fam, const char *username) + * Input: The hostname, the address, the type of mask to find, the address + * family, the username. + * Output: The matching value with the highest precedence. + * Side-effects: None + * Note: Setting bit 0 of the type means that the username is ignored. + * Warning: IsNeedPassword for everything that is not an auth{} entry + * should always be true (i.e. aconf->flags & CONF_FLAGS_NEED_PASSWORD == 0) + */ +struct AccessItem * +find_conf_by_address(const char *name, struct irc_ssaddr *addr, unsigned int type, + int fam, const char *username, const char *password, int do_match) +{ + unsigned int hprecv = 0; + dlink_node *ptr = NULL; + struct AccessItem *hprec = NULL; + struct AddressRec *arec; + int b; + int (*cmpfunc)(const char *, const char *) = do_match ? match : irccmp; + + if (username == NULL) + username = ""; + if (password == NULL) + password = ""; + + if (addr) + { + /* Check for IPV6 matches... */ +#ifdef IPV6 + if (fam == AF_INET6) + { + for (b = 128; b >= 0; b -= 16) + { + DLINK_FOREACH(ptr, atable[hash_ipv6(addr, b)].head) + { + arec = ptr->data; + + if (arec->type == (type & ~0x1) && + arec->precedence > hprecv && + arec->masktype == HM_IPV6 && + match_ipv6(addr, &arec->Mask.ipa.addr, + arec->Mask.ipa.bits) && + (type & 0x1 || cmpfunc(arec->username, username) == do_match) && + (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL || + match_conf_password(password, arec->aconf))) + { + hprecv = arec->precedence; + hprec = arec->aconf; + } + } + } + } + else +#endif + if (fam == AF_INET) + { + for (b = 32; b >= 0; b -= 8) + { + DLINK_FOREACH(ptr, atable[hash_ipv4(addr, b)].head) + { + arec = ptr->data; + + if (arec->type == (type & ~0x1) && + arec->precedence > hprecv && + arec->masktype == HM_IPV4 && + match_ipv4(addr, &arec->Mask.ipa.addr, + arec->Mask.ipa.bits) && + (type & 0x1 || cmpfunc(arec->username, username) == do_match) && + (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL || + match_conf_password(password, arec->aconf))) + { + hprecv = arec->precedence; + hprec = arec->aconf; + } + } + } + } + } + + if (name != NULL) + { + const char *p = name; + + while (1) + { + DLINK_FOREACH(ptr, atable[hash_text(p)].head) + { + arec = ptr->data; + if ((arec->type == (type & ~0x1)) && + arec->precedence > hprecv && + (arec->masktype == HM_HOST) && + cmpfunc(arec->Mask.hostname, name) == do_match && + (type & 0x1 || cmpfunc(arec->username, username) == do_match) && + (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL || + match_conf_password(password, arec->aconf))) + { + hprecv = arec->precedence; + hprec = arec->aconf; + } + } + p = strchr(p, '.'); + if (p == NULL) + break; + p++; + } + + DLINK_FOREACH(ptr, atable[0].head) + { + arec = ptr->data; + + if (arec->type == (type & ~0x1) && + arec->precedence > hprecv && + arec->masktype == HM_HOST && + cmpfunc(arec->Mask.hostname, name) == do_match && + (type & 0x1 || cmpfunc(arec->username, username) == do_match) && + (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL || + match_conf_password(password, arec->aconf))) + { + hprecv = arec->precedence; + hprec = arec->aconf; + } + } + } + + return hprec; +} + +/* struct AccessItem* find_address_conf(const char*, const char*, + * struct irc_ssaddr*, int, char *); + * Input: The hostname, username, address, address family. + * Output: The applicable AccessItem. + * Side-effects: None + */ +struct AccessItem * +find_address_conf(const char *host, const char *user, + struct irc_ssaddr *ip, int aftype, char *password) +{ + struct AccessItem *iconf, *kconf; + + /* Find the best auth{} block... If none, return NULL -A1kmm */ + if ((iconf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user, + password, 1)) == NULL) + return NULL; + + /* If they are exempt from K-lines, return the best auth{} block. -A1kmm */ + if (IsConfExemptKline(iconf)) + return iconf; + + /* Find the best K-line... -A1kmm */ + kconf = find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1); + + /* + * If they are K-lined, return the K-line. Otherwise, return the + * auth{} block. -A1kmm + */ + if (kconf != NULL) + return kconf; + + kconf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL, 1); + if (kconf != NULL && !IsConfExemptGline(iconf)) + return kconf; + + return iconf; +} + +/* struct AccessItem* find_dline_conf(struct irc_ssaddr*, int) + * + * Input: An address, an address family. + * Output: The best matching D-line or exempt line. + * Side effects: None. + */ +struct AccessItem * +find_dline_conf(struct irc_ssaddr *addr, int aftype) +{ + struct AccessItem *eline; + + eline = find_conf_by_address(NULL, addr, CONF_EXEMPTDLINE | 1, aftype, + NULL, NULL, 1); + if (eline != NULL) + return eline; + + return find_conf_by_address(NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL, 1); +} + +/* void add_conf_by_address(int, struct AccessItem *aconf) + * Input: + * Output: None + * Side-effects: Adds this entry to the hash table. + */ +void +add_conf_by_address(const unsigned int type, struct AccessItem *aconf) +{ + const char *address; + const char *username; + static unsigned int prec_value = 0xFFFFFFFF; + int bits = 0; + struct AddressRec *arec; + + address = aconf->host; + username = aconf->user; + + assert(type != 0); + assert(aconf != NULL); + + if (EmptyString(address)) + address = "/NOMATCH!/"; + + arec = MyMalloc(sizeof(struct AddressRec)); + arec->masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits); + arec->Mask.ipa.bits = bits; + arec->username = username; + arec->aconf = aconf; + arec->precedence = prec_value--; + arec->type = type; + + switch (arec->masktype) + { + case HM_IPV4: + /* We have to do this, since we do not re-hash for every bit -A1kmm. */ + bits -= bits % 8; + dlinkAdd(arec, &arec->node, &atable[hash_ipv4(&arec->Mask.ipa.addr, bits)]); + break; +#ifdef IPV6 + case HM_IPV6: + /* We have to do this, since we do not re-hash for every bit -A1kmm. */ + bits -= bits % 16; + dlinkAdd(arec, &arec->node, &atable[hash_ipv6(&arec->Mask.ipa.addr, bits)]); + break; +#endif + default: /* HM_HOST */ + arec->Mask.hostname = address; + dlinkAdd(arec, &arec->node, &atable[get_mask_hash(address)]); + break; + } +} + +/* void delete_one_address(const char*, struct AccessItem*) + * Input: An address string, the associated AccessItem. + * Output: None + * Side effects: Deletes an address record. Frees the AccessItem if there + * is nothing referencing it, sets it as illegal otherwise. + */ +void +delete_one_address_conf(const char *address, struct AccessItem *aconf) +{ + int bits = 0; + uint32_t hv = 0; + dlink_node *ptr = NULL, *ptr_next = NULL; + struct irc_ssaddr addr; + + switch (parse_netmask(address, &addr, &bits)) + { + case HM_IPV4: + /* We have to do this, since we do not re-hash for every bit -A1kmm. */ + bits -= bits % 8; + hv = hash_ipv4(&addr, bits); + break; +#ifdef IPV6 + case HM_IPV6: + /* We have to do this, since we do not re-hash for every bit -A1kmm. */ + bits -= bits % 16; + hv = hash_ipv6(&addr, bits); + break; +#endif + default: /* HM_HOST */ + hv = get_mask_hash(address); + break; + } + + DLINK_FOREACH_SAFE(ptr, ptr_next, atable[hv].head) + { + struct AddressRec *arec = ptr->data; + + if (arec->aconf == aconf) + { + dlinkDelete(&arec->node, &atable[hv]); + aconf->status |= CONF_ILLEGAL; + + if (!aconf->clients) + free_access_item(aconf); + + MyFree(arec); + return; + } + } +} + +/* void clear_out_address_conf(void) + * Input: None + * Output: None + * Side effects: Clears out all address records in the hash table, + * frees them, and frees the AccessItems if nothing references + * them, otherwise sets them as illegal. + */ +void +clear_out_address_conf(void) +{ + unsigned int i = 0; + dlink_node *ptr = NULL, *ptr_next = NULL; + + for (i = 0; i < ATABLE_SIZE; ++i) + { + DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head) + { + struct AddressRec *arec = ptr->data; + + /* We keep the temporary K-lines and destroy the + * permanent ones, just to be confusing :) -A1kmm + */ + if (!(arec->aconf->flags & CONF_FLAGS_TEMPORARY)) + { + dlinkDelete(&arec->node, &atable[i]); + /* unlink it from link list - Dianora */ + arec->aconf->status |= CONF_ILLEGAL; + + if (!arec->aconf->clients) + free_access_item(arec->aconf); + MyFree(arec); + } + } + } +} + +static void +hostmask_send_expiration(struct AddressRec *arec) +{ + char ban_type = '\0'; + + if (!ConfigFileEntry.tkline_expire_notices) + return; + + switch (arec->type) + { + case CONF_KLINE: + ban_type = 'K'; + break; + case CONF_DLINE: + ban_type = 'D'; + break; + case CONF_GLINE: + ban_type = 'G'; + break; + } + + sendto_realops_flags(UMODE_ALL, L_ALL, + "Temporary %c-line for [%s@%s] expired", ban_type, + (arec->aconf->user) ? arec->aconf->user : "*", + (arec->aconf->host) ? arec->aconf->host : "*"); +} + +void +hostmask_expire_temporary(void) +{ + unsigned int i = 0; + dlink_node *ptr = NULL, *ptr_next = NULL; + + for (i = 0; i < ATABLE_SIZE; ++i) + { + DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head) + { + struct AddressRec *arec = ptr->data; + + if (!IsConfTemporary(arec->aconf) || arec->aconf->hold > CurrentTime) + continue; + + switch (arec->type) + { + case CONF_KLINE: + case CONF_DLINE: + case CONF_GLINE: + hostmask_send_expiration(arec); + + dlinkDelete(&arec->node, &atable[i]); + free_access_item(arec->aconf); + MyFree(arec); + break; + } + } + } +} diff --git a/src/irc_res.c b/src/irc_res.c new file mode 100644 index 0000000..200b68d --- /dev/null +++ b/src/irc_res.c @@ -0,0 +1,836 @@ +/* + * A rewrite of Darren Reeds original res.c As there is nothing + * left of Darrens original code, this is now licensed by the hybrid group. + * (Well, some of the function names are the same, and bits of the structs..) + * You can use it where it is useful, free even. Buy us a beer and stuff. + * + * The authors takes no responsibility for any damage or loss + * of property which results from the use of this software. + * + * $Id$ + * + * July 1999 - Rewrote a bunch of stuff here. Change hostent builder code, + * added callbacks and reference counting of returned hostents. + * --Bleep (Thomas Helvey <tomh@inxpress.net>) + * + * This was all needlessly complicated for irc. Simplified. No more hostent + * All we really care about is the IP -> hostname mappings. Thats all. + * + * Apr 28, 2003 --cryogen and Dianora + */ + +#include "stdinc.h" +#include "list.h" +#include "balloc.h" +#include "client.h" +#include "event.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "rng_mt.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "log.h" +#include "s_misc.h" +#include "send.h" +#include "memory.h" +#include "irc_res.h" +#include "irc_reslib.h" + +#if (CHAR_BIT != 8) +#error this code needs to be able to address individual octets +#endif + +static PF res_readreply; + +#define MAXPACKET 1024 /* rfc sez 512 but we expand names so ... */ +#define RES_MAXALIASES 35 /* maximum aliases allowed */ +#define RES_MAXADDRS 35 /* maximum addresses allowed */ +#define AR_TTL 600 /* TTL in seconds for dns cache entries */ + +/* RFC 1104/1105 wasn't very helpful about what these fields + * should be named, so for now, we'll just name them this way. + * we probably should look at what named calls them or something. + */ +#define TYPE_SIZE (size_t)2 +#define CLASS_SIZE (size_t)2 +#define TTL_SIZE (size_t)4 +#define RDLENGTH_SIZE (size_t)2 +#define ANSWER_FIXED_SIZE (TYPE_SIZE + CLASS_SIZE + TTL_SIZE + RDLENGTH_SIZE) + +typedef enum +{ + REQ_IDLE, /* We're doing not much at all */ + REQ_PTR, /* Looking up a PTR */ + REQ_A, /* Looking up an A, possibly because AAAA failed */ +#ifdef IPV6 + REQ_AAAA, /* Looking up an AAAA */ +#endif + REQ_CNAME /* We got a CNAME in response, we better get a real answer next */ +} request_state; + +struct reslist +{ + dlink_node node; + int id; + int sent; /* number of requests sent */ + request_state state; /* State the resolver machine is in */ + time_t ttl; + char type; + char retries; /* retry counter */ + char sends; /* number of sends (>1 means resent) */ + char resend; /* send flag. 0 == dont resend */ + time_t sentat; + time_t timeout; + struct irc_ssaddr addr; + char *name; + dns_callback_fnc callback; + void *callback_ctx; +}; + +static fde_t ResolverFileDescriptor; +static dlink_list request_list = { NULL, NULL, 0 }; +static BlockHeap *dns_heap = NULL; + +static void rem_request(struct reslist *); +static struct reslist *make_request(dns_callback_fnc, void *); +static void do_query_name(dns_callback_fnc, void *, + const char *, struct reslist *, int); +static void do_query_number(dns_callback_fnc, void *, + const struct irc_ssaddr *, + struct reslist *); +static void query_name(const char *, int, int, struct reslist *); +static int send_res_msg(const char *, int, int); +static void resend_query(struct reslist *); +static int proc_answer(struct reslist *, HEADER *, char *, char *); +static struct reslist *find_id(int); + + +/* + * int + * res_ourserver(inp) + * looks up "inp" in irc_nsaddr_list[] + * returns: + * 0 : not found + * >0 : found + * author: + * paul vixie, 29may94 + * revised for ircd, cryogen(stu) may03 + */ +static int +res_ourserver(const struct irc_ssaddr *inp) +{ +#ifdef IPV6 + const struct sockaddr_in6 *v6; + const struct sockaddr_in6 *v6in = (const struct sockaddr_in6 *)inp; +#endif + const struct sockaddr_in *v4; + const struct sockaddr_in *v4in = (const struct sockaddr_in *)inp; + int ns; + + for (ns = 0; ns < irc_nscount; ++ns) + { + const struct irc_ssaddr *srv = &irc_nsaddr_list[ns]; +#ifdef IPV6 + v6 = (const struct sockaddr_in6 *)srv; +#endif + v4 = (const struct sockaddr_in *)srv; + + /* could probably just memcmp(srv, inp, srv.ss_len) here + * but we'll air on the side of caution - stu + * + */ + switch (srv->ss.ss_family) + { +#ifdef IPV6 + case AF_INET6: + if (srv->ss.ss_family == inp->ss.ss_family) + if (v6->sin6_port == v6in->sin6_port) + if (!memcmp(&v6->sin6_addr.s6_addr, &v6in->sin6_addr.s6_addr, + sizeof(struct in6_addr))) + return 1; + break; +#endif + case AF_INET: + if (srv->ss.ss_family == inp->ss.ss_family) + if (v4->sin_port == v4in->sin_port) + if (v4->sin_addr.s_addr == v4in->sin_addr.s_addr) + return 1; + break; + default: + break; + } + } + + return 0; +} + +/* + * timeout_query_list - Remove queries from the list which have been + * there too long without being resolved. + */ +static time_t +timeout_query_list(time_t now) +{ + dlink_node *ptr; + dlink_node *next_ptr; + struct reslist *request; + time_t next_time = 0; + time_t timeout = 0; + + DLINK_FOREACH_SAFE(ptr, next_ptr, request_list.head) + { + request = ptr->data; + timeout = request->sentat + request->timeout; + + if (now >= timeout) + { + if (--request->retries <= 0) + { + (*request->callback)(request->callback_ctx, NULL, NULL); + rem_request(request); + continue; + } + else + { + request->sentat = now; + request->timeout += request->timeout; + resend_query(request); + } + } + + if ((next_time == 0) || timeout < next_time) + next_time = timeout; + } + + return (next_time > now) ? next_time : (now + AR_TTL); +} + +/* + * timeout_resolver - check request list + */ +static void +timeout_resolver(void *notused) +{ + timeout_query_list(CurrentTime); +} + +/* + * start_resolver - do everything we need to read the resolv.conf file + * and initialize the resolver file descriptor if needed + */ +static void +start_resolver(void) +{ + irc_res_init(); + + if (!ResolverFileDescriptor.flags.open) + { + if (comm_open(&ResolverFileDescriptor, irc_nsaddr_list[0].ss.ss_family, + SOCK_DGRAM, 0, "Resolver socket") == -1) + return; + + /* At the moment, the resolver FD data is global .. */ + comm_setselect(&ResolverFileDescriptor, COMM_SELECT_READ, + res_readreply, NULL, 0); + eventAdd("timeout_resolver", timeout_resolver, NULL, 1); + } +} + +/* + * init_resolver - initialize resolver and resolver library + */ +void +init_resolver(void) +{ + dns_heap = BlockHeapCreate("dns", sizeof(struct reslist), DNS_HEAP_SIZE); + memset(&ResolverFileDescriptor, 0, sizeof(fde_t)); + start_resolver(); +} + +/* + * restart_resolver - reread resolv.conf, reopen socket + */ +void +restart_resolver(void) +{ + fd_close(&ResolverFileDescriptor); + eventDelete(timeout_resolver, NULL); /* -ddosen */ + start_resolver(); +} + +/* + * rem_request - remove a request from the list. + * This must also free any memory that has been allocated for + * temporary storage of DNS results. + */ +static void +rem_request(struct reslist *request) +{ + dlinkDelete(&request->node, &request_list); + + MyFree(request->name); + BlockHeapFree(dns_heap, request); +} + +/* + * make_request - Create a DNS request record for the server. + */ +static struct reslist * +make_request(dns_callback_fnc callback, void *ctx) +{ + struct reslist *request = BlockHeapAlloc(dns_heap); + + request->sentat = CurrentTime; + request->retries = 3; + request->resend = 1; + request->timeout = 4; /* start at 4 and exponential inc. */ + request->state = REQ_IDLE; + request->callback = callback; + request->callback_ctx = ctx; + + dlinkAdd(request, &request->node, &request_list); + return request; +} + +/* + * delete_resolver_queries - cleanup outstanding queries + * for which there no longer exist clients or conf lines. + */ +void +delete_resolver_queries(const void *vptr) +{ + dlink_node *ptr = NULL, *next_ptr = NULL; + + DLINK_FOREACH_SAFE(ptr, next_ptr, request_list.head) + { + struct reslist *request = ptr->data; + + if (request->callback_ctx == vptr) + rem_request(request); + } +} + +/* + * send_res_msg - sends msg to all nameservers found in the "_res" structure. + * This should reflect /etc/resolv.conf. We will get responses + * which arent needed but is easier than checking to see if nameserver + * isnt present. Returns number of messages successfully sent to + * nameservers or -1 if no successful sends. + */ +static int +send_res_msg(const char *msg, int len, int rcount) +{ + int i; + int sent = 0; + int max_queries = IRCD_MIN(irc_nscount, rcount); + + /* RES_PRIMARY option is not implemented + * if (res.options & RES_PRIMARY || 0 == max_queries) + */ + if (max_queries == 0) + max_queries = 1; + + for (i = 0; i < max_queries; i++) + { + if (sendto(ResolverFileDescriptor.fd, msg, len, 0, + (struct sockaddr*)&(irc_nsaddr_list[i]), + irc_nsaddr_list[i].ss_len) == len) + ++sent; + } + + return sent; +} + +/* + * find_id - find a dns request id (id is determined by dn_mkquery) + */ +static struct reslist * +find_id(int id) +{ + dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, request_list.head) + { + struct reslist *request = ptr->data; + + if (request->id == id) + return request; + } + + return NULL; +} + +/* + * gethost_byname_type - get host address from name + * + */ +void +gethost_byname_type(dns_callback_fnc callback, void *ctx, const char *name, int type) +{ + assert(name != NULL); + do_query_name(callback, ctx, name, NULL, type); +} + +/* + * gethost_byname - wrapper for _type - send T_AAAA first if IPV6 supported + */ +void +gethost_byname(dns_callback_fnc callback, void *ctx, const char *name) +{ +#ifdef IPV6 + gethost_byname_type(callback, ctx, name, T_AAAA); +#else + gethost_byname_type(callback, ctx, name, T_A); +#endif +} + +/* + * gethost_byaddr - get host name from address + */ +void +gethost_byaddr(dns_callback_fnc callback, void *ctx, const struct irc_ssaddr *addr) +{ + do_query_number(callback, ctx, addr, NULL); +} + +/* + * do_query_name - nameserver lookup name + */ +static void +do_query_name(dns_callback_fnc callback, void *ctx, const char *name, + struct reslist *request, int type) +{ + char host_name[HOSTLEN + 1]; + + strlcpy(host_name, name, sizeof(host_name)); + + if (request == NULL) + { + request = make_request(callback, ctx); + request->name = MyMalloc(strlen(host_name) + 1); + request->type = type; + strcpy(request->name, host_name); +#ifdef IPV6 + if (type != T_A) + request->state = REQ_AAAA; + else +#endif + request->state = REQ_A; + } + + request->type = type; + query_name(host_name, C_IN, type, request); +} + +/* + * do_query_number - Use this to do reverse IP# lookups. + */ +static void +do_query_number(dns_callback_fnc callback, void *ctx, + const struct irc_ssaddr *addr, + struct reslist *request) +{ + char ipbuf[128]; + const unsigned char *cp; + + if (addr->ss.ss_family == AF_INET) + { + const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr; + cp = (const unsigned char *)&v4->sin_addr.s_addr; + + snprintf(ipbuf, sizeof(ipbuf), "%u.%u.%u.%u.in-addr.arpa.", + (unsigned int)(cp[3]), (unsigned int)(cp[2]), + (unsigned int)(cp[1]), (unsigned int)(cp[0])); + } +#ifdef IPV6 + else if (addr->ss.ss_family == AF_INET6) + { + const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr; + cp = (const unsigned char *)&v6->sin6_addr.s6_addr; + + snprintf(ipbuf, sizeof(ipbuf), + "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x." + "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa.", + (unsigned int)(cp[15] & 0xf), (unsigned int)(cp[15] >> 4), + (unsigned int)(cp[14] & 0xf), (unsigned int)(cp[14] >> 4), + (unsigned int)(cp[13] & 0xf), (unsigned int)(cp[13] >> 4), + (unsigned int)(cp[12] & 0xf), (unsigned int)(cp[12] >> 4), + (unsigned int)(cp[11] & 0xf), (unsigned int)(cp[11] >> 4), + (unsigned int)(cp[10] & 0xf), (unsigned int)(cp[10] >> 4), + (unsigned int)(cp[9] & 0xf), (unsigned int)(cp[9] >> 4), + (unsigned int)(cp[8] & 0xf), (unsigned int)(cp[8] >> 4), + (unsigned int)(cp[7] & 0xf), (unsigned int)(cp[7] >> 4), + (unsigned int)(cp[6] & 0xf), (unsigned int)(cp[6] >> 4), + (unsigned int)(cp[5] & 0xf), (unsigned int)(cp[5] >> 4), + (unsigned int)(cp[4] & 0xf), (unsigned int)(cp[4] >> 4), + (unsigned int)(cp[3] & 0xf), (unsigned int)(cp[3] >> 4), + (unsigned int)(cp[2] & 0xf), (unsigned int)(cp[2] >> 4), + (unsigned int)(cp[1] & 0xf), (unsigned int)(cp[1] >> 4), + (unsigned int)(cp[0] & 0xf), (unsigned int)(cp[0] >> 4)); + } +#endif + if (request == NULL) + { + request = make_request(callback, ctx); + request->type = T_PTR; + memcpy(&request->addr, addr, sizeof(struct irc_ssaddr)); + request->name = MyMalloc(HOSTLEN + 1); + } + + query_name(ipbuf, C_IN, T_PTR, request); +} + +/* + * query_name - generate a query based on class, type and name. + */ +static void +query_name(const char *name, int query_class, int type, + struct reslist *request) +{ + char buf[MAXPACKET]; + int request_len = 0; + + memset(buf, 0, sizeof(buf)); + + if ((request_len = irc_res_mkquery(name, query_class, type, + (unsigned char *)buf, sizeof(buf))) > 0) + { + HEADER *header = (HEADER *)buf; + + /* + * generate an unique id + * NOTE: we don't have to worry about converting this to and from + * network byte order, the nameserver does not interpret this value + * and returns it unchanged + */ + do + header->id = (header->id + genrand_int32()) & 0xffff; + while (find_id(header->id)); + + request->id = header->id; + ++request->sends; + + request->sent += send_res_msg(buf, request_len, request->sends); + } +} + +static void +resend_query(struct reslist *request) +{ + if (request->resend == 0) + return; + + switch (request->type) + { + case T_PTR: + do_query_number(NULL, NULL, &request->addr, request); + break; + case T_A: + do_query_name(NULL, NULL, request->name, request, request->type); + break; +#ifdef IPV6 + case T_AAAA: + /* didnt work, try A */ + if (request->state == REQ_AAAA) + do_query_name(NULL, NULL, request->name, request, T_A); +#endif + default: + break; + } +} + +/* + * proc_answer - process name server reply + */ +static int +proc_answer(struct reslist *request, HEADER *header, char *buf, char *eob) +{ + char hostbuf[HOSTLEN + 100]; /* working buffer */ + unsigned char *current; /* current position in buf */ + int query_class; /* answer class */ + int type; /* answer type */ + int n; /* temp count */ + int rd_length; + struct sockaddr_in *v4; /* conversion */ +#ifdef IPV6 + struct sockaddr_in6 *v6; +#endif + current = (unsigned char *)buf + sizeof(HEADER); + + for (; header->qdcount > 0; --header->qdcount) + { + if ((n = irc_dn_skipname(current, (unsigned char *)eob)) < 0) + break; + + current += (size_t)n + QFIXEDSZ; + } + + /* + * process each answer sent to us blech. + */ + while (header->ancount > 0 && (char *)current < eob) + { + header->ancount--; + + n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, current, + hostbuf, sizeof(hostbuf)); + + if (n < 0 /* broken message */ || n == 0 /* no more answers left */) + return 0; + + hostbuf[HOSTLEN] = '\0'; + + /* With Address arithmetic you have to be very anal + * this code was not working on alpha due to that + * (spotted by rodder/jailbird/dianora) + */ + current += (size_t) n; + + if (!(((char *)current + ANSWER_FIXED_SIZE) < eob)) + break; + + type = irc_ns_get16(current); + current += TYPE_SIZE; + + query_class = irc_ns_get16(current); + current += CLASS_SIZE; + + request->ttl = irc_ns_get32(current); + current += TTL_SIZE; + + rd_length = irc_ns_get16(current); + current += RDLENGTH_SIZE; + + /* + * Wait to set request->type until we verify this structure + */ + switch (type) + { + case T_A: + if (request->type != T_A) + return 0; + + /* + * check for invalid rd_length or too many addresses + */ + if (rd_length != sizeof(struct in_addr)) + return 0; + + v4 = (struct sockaddr_in *)&request->addr; + request->addr.ss_len = sizeof(struct sockaddr_in); + v4->sin_family = AF_INET; + memcpy(&v4->sin_addr, current, sizeof(struct in_addr)); + return 1; + break; +#ifdef IPV6 + case T_AAAA: + if (request->type != T_AAAA) + return 0; + + if (rd_length != sizeof(struct in6_addr)) + return 0; + + request->addr.ss_len = sizeof(struct sockaddr_in6); + v6 = (struct sockaddr_in6 *)&request->addr; + v6->sin6_family = AF_INET6; + memcpy(&v6->sin6_addr, current, sizeof(struct in6_addr)); + return 1; + break; +#endif + case T_PTR: + if (request->type != T_PTR) + return 0; + + n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, + current, hostbuf, sizeof(hostbuf)); + if (n < 0 /* broken message */ || n == 0 /* no more answers left */) + return 0; + + strlcpy(request->name, hostbuf, HOSTLEN + 1); + return 1; + break; + case T_CNAME: /* first check we already havent started looking + into a cname */ + if (request->type != T_PTR) + return 0; + + if (request->state == REQ_CNAME) + { + n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, + current, hostbuf, sizeof(hostbuf)); + + if (n < 0) + return 0; + return 1; + } + + request->state = REQ_CNAME; + current += rd_length; + break; + + default: + /* XXX I'd rather just throw away the entire bogus thing + * but its possible its just a broken nameserver with still + * valid answers. But lets do some rudimentary logging for now... + */ + ilog(LOG_TYPE_IRCD, "irc_res.c bogus type %d", type); + break; + } + } + + return 1; +} + +/* + * res_readreply - read a dns reply from the nameserver and process it. + */ +static void +res_readreply(fde_t *fd, void *data) +{ + char buf[sizeof(HEADER) + MAXPACKET] + /* Sparc and alpha need 16bit-alignment for accessing header->id + * (which is uint16_t). Because of the header = (HEADER*) buf; + * lateron, this is neeeded. --FaUl + */ +#if defined(__sparc__) || defined(__alpha__) + __attribute__((aligned (16))) +#endif + ; + HEADER *header; + struct reslist *request = NULL; + int rc; + socklen_t len = sizeof(struct irc_ssaddr); + struct irc_ssaddr lsin; + + rc = recvfrom(fd->fd, buf, sizeof(buf), 0, (struct sockaddr *)&lsin, &len); + + /* Re-schedule a read *after* recvfrom, or we'll be registering + * interest where it'll instantly be ready for read :-) -- adrian + */ + comm_setselect(fd, COMM_SELECT_READ, res_readreply, NULL, 0); + + /* Better to cast the sizeof instead of rc */ + if (rc <= (int)(sizeof(HEADER))) + return; + + /* + * convert DNS reply reader from Network byte order to CPU byte order. + */ + header = (HEADER *)buf; + header->ancount = ntohs(header->ancount); + header->qdcount = ntohs(header->qdcount); + header->nscount = ntohs(header->nscount); + header->arcount = ntohs(header->arcount); + + /* + * check against possibly fake replies + */ + if (!res_ourserver(&lsin)) + return; + + /* + * response for an id which we have already received an answer for + * just ignore this response. + */ + if (!(request = find_id(header->id))) + return; + + if ((header->rcode != NO_ERRORS) || (header->ancount == 0)) + { + if (header->rcode == SERVFAIL || header->rcode == NXDOMAIN) + { + /* + * If a bad error was returned, stop here and don't + * send any more (no retries granted). + */ + (*request->callback)(request->callback_ctx, NULL, NULL); + rem_request(request); + } +#ifdef IPV6 + else + { + /* + * If we havent already tried this, and we're looking up AAAA, try A + * now + */ + if (request->state == REQ_AAAA && request->type == T_AAAA) + { + request->timeout += 4; + resend_query(request); + } + } +#endif + + return; + } + + /* + * If this fails there was an error decoding the received packet, + * try it again and hope it works the next time. + */ + if (proc_answer(request, header, buf, buf + rc)) + { + if (request->type == T_PTR) + { + if (request->name == NULL) + { + /* + * got a PTR response with no name, something bogus is happening + * don't bother trying again, the client address doesn't resolve + */ + (*request->callback)(request->callback_ctx, NULL, NULL); + rem_request(request); + return; + } + + /* + * Lookup the 'authoritative' name that we were given for the + * ip#. + * + */ +#ifdef IPV6 + if (request->addr.ss.ss_family == AF_INET6) + gethost_byname_type(request->callback, request->callback_ctx, request->name, T_AAAA); + else +#endif + gethost_byname_type(request->callback, request->callback_ctx, request->name, T_A); + rem_request(request); + } + else + { + /* + * got a name and address response, client resolved + */ + (*request->callback)(request->callback_ctx, &request->addr, request->name); + rem_request(request); + } + } + else if (!request->sent) + { + /* XXX - we got a response for a query we didn't send with a valid id? + * this should never happen, bail here and leave the client unresolved + */ + assert(0); + + /* XXX don't leak it */ + rem_request(request); + } +} + +void +report_dns_servers(struct Client *source_p) +{ + int i; + char ipaddr[HOSTIPLEN + 1]; + + for (i = 0; i < irc_nscount; i++) + { + getnameinfo((struct sockaddr *)&(irc_nsaddr_list[i]), + irc_nsaddr_list[i].ss_len, ipaddr, + sizeof(ipaddr), NULL, 0, NI_NUMERICHOST); + sendto_one(source_p, form_str(RPL_STATSALINE), + me.name, source_p->name, ipaddr); + } +} diff --git a/src/irc_reslib.c b/src/irc_reslib.c new file mode 100644 index 0000000..42bf2c2 --- /dev/null +++ b/src/irc_reslib.c @@ -0,0 +1,1168 @@ +/* + * Copyright (c) 1985, 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. + */ + +/* + * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * + * 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. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM 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. + */ + +/* Original copyright ISC as above. + * Code modified specifically for ircd use from the following orginal files + * in bind ... + * + * res_comp.c + * ns_name.c + * ns_netint.c + * res_init.c + * + * - Dianora + */ + +#include "stdinc.h" +#include "ircd_defs.h" +#include "irc_res.h" +#include "irc_reslib.h" +#include "irc_string.h" + +#define NS_TYPE_ELT 0x40 /* EDNS0 extended label type */ +#define DNS_LABELTYPE_BITSTRING 0x41 +#define MAXLINE 128 + +/* $Id$ */ + +struct irc_ssaddr irc_nsaddr_list[IRCD_MAXNS]; +int irc_nscount = 0; + +static const char digits[] = "0123456789"; +static const char digitvalue[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/ + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/ + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/ +}; + +static int labellen(const unsigned char *lp); +static int special(int ch); +static int printable(int ch); +static int irc_decode_bitstring(const unsigned char **cpp, char *dn, const char *eom); +static int irc_ns_name_compress(const char *src, unsigned char *dst, size_t dstsiz, + const unsigned char **dnptrs, const unsigned char **lastdnptr); +static int irc_dn_find(const unsigned char *, const unsigned char *, const unsigned char * const *, + const unsigned char * const *); +static int irc_encode_bitsring(const char **, const char *, unsigned char **, unsigned char **, + const unsigned char *); +static int irc_ns_name_uncompress(const unsigned char *, const unsigned char *, + const unsigned char *, char *, size_t); +static int irc_ns_name_unpack(const unsigned char *, const unsigned char *, + const unsigned char *, unsigned char *, + size_t); +static int irc_ns_name_ntop(const unsigned char *, char *, size_t); +static int irc_ns_name_skip(const unsigned char **, const unsigned char *); +static int mklower(int ch); + + +/* add_nameserver() + * + * input - either an IPV4 address in dotted quad + * or an IPV6 address in : format + * output - NONE + * side effects - entry in irc_nsaddr_list is filled in as needed + */ +static void +add_nameserver(const char *arg) +{ + struct addrinfo hints, *res; + + /* Done max number of nameservers? */ + if (irc_nscount >= IRCD_MAXNS) + return; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + + if (getaddrinfo(arg, "domain", &hints, &res)) + return; + + if (res == NULL) + return; + + memcpy(&irc_nsaddr_list[irc_nscount].ss, res->ai_addr, res->ai_addrlen); + irc_nsaddr_list[irc_nscount++].ss_len = res->ai_addrlen; + freeaddrinfo(res); +} + +/* parse_resvconf() + * + * inputs - NONE + * output - -1 if failure 0 if success + * side effects - fills in irc_nsaddr_list + */ +static void +parse_resvconf(void) +{ + char *p; + char *opt; + char *arg; + char input[MAXLINE]; + FILE *file; + + /* XXX "/etc/resolv.conf" should be from a define in config.h perhaps + * for cygwin support etc. this hardcodes it to unix for now -db + */ + if ((file = fopen("/etc/resolv.conf", "r")) == NULL) + return; + + while (fgets(input, sizeof(input), file) != NULL) + { + /* blow away any newline */ + if ((p = strpbrk(input, "\r\n")) != NULL) + *p = '\0'; + + p = input; + + /* skip until something thats not a space is seen */ + while (IsSpace(*p)) + ++p; + + /* if at this point, have a '\0' then continue */ + if (*p == '\0') + continue; + + /* Ignore comment lines immediately */ + if (*p == ';' || *p == '#') + continue; + + /* skip until a space is found */ + opt = p; + while (!IsSpace(*p) && *p) + ++p; + + if (*p == '\0') + continue; /* no arguments?.. ignore this line */ + + /* blow away the space character */ + *p++ = '\0'; + + /* skip these spaces that are before the argument */ + while (IsSpace(*p)) + ++p; + + /* Now arg should be right where p is pointing */ + arg = p; + + if ((p = strpbrk(arg, " \t")) != NULL) + *p = '\0'; /* take the first word */ + + if (!irccmp(opt, "nameserver")) + add_nameserver(arg); + } + + fclose(file); +} + +void +irc_res_init(void) +{ + irc_nscount = 0; + memset(irc_nsaddr_list, 0, sizeof(irc_nsaddr_list)); + + parse_resvconf(); + + if (!irc_nscount) + add_nameserver("127.0.0.1"); +} + +/* + * Expand compressed domain name 'comp_dn' to full domain name. + * 'msg' is a pointer to the begining of the message, + * 'eomorig' points to the first location after the message, + * 'exp_dn' is a pointer to a buffer of size 'length' for the result. + * Return size of compressed name or -1 if there was an error. + */ +int +irc_dn_expand(const unsigned char *msg, const unsigned char *eom, + const unsigned char *src, char *dst, int dstsiz) +{ + int n = irc_ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz); + + if (n > 0 && dst[0] == '.') + dst[0] = '\0'; + return(n); +} /*2*/ + +/* + * irc_ns_name_uncompress(msg, eom, src, dst, dstsiz) + * Expand compressed domain name to presentation format. + * return: + * Number of bytes read out of `src', or -1 (with errno set). + * note: + * Root domain returns as "." not "". + */ +static int +irc_ns_name_uncompress(const unsigned char *msg, const unsigned char *eom, + const unsigned char *src, char *dst, size_t dstsiz) +{ + unsigned char tmp[NS_MAXCDNAME]; + int n; + + if ((n = irc_ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1) + return(-1); + if (irc_ns_name_ntop(tmp, dst, dstsiz) == -1) + return(-1); + return(n); +} /*2*/ + +/* + * irc_ns_name_unpack(msg, eom, src, dst, dstsiz) + * Unpack a domain name from a message, source may be compressed. + * return: + * -1 if it fails, or consumed octets if it succeeds. + */ +static int +irc_ns_name_unpack(const unsigned char *msg, const unsigned char *eom, + const unsigned char *src, unsigned char *dst, + size_t dstsiz) +{ + const unsigned char *srcp, *dstlim; + unsigned char *dstp; + int n, len, checked, l; + + len = -1; + checked = 0; + dstp = dst; + srcp = src; + dstlim = dst + dstsiz; + if (srcp < msg || srcp >= eom) { + errno = EMSGSIZE; + return (-1); + } + /* Fetch next label in domain name. */ + while ((n = *srcp++) != 0) { + /* Check for indirection. */ + switch (n & NS_CMPRSFLGS) { + case 0: + case NS_TYPE_ELT: + /* Limit checks. */ + if ((l = labellen(srcp - 1)) < 0) { + errno = EMSGSIZE; + return(-1); + } + if (dstp + l + 1 >= dstlim || srcp + l >= eom) { + errno = EMSGSIZE; + return (-1); + } + checked += l + 1; + *dstp++ = n; + memcpy(dstp, srcp, l); + dstp += l; + srcp += l; + break; + + case NS_CMPRSFLGS: + if (srcp >= eom) { + errno = EMSGSIZE; + return (-1); + } + if (len < 0) + len = srcp - src + 1; + srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff)); + if (srcp < msg || srcp >= eom) { /* Out of range. */ + errno = EMSGSIZE; + return (-1); + } + checked += 2; + /* + * Check for loops in the compressed name; + * if we've looked at the whole message, + * there must be a loop. + */ + if (checked >= eom - msg) { + errno = EMSGSIZE; + return (-1); + } + break; + + default: + errno = EMSGSIZE; + return (-1); /* flag error */ + } + } + *dstp = '\0'; + if (len < 0) + len = srcp - src; + return (len); +} /*2*/ + +/* + * irc_ns_name_ntop(src, dst, dstsiz) + * Convert an encoded domain name to printable ascii as per RFC1035. + * return: + * Number of bytes written to buffer, or -1 (with errno set) + * notes: + * The root is returned as "." + * All other domains are returned in non absolute form + */ +static int +irc_ns_name_ntop(const unsigned char *src, char *dst, size_t dstsiz) +{ + const unsigned char *cp; + char *dn, *eom; + unsigned char c; + unsigned int n; + int l; + + cp = src; + dn = dst; + eom = dst + dstsiz; + + while ((n = *cp++) != 0) { + if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { + /* Some kind of compression pointer. */ + errno = EMSGSIZE; + return (-1); + } + if (dn != dst) { + if (dn >= eom) { + errno = EMSGSIZE; + return (-1); + } + *dn++ = '.'; + } + if ((l = labellen((cp - 1))) < 0) { + errno = EMSGSIZE; /* XXX */ + return(-1); + } + if (dn + l >= eom) { + errno = EMSGSIZE; + return (-1); + } + if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) { + int m; + + if (n != DNS_LABELTYPE_BITSTRING) { + /* XXX: labellen should reject this case */ + errno = EINVAL; + return(-1); + } + if ((m = irc_decode_bitstring(&cp, dn, eom)) < 0) + { + errno = EMSGSIZE; + return(-1); + } + dn += m; + continue; + } + for ((void)NULL; l > 0; l--) { + c = *cp++; + if (special(c)) { + if (dn + 1 >= eom) { + errno = EMSGSIZE; + return (-1); + } + *dn++ = '\\'; + *dn++ = (char)c; + } else if (!printable(c)) { + if (dn + 3 >= eom) { + errno = EMSGSIZE; + return (-1); + } + *dn++ = '\\'; + *dn++ = digits[c / 100]; + *dn++ = digits[(c % 100) / 10]; + *dn++ = digits[c % 10]; + } else { + if (dn >= eom) { + errno = EMSGSIZE; + return (-1); + } + *dn++ = (char)c; + } + } + } + if (dn == dst) { + if (dn >= eom) { + errno = EMSGSIZE; + return (-1); + } + *dn++ = '.'; + } + if (dn >= eom) { + errno = EMSGSIZE; + return (-1); + } + *dn++ = '\0'; + return (dn - dst); +} /*2*/ + +/* + * Skip over a compressed domain name. Return the size or -1. + */ +int +irc_dn_skipname(const unsigned char *ptr, const unsigned char *eom) { + const unsigned char *saveptr = ptr; + + if (irc_ns_name_skip(&ptr, eom) == -1) + return(-1); + return(ptr - saveptr); +} /*2*/ + +/* + * ns_name_skip(ptrptr, eom) + * Advance *ptrptr to skip over the compressed name it points at. + * return: + * 0 on success, -1 (with errno set) on failure. + */ +static int +irc_ns_name_skip(const unsigned char **ptrptr, const unsigned char *eom) +{ + const unsigned char *cp; + unsigned int n; + int l; + + cp = *ptrptr; + + while (cp < eom && (n = *cp++) != 0) + { + /* Check for indirection. */ + switch (n & NS_CMPRSFLGS) + { + case 0: /* normal case, n == len */ + cp += n; + continue; + case NS_TYPE_ELT: /* EDNS0 extended label */ + if ((l = labellen(cp - 1)) < 0) + { + errno = EMSGSIZE; /* XXX */ + return(-1); + } + + cp += l; + continue; + case NS_CMPRSFLGS: /* indirection */ + cp++; + break; + default: /* illegal type */ + errno = EMSGSIZE; + return(-1); + } + + break; + } + + if (cp > eom) + { + errno = EMSGSIZE; + return (-1); + } + + *ptrptr = cp; + return(0); +} /*2*/ + +unsigned int +irc_ns_get16(const unsigned char *src) +{ + unsigned int dst; + + IRC_NS_GET16(dst, src); + return(dst); +} + +unsigned long +irc_ns_get32(const unsigned char *src) +{ + unsigned long dst; + + IRC_NS_GET32(dst, src); + return(dst); +} + +void +irc_ns_put16(unsigned int src, unsigned char *dst) +{ + IRC_NS_PUT16(src, dst); +} + +void +irc_ns_put32(unsigned long src, unsigned char *dst) +{ + IRC_NS_PUT32(src, dst); +} + +/* From ns_name.c */ + +/* + * special(ch) + * Thinking in noninternationalized USASCII (per the DNS spec), + * is this characted special ("in need of quoting") ? + * return: + * boolean. + */ +static int +special(int ch) +{ + switch (ch) + { + case 0x22: /* '"' */ + case 0x2E: /* '.' */ + case 0x3B: /* ';' */ + case 0x5C: /* '\\' */ + case 0x28: /* '(' */ + case 0x29: /* ')' */ + /* Special modifiers in zone files. */ + case 0x40: /* '@' */ + case 0x24: /* '$' */ + return(1); + default: + return(0); + } +} /*2*/ + +static int +labellen(const unsigned char *lp) +{ + int bitlen; + unsigned char l = *lp; + + if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) + { + /* should be avoided by the caller */ + return(-1); + } + + if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) + { + if (l == DNS_LABELTYPE_BITSTRING) + { + if ((bitlen = *(lp + 1)) == 0) + bitlen = 256; + return((bitlen + 7 ) / 8 + 1); + } + + return(-1); /* unknwon ELT */ + } + + return(l); +} /*2*/ + + +/* + * printable(ch) + * Thinking in noninternationalized USASCII (per the DNS spec), + * is this character visible and not a space when printed ? + * return: + * boolean. + */ +static int +printable(int ch) +{ + return(ch > 0x20 && ch < 0x7f); +} /*2*/ + +static int +irc_decode_bitstring(const unsigned char **cpp, char *dn, const char *eom) +{ + const unsigned char *cp = *cpp; + char *beg = dn, tc; + int b, blen, plen; + + if ((blen = (*cp & 0xff)) == 0) + blen = 256; + plen = (blen + 3) / 4; + plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1); + if (dn + plen >= eom) + return(-1); + + cp++; + dn += sprintf(dn, "\\[x"); + for (b = blen; b > 7; b -= 8, cp++) + dn += sprintf(dn, "%02x", *cp & 0xff); + if (b > 4) { + tc = *cp++; + dn += sprintf(dn, "%02x", tc & (0xff << (8 - b))); + } else if (b > 0) { + tc = *cp++; + dn += sprintf(dn, "%1x", + ((tc >> 4) & 0x0f) & (0x0f << (4 - b))); + } + dn += sprintf(dn, "/%d]", blen); + + *cpp = cp; + return(dn - beg); +} /*2*/ + +/* + * irc_ns_name_pton(src, dst, dstsiz) + * Convert a ascii string into an encoded domain name as per RFC1035. + * return: + * -1 if it fails + * 1 if string was fully qualified + * 0 is string was not fully qualified + * notes: + * Enforces label and domain length limits. + */ +static int +irc_ns_name_pton(const char *src, unsigned char *dst, size_t dstsiz) +{ + unsigned char *label, *bp, *eom; + char *cp; + int c, n, escaped, e = 0; + + escaped = 0; + bp = dst; + eom = dst + dstsiz; + label = bp++; + + + while ((c = *src++) != 0) { + if (escaped) { + if (c == '[') { /* start a bit string label */ + if ((cp = strchr(src, ']')) == NULL) { + errno = EINVAL; /* ??? */ + return(-1); + } + if ((e = irc_encode_bitsring(&src, + cp + 2, + &label, + &bp, + eom)) + != 0) { + errno = e; + return(-1); + } + escaped = 0; + label = bp++; + if ((c = *src++) == 0) + goto done; + else if (c != '.') { + errno = EINVAL; + return(-1); + } + continue; + } + else if ((cp = strchr(digits, c)) != NULL) { + n = (cp - digits) * 100; + if ((c = *src++) == 0 || + (cp = strchr(digits, c)) == NULL) { + errno = EMSGSIZE; + return (-1); + } + n += (cp - digits) * 10; + if ((c = *src++) == 0 || + (cp = strchr(digits, c)) == NULL) { + errno = EMSGSIZE; + return (-1); + } + n += (cp - digits); + if (n > 255) { + errno = EMSGSIZE; + return (-1); + } + c = n; + } + escaped = 0; + } else if (c == '\\') { + escaped = 1; + continue; + } else if (c == '.') { + c = (bp - label - 1); + if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */ + errno = EMSGSIZE; + return (-1); + } + if (label >= eom) { + errno = EMSGSIZE; + return (-1); + } + *label = c; + /* Fully qualified ? */ + if (*src == '\0') { + if (c != 0) { + if (bp >= eom) { + errno = EMSGSIZE; + return (-1); + } + *bp++ = '\0'; + } + if ((bp - dst) > NS_MAXCDNAME) { + errno = EMSGSIZE; + return (-1); + } + return (1); + } + if (c == 0 || *src == '.') { + errno = EMSGSIZE; + return (-1); + } + label = bp++; + continue; + } + if (bp >= eom) { + errno = EMSGSIZE; + return (-1); + } + *bp++ = (unsigned char)c; + } + c = (bp - label - 1); + if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */ + errno = EMSGSIZE; + return (-1); + } + done: + if (label >= eom) { + errno = EMSGSIZE; + return (-1); + } + *label = c; + if (c != 0) { + if (bp >= eom) { + errno = EMSGSIZE; + return (-1); + } + *bp++ = 0; + } + + if ((bp - dst) > NS_MAXCDNAME) + { /* src too big */ + errno = EMSGSIZE; + return (-1); + } + + return (0); +} /*2*/ + +/* + * irc_ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr) + * Pack domain name 'domain' into 'comp_dn'. + * return: + * Size of the compressed name, or -1. + * notes: + * 'dnptrs' is an array of pointers to previous compressed names. + * dnptrs[0] is a pointer to the beginning of the message. The array + * ends with NULL. + * 'lastdnptr' is a pointer to the end of the array pointed to + * by 'dnptrs'. + * Side effects: + * The list of pointers in dnptrs is updated for labels inserted into + * the message as we compress the name. If 'dnptr' is NULL, we don't + * try to compress names. If 'lastdnptr' is NULL, we don't update the + * list. + */ +static int +irc_ns_name_pack(const unsigned char *src, unsigned char *dst, int dstsiz, + const unsigned char **dnptrs, const unsigned char **lastdnptr) +{ + unsigned char *dstp; + const unsigned char **cpp, **lpp, *eob, *msg; + const unsigned char *srcp; + int n, l, first = 1; + + srcp = src; + dstp = dst; + eob = dstp + dstsiz; + lpp = cpp = NULL; + if (dnptrs != NULL) { + if ((msg = *dnptrs++) != NULL) { + for (cpp = dnptrs; *cpp != NULL; cpp++) + (void)NULL; + lpp = cpp; /* end of list to search */ + } + } else + msg = NULL; + + /* make sure the domain we are about to add is legal */ + l = 0; + do { + int l0; + + n = *srcp; + if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { + errno = EMSGSIZE; + return (-1); + } + if ((l0 = labellen(srcp)) < 0) { + errno = EINVAL; + return(-1); + } + l += l0 + 1; + if (l > NS_MAXCDNAME) { + errno = EMSGSIZE; + return (-1); + } + srcp += l0 + 1; + } while (n != 0); + + /* from here on we need to reset compression pointer array on error */ + srcp = src; + do { + /* Look to see if we can use pointers. */ + n = *srcp; + if (n != 0 && msg != NULL) { + l = irc_dn_find(srcp, msg, (const unsigned char * const *)dnptrs, + (const unsigned char * const *)lpp); + if (l >= 0) { + if (dstp + 1 >= eob) { + goto cleanup; + } + *dstp++ = (l >> 8) | NS_CMPRSFLGS; + *dstp++ = l % 256; + return (dstp - dst); + } + /* Not found, save it. */ + if (lastdnptr != NULL && cpp < lastdnptr - 1 && + (dstp - msg) < 0x4000 && first) { + *cpp++ = dstp; + *cpp = NULL; + first = 0; + } + } + /* copy label to buffer */ + if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { + /* Should not happen. */ + goto cleanup; + } + n = labellen(srcp); + if (dstp + 1 + n >= eob) { + goto cleanup; + } + memcpy(dstp, srcp, n + 1); + srcp += n + 1; + dstp += n + 1; + } while (n != 0); + + if (dstp > eob) { +cleanup: + if (msg != NULL) + *lpp = NULL; + errno = EMSGSIZE; + return (-1); + } + return(dstp - dst); +} /*2*/ + +static int +irc_ns_name_compress(const char *src, unsigned char *dst, size_t dstsiz, + const unsigned char **dnptrs, const unsigned char **lastdnptr) +{ + unsigned char tmp[NS_MAXCDNAME]; + + if (irc_ns_name_pton(src, tmp, sizeof tmp) == -1) + return(-1); + return(irc_ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr)); +} + +static int +irc_encode_bitsring(const char **bp, const char *end, unsigned char **labelp, + unsigned char **dst, const unsigned char *eom) +{ + int afterslash = 0; + const char *cp = *bp; + unsigned char *tp; + char c; + const char *beg_blen; + char *end_blen = NULL; + int value = 0, count = 0, tbcount = 0, blen = 0; + + beg_blen = end_blen = NULL; + + /* a bitstring must contain at least 2 characters */ + if (end - cp < 2) + return(EINVAL); + + /* XXX: currently, only hex strings are supported */ + if (*cp++ != 'x') + return(EINVAL); + if (!isxdigit((*cp) & 0xff)) /* reject '\[x/BLEN]' */ + return(EINVAL); + + for (tp = *dst + 1; cp < end && tp < eom; cp++) { + switch((c = *cp)) { + case ']': /* end of the bitstring */ + if (afterslash) { + if (beg_blen == NULL) + return(EINVAL); + blen = (int)strtol(beg_blen, &end_blen, 10); + if (*end_blen != ']') + return(EINVAL); + } + if (count) + *tp++ = ((value << 4) & 0xff); + cp++; /* skip ']' */ + goto done; + case '/': + afterslash = 1; + break; + default: + if (afterslash) { + if (!isdigit(c&0xff)) + return(EINVAL); + if (beg_blen == NULL) { + + if (c == '0') { + /* blen never begings with 0 */ + return(EINVAL); + } + beg_blen = cp; + } + } else { + if (!isxdigit(c&0xff)) + return(EINVAL); + value <<= 4; + value += digitvalue[(int)c]; + count += 4; + tbcount += 4; + if (tbcount > 256) + return(EINVAL); + if (count == 8) { + *tp++ = value; + count = 0; + } + } + break; + } + } + done: + if (cp >= end || tp >= eom) + return(EMSGSIZE); + + /* + * bit length validation: + * If a <length> is present, the number of digits in the <bit-data> + * MUST be just sufficient to contain the number of bits specified + * by the <length>. If there are insignificant bits in a final + * hexadecimal or octal digit, they MUST be zero. + * RFC 2673, Section 3.2. + */ + if (blen > 0) { + int traillen; + + if (((blen + 3) & ~3) != tbcount) + return(EINVAL); + traillen = tbcount - blen; /* between 0 and 3 */ + if (((value << (8 - traillen)) & 0xff) != 0) + return(EINVAL); + } + else + blen = tbcount; + if (blen == 256) + blen = 0; + + /* encode the type and the significant bit fields */ + **labelp = DNS_LABELTYPE_BITSTRING; + **dst = blen; + + *bp = cp; + *dst = tp; + + return(0); +} /*2*/ + +/* + * dn_find(domain, msg, dnptrs, lastdnptr) + * Search for the counted-label name in an array of compressed names. + * return: + * offset from msg if found, or -1. + * notes: + * dnptrs is the pointer to the first name on the list, + * not the pointer to the start of the message. + */ +static int +irc_dn_find(const unsigned char *domain, const unsigned char *msg, + const unsigned char * const *dnptrs, + const unsigned char * const *lastdnptr) +{ + const unsigned char *dn, *cp, *sp; + const unsigned char * const *cpp; + unsigned int n; + + for (cpp = dnptrs; cpp < lastdnptr; cpp++) + { + sp = *cpp; + /* + * terminate search on: + * root label + * compression pointer + * unusable offset + */ + while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 && + (sp - msg) < 0x4000) { + dn = domain; + cp = sp; + while ((n = *cp++) != 0) { + /* + * check for indirection + */ + switch (n & NS_CMPRSFLGS) { + case 0: /* normal case, n == len */ + n = labellen(cp - 1); /* XXX */ + + if (n != *dn++) + goto next; + + for ((void)NULL; n > 0; n--) + if (mklower(*dn++) != + mklower(*cp++)) + goto next; + /* Is next root for both ? */ + if (*dn == '\0' && *cp == '\0') + return (sp - msg); + if (*dn) + continue; + goto next; + case NS_CMPRSFLGS: /* indirection */ + cp = msg + (((n & 0x3f) << 8) | *cp); + break; + + default: /* illegal type */ + errno = EMSGSIZE; + return (-1); + } + } + next: ; + sp += *sp + 1; + } + } + errno = ENOENT; + return (-1); +} /*2*/ + +/* + * * Thinking in noninternationalized USASCII (per the DNS spec), + * * convert this character to lower case if it's upper case. + * */ +static int +mklower(int ch) +{ + if (ch >= 0x41 && ch <= 0x5A) + return(ch + 0x20); + + return(ch); +} /*2*/ + +/* From resolv/mkquery.c */ + +/* + * Form all types of queries. + * Returns the size of the result or -1. + */ +int +irc_res_mkquery( + const char *dname, /* domain name */ + int class, int type, /* class and type of query */ + unsigned char *buf, /* buffer to put query */ + int buflen) /* size of buffer */ +{ + HEADER *hp; + unsigned char *cp; + int n; + const unsigned char *dnptrs[20], **dpp, **lastdnptr; + + /* + * Initialize header fields. + */ + if ((buf == NULL) || (buflen < HFIXEDSZ)) + return (-1); + memset(buf, 0, HFIXEDSZ); + hp = (HEADER *) buf; + + hp->id = 0; + hp->opcode = QUERY; + hp->rd = 1; /* recurse */ + hp->rcode = NO_ERRORS; + cp = buf + HFIXEDSZ; + buflen -= HFIXEDSZ; + dpp = dnptrs; + *dpp++ = buf; + *dpp++ = NULL; + lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; + + if ((buflen -= QFIXEDSZ) < 0) + return (-1); + if ((n = irc_ns_name_compress(dname, cp, buflen, dnptrs, + lastdnptr)) < 0) + return (-1); + + cp += n; + buflen -= n; + IRC_NS_PUT16(type, cp); + IRC_NS_PUT16(class, cp); + hp->qdcount = htons(1); + + return (cp - buf); +} diff --git a/src/irc_string.c b/src/irc_string.c new file mode 100644 index 0000000..08b4321 --- /dev/null +++ b/src/irc_string.c @@ -0,0 +1,263 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * irc_string.c: IRC string functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "config.h" +#ifdef HAVE_LIBPCRE +#include <pcre.h> +#endif + +#include "stdinc.h" +#include "irc_string.h" +#include "sprintf_irc.h" + + +int +has_wildcards(const char *s) +{ + char c; + + while ((c = *s++)) + if (IsMWildChar(c)) + return 1; + + return 0; +} + +/* + * myctime - This is like standard ctime()-function, but it zaps away + * the newline from the end of that string. Also, it takes + * the time value as parameter, instead of pointer to it. + * Note that it is necessary to copy the string to alternate + * buffer (who knows how ctime() implements it, maybe it statically + * has newline there and never 'refreshes' it -- zapping that + * might break things in other places...) + * + * + * Thu Nov 24 18:22:48 1986 + */ +const char * +myctime(time_t value) +{ + static char buf[32]; + char *p; + + strcpy(buf, ctime(&value)); + + if ((p = strchr(buf, '\n')) != NULL) + *p = '\0'; + return buf; +} + +/* + * strip_tabs(dst, src, length) + * + * Copies src to dst, while converting all \t (tabs) into spaces. + */ +void +strip_tabs(char *dest, const char *src, size_t len) +{ + char *d = dest; + + /* Sanity check; we don't want anything nasty... */ + assert(dest != NULL); + assert(src != NULL); + assert(len > 0); + + for (; --len && *src; ++src) + *d++ = *src == '\t' ? ' ' : *src; + + *d = '\0'; /* NUL terminate, thanks and goodbye */ +} + +/* + * strtoken - walk through a string of tokens, using a set of separators + * argv 9/90 + * + */ +#ifndef HAVE_STRTOK_R + +char * +strtoken(char** save, char* str, const char* fs) +{ + char* pos = *save; /* keep last position across calls */ + char* tmp; + + if (str) + pos = str; /* new string scan */ + + while (pos && *pos && strchr(fs, *pos) != NULL) + ++pos; /* skip leading separators */ + + if (!pos || !*pos) + return (pos = *save = NULL); /* string contains only sep's */ + + tmp = pos; /* now, keep position of the token */ + + while (*pos && strchr(fs, *pos) == NULL) + ++pos; /* skip content of the token */ + + if (*pos) + *pos++ = '\0'; /* remove first sep after the token */ + else + pos = NULL; /* end of string */ + + *save = pos; + return tmp; +} +#endif /* !HAVE_STRTOK_R */ + +/* libio_basename() + * + * input - i.e. "/usr/local/ircd/modules/m_whois.so" + * output - i.e. "m_whois.so" + * side effects - this will be overwritten on subsequent calls + */ +const char * +libio_basename(const char *path) +{ + const char *s; + + if ((s = strrchr(path, '/')) == NULL) + s = path; + else + s++; + + return s; +} + +/* + * strlcat and strlcpy were ripped from openssh 2.5.1p2 + * They had the following Copyright info: + * + * + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED `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 AUTHOR 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. + */ + +#ifndef HAVE_STRLCAT +size_t +strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz, dlen; + + while (n-- != 0 && *d != '\0') + d++; + + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return dlen + strlen(s); + + while (*s != '\0') + { + if (n != 1) + { + *d++ = *s; + n--; + } + + s++; + } + + *d = '\0'; + return dlen + (s - src); /* count does not include NUL */ +} +#endif + +#ifndef HAVE_STRLCPY +size_t +strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) + { + do + { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) + { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return s - src - 1; /* count does not include NUL */ +} +#endif + +#ifdef HAVE_LIBPCRE +void * +ircd_pcre_compile(const char *pattern, const char **errptr) +{ + int erroroffset = 0; + int options = PCRE_EXTRA; + + assert(pattern); + + return pcre_compile(pattern, options, errptr, &erroroffset, NULL); +} + +int +ircd_pcre_exec(const void *code, const char *subject) +{ + assert(code && subject); + + return pcre_exec(code, NULL, subject, strlen(subject), 0, 0, NULL, 0) < 0; +} +#endif diff --git a/src/ircd.c b/src/ircd.c new file mode 100644 index 0000000..ee02bcd --- /dev/null +++ b/src/ircd.c @@ -0,0 +1,658 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * ircd.c: Starts up and runs the ircd. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "s_user.h" +#include "list.h" +#include "ircd.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "event.h" +#include "fdlist.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd_signal.h" +#include "s_gline.h" +#include "motd.h" +#include "hostmask.h" +#include "numeric.h" +#include "packet.h" +#include "parse.h" +#include "irc_res.h" +#include "restart.h" +#include "rng_mt.h" +#include "s_auth.h" +#include "s_bsd.h" +#include "conf.h" +#include "log.h" +#include "s_misc.h" +#include "s_serv.h" /* try_connections */ +#include "send.h" +#include "whowas.h" +#include "modules.h" +#include "memory.h" +#include "hook.h" +#include "ircd_getopt.h" +#include "balloc.h" +#include "motd.h" +#include "supported.h" +#include "watch.h" + + +/* /quote set variables */ +struct SetOptions GlobalSetOptions; + +/* configuration set from ircd.conf */ +struct config_file_entry ConfigFileEntry; +/* server info set from ircd.conf */ +struct server_info ServerInfo; +/* admin info set from ircd.conf */ +struct admin_info AdminInfo = { NULL, NULL, NULL }; +struct Counter Count = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +struct ServerState_t server_state = { 0 }; +struct logging_entry ConfigLoggingEntry = { .use_logging = 1 }; +struct ServerStatistics ServerStats; +struct timeval SystemTime; +struct Client me; /* That's me */ +struct LocalUser meLocalUser; /* That's also part of me */ + +const char *logFileName = LPATH; +const char *pidFileName = PPATH; + +char **myargv; + +int dorehash = 0; +int doremotd = 0; + +/* Set to zero because it should be initialized later using + * initialize_server_capabs + */ +int default_server_capabs = 0; +unsigned int splitmode; +unsigned int splitchecking; +unsigned int split_users; +unsigned int split_servers; + +/* Do klines the same way hybrid-6 did them, i.e. at the + * top of the next io_loop instead of in the same loop as + * the klines are being applied. + * + * This should fix strange CPU starvation as very indirectly reported. + * (Why do you people not email bug reports? WHY? WHY?) + * + * - Dianora + */ + +int rehashed_klines = 0; + + +/* + * print_startup - print startup information + */ +static void +print_startup(int pid) +{ + printf("ircd: version %s\n", ircd_version); + printf("ircd: pid %d\n", pid); + printf("ircd: running in %s mode from %s\n", !server_state.foreground ? "background" + : "foreground", ConfigFileEntry.dpath); +} + +static void +make_daemon(void) +{ + int pid; + + if ((pid = fork()) < 0) + { + perror("fork"); + exit(EXIT_FAILURE); + } + else if (pid > 0) + { + print_startup(pid); + exit(EXIT_SUCCESS); + } + + setsid(); +} + +static int printVersion = 0; + +static struct lgetopt myopts[] = { + {"dlinefile", &ConfigFileEntry.dlinefile, + STRING, "File to use for dline.conf"}, + {"configfile", &ConfigFileEntry.configfile, + STRING, "File to use for ircd.conf"}, + {"klinefile", &ConfigFileEntry.klinefile, + STRING, "File to use for kline.conf"}, + {"xlinefile", &ConfigFileEntry.xlinefile, + STRING, "File to use for xline.conf"}, + {"logfile", &logFileName, + STRING, "File to use for ircd.log"}, + {"pidfile", &pidFileName, + STRING, "File to use for process ID"}, + {"foreground", &server_state.foreground, + YESNO, "Run in foreground (don't detach)"}, + {"version", &printVersion, + YESNO, "Print version and exit"}, + {"help", NULL, USAGE, "Print this text"}, + {NULL, NULL, STRING, NULL}, +}; + +void +set_time(void) +{ + static char to_send[200]; + struct timeval newtime; + newtime.tv_sec = 0; + newtime.tv_usec = 0; + + if (gettimeofday(&newtime, NULL) == -1) + { + ilog(LOG_TYPE_IRCD, "Clock Failure (%s), TS can be corrupted", + strerror(errno)); + sendto_realops_flags(UMODE_ALL, L_ALL, + "Clock Failure (%s), TS can be corrupted", + strerror(errno)); + restart("Clock Failure"); + } + + if (newtime.tv_sec < CurrentTime) + { + snprintf(to_send, sizeof(to_send), + "System clock is running backwards - (%lu < %lu)", + (unsigned long)newtime.tv_sec, (unsigned long)CurrentTime); + report_error(L_ALL, to_send, me.name, 0); + set_back_events(CurrentTime - newtime.tv_sec); + } + + SystemTime.tv_sec = newtime.tv_sec; + SystemTime.tv_usec = newtime.tv_usec; +} + +static void +io_loop(void) +{ + while (1 == 1) + { + /* + * Maybe we want a flags word? + * ie. if (REHASHED_KLINES(global_flags)) + * SET_REHASHED_KLINES(global_flags) + * CLEAR_REHASHED_KLINES(global_flags) + * + * - Dianora + */ + if (rehashed_klines) + { + check_conf_klines(); + rehashed_klines = 0; + } + + if (listing_client_list.head) + { + dlink_node *ptr = NULL, *ptr_next = NULL; + DLINK_FOREACH_SAFE(ptr, ptr_next, listing_client_list.head) + { + struct Client *client_p = ptr->data; + assert(client_p->localClient->list_task); + safe_list_channels(client_p, client_p->localClient->list_task, 0); + } + } + + /* Run pending events, then get the number of seconds to the next + * event + */ + while (eventNextTime() <= CurrentTime) + eventRun(); + + comm_select(); + exit_aborted_clients(); + free_exited_clients(); + send_queued_all(); + + /* Check to see whether we have to rehash the configuration .. */ + if (dorehash) + { + rehash(1); + dorehash = 0; + } + if (doremotd) + { + read_message_file(&ConfigFileEntry.motd); + sendto_realops_flags(UMODE_ALL, L_ALL, + "Got signal SIGUSR1, reloading ircd motd file"); + doremotd = 0; + } + } +} + +/* initalialize_global_set_options() + * + * inputs - none + * output - none + * side effects - This sets all global set options needed + */ +static void +initialize_global_set_options(void) +{ + memset(&GlobalSetOptions, 0, sizeof(GlobalSetOptions)); + + GlobalSetOptions.autoconn = 1; + GlobalSetOptions.spam_time = MIN_JOIN_LEAVE_TIME; + GlobalSetOptions.spam_num = MAX_JOIN_LEAVE_COUNT; + + if (ConfigFileEntry.default_floodcount) + GlobalSetOptions.floodcount = ConfigFileEntry.default_floodcount; + else + GlobalSetOptions.floodcount = 10; + + /* XXX I have no idea what to try here - Dianora */ + GlobalSetOptions.joinfloodcount = 16; + GlobalSetOptions.joinfloodtime = 8; + + split_servers = ConfigChannel.default_split_server_count; + split_users = ConfigChannel.default_split_user_count; + + if (split_users && split_servers && (ConfigChannel.no_create_on_split || + ConfigChannel.no_join_on_split)) + { + splitmode = 1; + splitchecking = 1; + } + + GlobalSetOptions.ident_timeout = IDENT_TIMEOUT; + /* End of global set options */ +} + +/* initialize_message_files() + * + * inputs - none + * output - none + * side effects - Set up all message files needed, motd etc. + */ +static void +initialize_message_files(void) +{ + init_message_file(USER_MOTD, MPATH, &ConfigFileEntry.motd); + init_message_file(USER_LINKS, LIPATH, &ConfigFileEntry.linksfile); + + read_message_file(&ConfigFileEntry.motd); + read_message_file(&ConfigFileEntry.linksfile); + + init_isupport(); +} + +/* initialize_server_capabs() + * + * inputs - none + * output - none + */ +static void +initialize_server_capabs(void) +{ + add_capability("QS", CAP_QS, 1); + add_capability("EOB", CAP_EOB, 1); + add_capability("TS6", CAP_TS6, 0); + add_capability("CLUSTER", CAP_CLUSTER, 1); + add_capability("SVS", CAP_SVS, 1); +#ifdef HALFOPS + add_capability("HOPS", CAP_HOPS, 1); +#endif +} + +/* write_pidfile() + * + * inputs - filename+path of pid file + * output - NONE + * side effects - write the pid of the ircd to filename + */ +static void +write_pidfile(const char *filename) +{ + FILE *fb; + + if ((fb = fopen(filename, "w"))) + { + char buff[32]; + unsigned int pid = (unsigned int)getpid(); + + snprintf(buff, sizeof(buff), "%u\n", pid); + + if ((fputs(buff, fb) == -1)) + ilog(LOG_TYPE_IRCD, "Error writing %u to pid file %s (%s)", + pid, filename, strerror(errno)); + + fclose(fb); + } + else + { + ilog(LOG_TYPE_IRCD, "Error opening pid file %s", filename); + } +} + +/* check_pidfile() + * + * inputs - filename+path of pid file + * output - none + * side effects - reads pid from pidfile and checks if ircd is in process + * list. if it is, gracefully exits + * -kre + */ +static void +check_pidfile(const char *filename) +{ + FILE *fb; + char buff[32]; + pid_t pidfromfile; + + /* Don't do logging here, since we don't have log() initialised */ + if ((fb = fopen(filename, "r"))) + { + if (fgets(buff, 20, fb) == NULL) + { + /* log(L_ERROR, "Error reading from pid file %s (%s)", filename, + * strerror(errno)); + */ + } + else + { + pidfromfile = atoi(buff); + + if (!kill(pidfromfile, 0)) + { + /* log(L_ERROR, "Server is already running"); */ + printf("ircd: daemon is already running\n"); + exit(-1); + } + } + + fclose(fb); + } + else if (errno != ENOENT) + { + /* log(L_ERROR, "Error opening pid file %s", filename); */ + } +} + +/* setup_corefile() + * + * inputs - nothing + * output - nothing + * side effects - setups corefile to system limits. + * -kre + */ +static void +setup_corefile(void) +{ +#ifdef HAVE_SYS_RESOURCE_H + struct rlimit rlim; /* resource limits */ + + /* Set corefilesize to maximum */ + if (!getrlimit(RLIMIT_CORE, &rlim)) + { + rlim.rlim_cur = rlim.rlim_max; + setrlimit(RLIMIT_CORE, &rlim); + } +#endif +} + +/* init_ssl() + * + * inputs - nothing + * output - nothing + * side effects - setups SSL context. + */ +static void +init_ssl(void) +{ +#ifdef HAVE_LIBCRYPTO + SSL_load_error_strings(); + SSLeay_add_ssl_algorithms(); + + if ((ServerInfo.server_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) + { + const char *s; + + fprintf(stderr, "ERROR: Could not initialize the SSL Server context -- %s\n", + s = ERR_lib_error_string(ERR_get_error())); + ilog(LOG_TYPE_IRCD, "ERROR: Could not initialize the SSL Server context -- %s\n", s); + } + + SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1); + SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_TLS_ROLLBACK_BUG|SSL_OP_ALL); + SSL_CTX_set_verify(ServerInfo.server_ctx, SSL_VERIFY_NONE, NULL); + + if ((ServerInfo.client_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) + { + const char *s; + + fprintf(stderr, "ERROR: Could not initialize the SSL Client context -- %s\n", + s = ERR_lib_error_string(ERR_get_error())); + ilog(LOG_TYPE_IRCD, "ERROR: Could not initialize the SSL Client context -- %s\n", s); + } + + SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1); + SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_TLS_ROLLBACK_BUG|SSL_OP_ALL); + SSL_CTX_set_verify(ServerInfo.client_ctx, SSL_VERIFY_NONE, NULL); +#endif /* HAVE_LIBCRYPTO */ +} + +/* init_callbacks() + * + * inputs - nothing + * output - nothing + * side effects - setups standard hook points + */ +static void +init_callbacks(void) +{ + iorecv_cb = register_callback("iorecv", iorecv_default); + iosend_cb = register_callback("iosend", iosend_default); +} + +int +main(int argc, char *argv[]) +{ + /* Check to see if the user is running + * us as root, which is a nono + */ + if (geteuid() == 0) + { + fprintf(stderr, "Don't run ircd as root!!!\n"); + return -1; + } + + /* Setup corefile size immediately after boot -kre */ + setup_corefile(); + + /* save server boot time right away, so getrusage works correctly */ + set_time(); + + /* It ain't random, but it ought to be a little harder to guess */ + init_genrand(SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid() << 20))); + + me.localClient = &meLocalUser; + dlinkAdd(&me, &me.node, &global_client_list); /* Pointer to beginning + of Client list */ + /* Initialise the channel capability usage counts... */ + init_chcap_usage_counts(); + + ConfigFileEntry.dpath = DPATH; + ConfigFileEntry.configfile = CPATH; /* Server configuration file */ + ConfigFileEntry.klinefile = KPATH; /* Server kline file */ + ConfigFileEntry.xlinefile = XPATH; /* Server xline file */ + ConfigFileEntry.dlinefile = DLPATH; /* dline file */ + ConfigFileEntry.cresvfile = CRESVPATH; /* channel resv file */ + ConfigFileEntry.nresvfile = NRESVPATH; /* nick resv file */ + myargv = argv; + umask(077); /* better safe than sorry --SRB */ + + parseargs(&argc, &argv, myopts); + + if (printVersion) + { + printf("ircd: version %s\n", ircd_version); + exit(EXIT_SUCCESS); + } + + if (chdir(ConfigFileEntry.dpath)) + { + perror("chdir"); + exit(EXIT_FAILURE); + } + + init_ssl(); + + if (!server_state.foreground) + { + make_daemon(); + close_standard_fds(); /* this needs to be before init_netio()! */ + } + else + print_startup(getpid()); + + setup_signals(); + + /* Init the event subsystem */ + eventInit(); + /* We need this to initialise the fd array before anything else */ + fdlist_init(); + log_add_file(LOG_TYPE_IRCD, 0, logFileName); + check_can_use_v6(); + init_comm(); /* This needs to be setup early ! -- adrian */ + /* Check if there is pidfile and daemon already running */ + check_pidfile(pidFileName); + + initBlockHeap(); + init_dlink_nodes(); + init_callbacks(); + initialize_message_files(); + dbuf_init(); + init_hash(); + init_ip_hash_table(); /* client host ip hash table */ + init_host_hash(); /* Host-hashtable. */ + init_client(); + init_class(); + whowas_init(); + watch_init(); + init_auth(); /* Initialise the auth code */ + init_resolver(); /* Needs to be setup before the io loop */ + modules_init(); + read_conf_files(1); /* cold start init conf files */ + init_uid(); + initialize_server_capabs(); /* Set up default_server_capabs */ + initialize_global_set_options(); + init_channels(); + + if (EmptyString(ServerInfo.sid)) + { + ilog(LOG_TYPE_IRCD, "ERROR: No server id specified in serverinfo block."); + exit(EXIT_FAILURE); + } + + strlcpy(me.id, ServerInfo.sid, sizeof(me.id)); + + if (EmptyString(ServerInfo.name)) + { + ilog(LOG_TYPE_IRCD, "ERROR: No server name specified in serverinfo block."); + exit(EXIT_FAILURE); + } + + strlcpy(me.name, ServerInfo.name, sizeof(me.name)); + + /* serverinfo{} description must exist. If not, error out.*/ + if (EmptyString(ServerInfo.description)) + { + ilog(LOG_TYPE_IRCD, "ERROR: No server description specified in serverinfo block."); + exit(EXIT_FAILURE); + } + + strlcpy(me.info, ServerInfo.description, sizeof(me.info)); + + me.from = &me; + me.servptr = &me; + me.localClient->lasttime = CurrentTime; + me.localClient->since = CurrentTime; + me.localClient->firsttime = CurrentTime; + + SetMe(&me); + make_server(&me); + + hash_add_id(&me); + hash_add_client(&me); + + /* add ourselves to global_serv_list */ + dlinkAdd(&me, make_dlink_node(), &global_serv_list); + + if (chdir(MODPATH)) + { + ilog(LOG_TYPE_IRCD, "Could not load core modules. Terminating!"); + exit(EXIT_FAILURE); + } + + load_all_modules(1); + load_conf_modules(); + load_core_modules(1); + + /* Go back to DPATH after checking to see if we can chdir to MODPATH */ + if (chdir(ConfigFileEntry.dpath)) + { + perror("chdir"); + exit(EXIT_FAILURE); + } + + /* + * assemble_umode_buffer() has to be called after + * reading conf/loading modules. + */ + assemble_umode_buffer(); + + write_pidfile(pidFileName); + + ilog(LOG_TYPE_IRCD, "Server Ready"); + + eventAddIsh("cleanup_glines", cleanup_glines, NULL, CLEANUP_GLINES_TIME); + eventAddIsh("cleanup_tklines", cleanup_tklines, NULL, CLEANUP_TKLINES_TIME); + + /* We want try_connections to be called as soon as possible now! -- adrian */ + /* No, 'cause after a restart it would cause all sorts of nick collides */ + eventAddIsh("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME); + + /* Setup the timeout check. I'll shift it later :) -- adrian */ + eventAddIsh("comm_checktimeouts", comm_checktimeouts, NULL, 1); + + if (ConfigServerHide.links_delay > 0) + eventAddIsh("write_links_file", write_links_file, NULL, ConfigServerHide.links_delay); + else + ConfigServerHide.links_disabled = 1; + + if (splitmode) + eventAddIsh("check_splitmode", check_splitmode, NULL, 60); + + io_loop(); + return 0; +} diff --git a/src/ircd_signal.c b/src/ircd_signal.c new file mode 100644 index 0000000..b76e542 --- /dev/null +++ b/src/ircd_signal.c @@ -0,0 +1,135 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * ircd_signal.c: responsible for ircd's signal handling + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "ircd_signal.h" +#include "ircd.h" /* dorehash */ +#include "restart.h" /* server_die */ +#include "memory.h" +#include "s_bsd.h" + +/* + * sigterm_handler - exit the server + */ +static void +sigterm_handler(int sig) +{ + server_die("received signal SIGTERM", 0); +} + +/* + * sighup_handler - reread the server configuration + */ +static void +sighup_handler(int sig) +{ + dorehash = 1; +} + +/* + * sigusr1_handler - reread the motd file + */ +static void +sigusr1_handler(int sig) +{ + doremotd = 1; +} + +/* + * + * inputs - nothing + * output - nothing + * side effects - Reaps zombies periodically + * -AndroSyn + */ +static void +sigchld_handler(int sig) +{ + int status; + waitpid(-1, &status, WNOHANG); +} + +/* + * sigint_handler - restart the server + */ +static void +sigint_handler(int sig) +{ + server_die("SIGINT received", !server_state.foreground); +} + +/* + * setup_signals - initialize signal handlers for server + */ +void +setup_signals(void) +{ + struct sigaction act; + + act.sa_flags = 0; + act.sa_handler = SIG_IGN; + + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask, SIGPIPE); + sigaddset(&act.sa_mask, SIGALRM); + sigaction(SIGALRM, &act, 0); +#ifdef SIGTRAP + sigaddset(&act.sa_mask, SIGTRAP); +#endif +#ifdef SIGXFSZ + sigaddset(&act.sa_mask, SIGXFSZ); + sigaction(SIGXFSZ, &act, 0); +#endif + +#ifdef SIGWINCH + sigaddset(&act.sa_mask, SIGWINCH); + sigaction(SIGWINCH, &act, 0); +#endif + sigaction(SIGPIPE, &act, 0); +#ifdef SIGTRAP + sigaction(SIGTRAP, &act, 0); +#endif + + act.sa_handler = sighup_handler; + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask, SIGHUP); + sigaction(SIGHUP, &act, 0); + + act.sa_handler = sigint_handler; + sigaddset(&act.sa_mask, SIGINT); + sigaction(SIGINT, &act, 0); + + act.sa_handler = sigterm_handler; + sigaddset(&act.sa_mask, SIGTERM); + sigaction(SIGTERM, &act, 0); + + act.sa_handler = sigusr1_handler; + sigaddset(&act.sa_mask, SIGUSR1); + sigaction(SIGUSR1, &act, 0); + + act.sa_handler = sigchld_handler; + sigaddset(&act.sa_mask, SIGCHLD); + sigaction(SIGCHLD, &act, 0); +} diff --git a/src/list.c b/src/list.c new file mode 100644 index 0000000..2850d46 --- /dev/null +++ b/src/list.c @@ -0,0 +1,277 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * list.c: Various assorted functions for various structures. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "balloc.h" + +static BlockHeap *dnode_heap; + + +/* init_dlink_nodes() + * + * inputs - NONE + * output - NONE + * side effects - initializes the dnode BlockHeap + */ +void +init_dlink_nodes(void) +{ + dnode_heap = BlockHeapCreate("dlink node", sizeof(dlink_node), DNODE_HEAP_SIZE); +} + +/* make_dlink_node() + * + * inputs - NONE + * output - pointer to new dlink_node + * side effects - NONE + */ +dlink_node * +make_dlink_node(void) +{ + dlink_node *lp = BlockHeapAlloc(dnode_heap); + + return lp; +} + +/* free_dlink_node() + * + * inputs - pointer to dlink_node + * output - NONE + * side effects - free given dlink_node + */ +void +free_dlink_node(dlink_node *ptr) +{ + BlockHeapFree(dnode_heap, ptr); +} + +/* + * dlink_ routines are stolen from squid, except for dlinkAddBefore, + * which is mine. + * -- adrian + */ +void +dlinkAdd(void *data, dlink_node *m, dlink_list *list) +{ + m->data = data; + m->prev = NULL; + m->next = list->head; + + /* Assumption: If list->tail != NULL, list->head != NULL */ + if (list->head != NULL) + list->head->prev = m; + else if (list->tail == NULL) + list->tail = m; + + list->head = m; + list->length++; +} + +void +dlinkAddBefore(dlink_node *b, void *data, dlink_node *m, dlink_list *list) +{ + /* Shortcut - if its the first one, call dlinkAdd only */ + if (b == list->head) + dlinkAdd(data, m, list); + else + { + m->data = data; + b->prev->next = m; + m->prev = b->prev; + b->prev = m; + m->next = b; + list->length++; + } +} + +void +dlinkAddTail(void *data, dlink_node *m, dlink_list *list) +{ + m->data = data; + m->next = NULL; + m->prev = list->tail; + + /* Assumption: If list->tail != NULL, list->head != NULL */ + if (list->tail != NULL) + list->tail->next = m; + else if (list->head == NULL) + list->head = m; + + list->tail = m; + list->length++; +} + +/* Execution profiles show that this function is called the most + * often of all non-spontaneous functions. So it had better be + * efficient. */ +void +dlinkDelete(dlink_node *m, dlink_list *list) +{ + /* Assumption: If m->next == NULL, then list->tail == m + * and: If m->prev == NULL, then list->head == m + */ + if (m->next) + m->next->prev = m->prev; + else + { + assert(list->tail == m); + list->tail = m->prev; + } + + if (m->prev) + m->prev->next = m->next; + else + { + assert(list->head == m); + list->head = m->next; + } + + /* Set this to NULL does matter */ + m->next = m->prev = NULL; + list->length--; +} + +/* + * dlinkFind + * inputs - list to search + * - data + * output - pointer to link or NULL if not found + * side effects - Look for ptr in the linked listed pointed to by link. + */ +dlink_node * +dlinkFind(dlink_list *list, void *data) +{ + dlink_node *ptr; + + DLINK_FOREACH(ptr, list->head) + if (ptr->data == data) + return ptr; + + return NULL; +} + +void +dlinkMoveList(dlink_list *from, dlink_list *to) +{ + /* There are three cases */ + /* case one, nothing in from list */ + if (from->head == NULL) + return; + + /* case two, nothing in to list */ + /* actually if to->head is NULL and to->tail isn't, thats a bug */ + if (to->head == NULL) + { + to->head = from->head; + to->tail = from->tail; + from->head = from->tail = NULL; + to->length = from->length; + from->length = 0; + return; + } + + /* third case play with the links */ + from->tail->next = to->head; + from->head->prev = to->head->prev; + to->head->prev = from->tail; + to->head = from->head; + from->head = from->tail = NULL; + to->length += from->length; + from->length = 0; + /* I think I got that right */ +} + +void +dlink_move_node(dlink_node *m, dlink_list *list_del, dlink_list *list_add) +{ + /* Assumption: If m->next == NULL, then list_del->tail == m + * and: If m->prev == NULL, then list_del->head == m + */ + if (m->next) + m->next->prev = m->prev; + else + { + assert(list->tail == m); + list_del->tail = m->prev; + } + + if (m->prev) + m->prev->next = m->next; + else + { + assert(list->head == m); + list_del->head = m->next; + } + + /* Set this to NULL does matter */ + m->prev = NULL; + m->next = list_add->head; + + /* Assumption: If list_add->tail != NULL, list_add->head != NULL */ + if (list_add->head != NULL) + list_add->head->prev = m; + else if (list_add->tail == NULL) + list_add->tail = m; + + list_add->head = m; + list_add->length++; + list_del->length--; +} + +dlink_node * +dlinkFindDelete(dlink_list *list, void *data) +{ + dlink_node *m; + + DLINK_FOREACH(m, list->head) + { + if (m->data == data) + { + if (m->next) + m->next->prev = m->prev; + else + { + assert(list->tail == m); + list->tail = m->prev; + } + if (m->prev) + m->prev->next = m->next; + else + { + assert(list->head == m); + list->head = m->next; + } + /* Set this to NULL does matter */ + m->next = m->prev = NULL; + list->length--; + + return m; + } + } + + return NULL; +} + + diff --git a/src/listener.c b/src/listener.c new file mode 100644 index 0000000..3572570 --- /dev/null +++ b/src/listener.c @@ -0,0 +1,429 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * listener.c: Listens on a port. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "listener.h" +#include "client.h" +#include "fdlist.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "ircd_defs.h" +#include "s_bsd.h" +#include "numeric.h" +#include "conf.h" +#include "send.h" +#include "memory.h" + +static PF accept_connection; + +static dlink_list ListenerPollList = { NULL, NULL, 0 }; +static void close_listener(struct Listener *listener); + +static struct Listener * +make_listener(int port, struct irc_ssaddr *addr) +{ + struct Listener *listener = MyMalloc(sizeof(struct Listener)); + + listener->port = port; + memcpy(&listener->addr, addr, sizeof(struct irc_ssaddr)); + + return listener; +} + +void +free_listener(struct Listener *listener) +{ + assert(listener != NULL); + + dlinkDelete(&listener->listener_node, &ListenerPollList); + MyFree(listener); +} + +/* + * get_listener_name - return displayable listener name and port + * returns "host.foo.org/6667" for a given listener + */ +const char * +get_listener_name(const struct Listener *const listener) +{ + static char buf[HOSTLEN + HOSTLEN + PORTNAMELEN + 4]; + + snprintf(buf, sizeof(buf), "%s[%s/%u]", me.name, + listener->name, listener->port); + return buf; +} + +/* show_ports() + * + * inputs - pointer to client to show ports to + * output - none + * side effects - send port listing to a client + */ +void +show_ports(struct Client *source_p) +{ + char buf[6]; + char *p = NULL; + dlink_node *ptr; + + DLINK_FOREACH(ptr, ListenerPollList.head) + { + const struct Listener *listener = ptr->data; + p = buf; + + if (listener->flags & LISTENER_HIDDEN) { + if (!HasUMode(source_p, UMODE_ADMIN)) + continue; + *p++ = 'H'; + } + + if (listener->flags & LISTENER_SERVER) + *p++ = 'S'; + if (listener->flags & LISTENER_SSL) + *p++ = 's'; + *p = '\0'; + sendto_one(source_p, form_str(RPL_STATSPLINE), + me.name, source_p->name, 'P', listener->port, + HasUMode(source_p, UMODE_ADMIN) ? listener->name : me.name, + listener->ref_count, buf, + listener->active ? "active" : "disabled"); + } +} + +/* + * inetport - create a listener socket in the AF_INET or AF_INET6 domain, + * bind it to the port given in 'port' and listen to it + * returns true (1) if successful false (0) on error. + * + * If the operating system has a define for SOMAXCONN, use it, otherwise + * use HYBRID_SOMAXCONN + */ +#ifdef SOMAXCONN +#undef HYBRID_SOMAXCONN +#define HYBRID_SOMAXCONN SOMAXCONN +#endif + +static int +inetport(struct Listener *listener) +{ + struct irc_ssaddr lsin; + socklen_t opt = 1; + + memset(&lsin, 0, sizeof(lsin)); + memcpy(&lsin, &listener->addr, sizeof(lsin)); + + getnameinfo((struct sockaddr *)&lsin, lsin.ss_len, listener->name, + sizeof(listener->name), NULL, 0, NI_NUMERICHOST); + + /* + * At first, open a new socket + */ + if (comm_open(&listener->fd, listener->addr.ss.ss_family, SOCK_STREAM, 0, + "Listener socket") == -1) + { + report_error(L_ALL, "opening listener socket %s:%s", + get_listener_name(listener), errno); + return 0; + } + + if (setsockopt(listener->fd.fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) + { + report_error(L_ALL, "setting SO_REUSEADDR for listener %s:%s", + get_listener_name(listener), errno); + fd_close(&listener->fd); + return 0; + } + + /* + * Bind a port to listen for new connections if port is non-null, + * else assume it is already open and try get something from it. + */ + lsin.ss_port = htons(listener->port); + + if (bind(listener->fd.fd, (struct sockaddr *)&lsin, lsin.ss_len)) + { + report_error(L_ALL, "binding listener socket %s:%s", + get_listener_name(listener), errno); + fd_close(&listener->fd); + return 0; + } + + if (listen(listener->fd.fd, HYBRID_SOMAXCONN)) + { + report_error(L_ALL, "listen failed for %s:%s", + get_listener_name(listener), errno); + fd_close(&listener->fd); + return 0; + } + + /* Listen completion events are READ events .. */ + + accept_connection(&listener->fd, listener); + return 1; +} + +static struct Listener * +find_listener(int port, struct irc_ssaddr *addr) +{ + dlink_node *ptr; + struct Listener *listener = NULL; + struct Listener *last_closed = NULL; + + DLINK_FOREACH(ptr, ListenerPollList.head) + { + listener = ptr->data; + + if ((port == listener->port) && + (!memcmp(addr, &listener->addr, sizeof(struct irc_ssaddr)))) + { + /* Try to return an open listener, otherwise reuse a closed one */ + if (!listener->fd.flags.open) + last_closed = listener; + else + return (listener); + } + } + + return (last_closed); +} + +/* + * add_listener- create a new listener + * port - the port number to listen on + * vhost_ip - if non-null must contain a valid IP address string in + * the format "255.255.255.255" + */ +void +add_listener(int port, const char *vhost_ip, unsigned int flags) +{ + struct Listener *listener; + struct irc_ssaddr vaddr; + struct addrinfo hints, *res; + char portname[PORTNAMELEN + 1]; +#ifdef IPV6 + static short int pass = 0; /* if ipv6 and no address specified we need to + have two listeners; one for each protocol. */ +#endif + + /* + * if no or invalid port in conf line, don't bother + */ + if (!(port > 0 && port <= 0xFFFF)) + return; + + memset(&vaddr, 0, sizeof(vaddr)); + + /* Set up the hints structure */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + /* Get us ready for a bind() and don't bother doing dns lookup */ + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + +#ifdef IPV6 + if (ServerInfo.can_use_v6) + { + snprintf(portname, sizeof(portname), "%d", port); + getaddrinfo("::", portname, &hints, &res); + vaddr.ss.ss_family = AF_INET6; + assert(res != NULL); + + memcpy((struct sockaddr*)&vaddr, res->ai_addr, res->ai_addrlen); + vaddr.ss_port = port; + vaddr.ss_len = res->ai_addrlen; + freeaddrinfo(res); + } + else +#endif + { + struct sockaddr_in *v4 = (struct sockaddr_in*) &vaddr; + v4->sin_addr.s_addr = INADDR_ANY; + vaddr.ss.ss_family = AF_INET; + vaddr.ss_len = sizeof(struct sockaddr_in); + v4->sin_port = htons(port); + } + + snprintf(portname, PORTNAMELEN, "%d", port); + + if (vhost_ip) + { + if (getaddrinfo(vhost_ip, portname, &hints, &res)) + return; + + assert(res != NULL); + + memcpy((struct sockaddr*)&vaddr, res->ai_addr, res->ai_addrlen); + vaddr.ss_port = port; + vaddr.ss_len = res->ai_addrlen; + freeaddrinfo(res); + } +#ifdef IPV6 + else if (pass == 0 && ServerInfo.can_use_v6) + { + /* add the ipv4 listener if we havent already */ + pass = 1; + add_listener(port, "0.0.0.0", flags); + } + pass = 0; +#endif + + if ((listener = find_listener(port, &vaddr))) + { + listener->flags = flags; + if (listener->fd.flags.open) + return; + } + else + { + listener = make_listener(port, &vaddr); + dlinkAdd(listener, &listener->listener_node, &ListenerPollList); + listener->flags = flags; + } + + if (inetport(listener)) + listener->active = 1; + else + close_listener(listener); +} + +/* + * close_listener - close a single listener + */ +static void +close_listener(struct Listener *listener) +{ + assert(listener != NULL); + + if (listener == NULL) + return; + + if (listener->fd.flags.open) + fd_close(&listener->fd); + + listener->active = 0; + + if (listener->ref_count) + return; + + free_listener(listener); +} + +/* + * close_listeners - close and free all listeners that are not being used + */ +void +close_listeners(void) +{ + dlink_node *ptr = NULL, *next_ptr = NULL; + + /* close all 'extra' listening ports we have */ + DLINK_FOREACH_SAFE(ptr, next_ptr, ListenerPollList.head) + close_listener(ptr->data); +} + +#define TOOFAST_WARNING "ERROR :Trying to reconnect too fast.\r\n" +#define DLINE_WARNING "ERROR :You have been D-lined.\r\n" + +static void +accept_connection(fde_t *pfd, void *data) +{ + static time_t last_oper_notice = 0; + struct irc_ssaddr addr; + int fd; + int pe; + struct Listener *listener = data; + + memset(&addr, 0, sizeof(addr)); + + assert(listener != NULL); + + /* There may be many reasons for error return, but + * in otherwise correctly working environment the + * probable cause is running out of file descriptors + * (EMFILE, ENFILE or others?). The man pages for + * accept don't seem to list these as possible, + * although it's obvious that it may happen here. + * Thus no specific errors are tested at this + * point, just assume that connections cannot + * be accepted until some old is closed first. + */ + while ((fd = comm_accept(listener, &addr)) != -1) + { + /* + * check for connection limit + */ + if (number_fd > hard_fdlimit - 10) + { + ++ServerStats.is_ref; + + /* + * slow down the whining to opers bit + */ + if ((last_oper_notice + 20) <= CurrentTime) + { + sendto_realops_flags(UMODE_ALL, L_ALL, "All connections in use. (%s)", + get_listener_name(listener)); + last_oper_notice = CurrentTime; + } + + if (!(listener->flags & LISTENER_SSL)) + send(fd, "ERROR :All connections in use\r\n", 32, 0); + + close(fd); + break; /* jump out and re-register a new io request */ + } + + /* + * Do an initial check we aren't connecting too fast or with too many + * from this IP... + */ + if ((pe = conf_connect_allowed(&addr, addr.ss.ss_family)) != 0) + { + ++ServerStats.is_ref; + + if (!(listener->flags & LISTENER_SSL)) + switch (pe) + { + case BANNED_CLIENT: + send(fd, DLINE_WARNING, sizeof(DLINE_WARNING)-1, 0); + break; + case TOO_FAST: + send(fd, TOOFAST_WARNING, sizeof(TOOFAST_WARNING)-1, 0); + break; + } + + close(fd); + continue; /* drop the one and keep on clearing the queue */ + } + + ++ServerStats.is_ac; + add_connection(listener, &addr, fd); + } + + /* Re-register a new IO request for the next accept .. */ + comm_setselect(&listener->fd, COMM_SELECT_READ, accept_connection, + listener, 0); +} diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000..e81257b --- /dev/null +++ b/src/log.c @@ -0,0 +1,123 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * log.c: Logger functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" + +#include "log.h" +#include "irc_string.h" +#include "ircd.h" +#include "conf.h" +#include "s_misc.h" + + +static struct { + char path[PATH_MAX + 1]; + size_t size; + FILE *file; +} log_type_table[LOG_TYPE_LAST]; + + +int +log_add_file(enum log_type type, size_t size, const char *path) +{ + if (log_type_table[type].file) + fclose(log_type_table[type].file); + + strlcpy(log_type_table[type].path, path, sizeof(log_type_table[type].path)); + log_type_table[type].size = size; + + return (log_type_table[type].file = fopen(path, "a")) != NULL; +} + +void +log_close_all(void) +{ + unsigned int type = 0; + + while (++type < LOG_TYPE_LAST) + { + if (log_type_table[type].file == NULL) + continue; + + fclose(log_type_table[type].file); + log_type_table[type].file = NULL; + } +} + +static int +log_exceed_size(unsigned int type) +{ + struct stat sb; + + if (!log_type_table[type].size) + return 0; + + if (stat(log_type_table[type].path, &sb) < 0) + return -1; + + return (size_t)sb.st_size > log_type_table[type].size; +} + +static void +log_write(enum log_type type, const char *message) +{ + char buf[IRCD_BUFSIZE]; + + strftime(buf, sizeof(buf), "[%FT%H:%M:%S%z]", localtime(&CurrentTime)); + + fprintf(log_type_table[type].file, "%s %s\n", buf, message); + fflush(log_type_table[type].file); +} + +void +ilog(enum log_type type, const char *fmt, ...) +{ + char buf[LOG_BUFSIZE]; + va_list args; + + if (!log_type_table[type].file || !ConfigLoggingEntry.use_logging) + return; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + log_write(type, buf); + + if (log_exceed_size(type) <= 0) + return; + + snprintf(buf, sizeof(buf), "Rotating logfile %s", + log_type_table[type].path); + log_write(type, buf); + + fclose(log_type_table[type].file); + log_type_table[type].file = NULL; + + snprintf(buf, sizeof(buf), "%s.old", log_type_table[type].path); + unlink(buf); + rename(log_type_table[type].path, buf); + + log_add_file(type, log_type_table[type].size, log_type_table[type].path); +} diff --git a/src/match.c b/src/match.c new file mode 100644 index 0000000..4c4513e --- /dev/null +++ b/src/match.c @@ -0,0 +1,616 @@ +/************************************************************************ + * IRC - Internet Relay Chat, src/match.c + * Copyright (C) 1990 Jarkko Oikarinen + * + * 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 1, 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. + * + * $Id$ + * + */ + +#include "stdinc.h" +#include "irc_string.h" +#include "client.h" +#include "ircd.h" + +/* Fix "statement not reached" warnings on Sun WorkShop C */ +#ifdef __SUNPRO_C +# pragma error_messages(off, E_STATEMENT_NOT_REACHED) +#endif + +/* match() + * + * Compare if a given string (name) matches the given + * mask (which can contain wild cards: '*' - match any + * number of chars, '?' - match any single character. + * + * return 1, if match + * 0, if no match + * + * Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu) + */ +int +match(const char *mask, const char *name) +{ + const unsigned char *m = (const unsigned char *)mask; + const unsigned char *n = (const unsigned char *)name; + const unsigned char *ma = NULL; + const unsigned char *na = (const unsigned char *)name; + + assert(mask != NULL); + assert(name != NULL); + + while (1) + { + if (*m == '*') + { + while (*m == '*') + m++; + ma = m; + na = n; + } + + if (!*m) + { + if (!*n) + return 1; + if (!ma) + return 0; + for (m--; (m > (const unsigned char *)mask) && (*m == '?'); m--) + ; + if (*m == '*') + return 1; + m = ma; + n = ++na; + } + else if (!*n) + { + while (*m == '*') + m++; + return *m == 0; + } + + if (ToLower(*m) != ToLower(*n) && *m != '?' && (*m != '#' || !IsDigit(*n))) + { + if (!ma) + return 0; + m = ma; + n = ++na; + } + else + m++, n++; + } + + return 0; +} + +/* match_esc() + * + * The match() function with support for escaping characters such + * as '*' and '?' + */ +int +match_esc(const char *mask, const char *name) +{ + const unsigned char *m = (const unsigned char *)mask; + const unsigned char *n = (const unsigned char *)name; + const unsigned char *ma = NULL; + const unsigned char *na = (const unsigned char *)name; + + assert(mask != NULL); + assert(name != NULL); + + while (1) + { + if (*m == '*') + { + while (*m == '*') + m++; + ma = m; + na = n; + } + + if (!*m) + { + if (!*n) + return 1; + if (!ma) + return 0; + for (m--; (m > (const unsigned char *)mask) && (*m == '?'); m--) + ; + if (*m == '*') + return 1; + m = ma; + n = ++na; + } + else if (!*n) + { + while (*m == '*') + m++; + return *m == 0; + } + + if (*m != '?' && (*m != '#' || IsDigit(*n))) + { + if (*m == '\\') + if (!*++m) + return 0; + if (ToLower(*m) != ToLower(*n)) + { + if (!ma) + return 0; + m = ma; + n = ++na; + } + else + m++, n++; + } + else + m++, n++; + } + + return 0; +} + +/* match_chan() + * + * The match_esc() function doing channel prefix auto-escape, + * ie. mask: #blah*blah is seen like \#blah*blah + */ +int +match_chan(const char *mask, const char *name) +{ + if (*mask == '#') + { + if (*name != '#') + return 0; + ++name, ++mask; + } + + return match_esc(mask, name); +} + +/* collapse() + * + * collapses a string containing multiple *'s. + */ +char * +collapse(char *pattern) +{ + char *p = pattern, *po = pattern; + char c; + + if (p == NULL) + return NULL; + + while ((c = *p++)) + { + if (c != '*') + *po++ = c; + else if (*p != '*') + *po++ = '*'; + } + + *po = 0; + + return pattern; +} + +/* collapse_esc() + * + * The collapse() function with support for escaping characters + */ +char * +collapse_esc(char *pattern) +{ + char *p = pattern, *po = pattern; + char c; + + if (p == NULL) + return NULL; + + while ((c = *p++)) + { + if (c != '*') + { + *po++ = c; + if (c == '\\' && *p) + *po++ = *p++; + } + else if (*p != '*') + *po++ = '*'; + } + + *po = 0; + + return pattern; +} + +/* + * irccmp - case insensitive comparison of two 0 terminated strings. + * + * returns 0, if s1 equal to s2 + * 1, if not + */ +int +irccmp(const char *s1, const char *s2) +{ + const unsigned char *str1 = (const unsigned char *)s1; + const unsigned char *str2 = (const unsigned char *)s2; + + assert(s1 != NULL); + assert(s2 != NULL); + + for (; ToUpper(*str1) == ToUpper(*str2); ++str1, ++str2) + if (*str1 == '\0') + return 0; + + return 1; +} + +int +ircncmp(const char *s1, const char *s2, size_t n) +{ + const unsigned char *str1 = (const unsigned char *)s1; + const unsigned char *str2 = (const unsigned char *)s2; + + assert(s1 != NULL); + assert(s2 != NULL); + assert(n > 0); + + if (n == 0) + return 0; + + for (; ToUpper(*str1) == ToUpper(*str2); ++str1, ++str2) + if (--n == 0 || *str1 == '\0') + return 0; + + return 1; +} + +const unsigned char ToLowerTab[] = { + 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, + 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, + ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')', + '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + ':', ';', '<', '=', '>', '?', + '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', + 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', + '_', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', + 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', + 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, + 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, + 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, + 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, + 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, + 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +const unsigned char ToUpperTab[] = { + 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, + 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, + ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')', + '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + ':', ';', '<', '=', '>', '?', + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', + 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', + 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', + 0x5f, + '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', + 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', + 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', + 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, + 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, + 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, + 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, + 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, + 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +/* + * CharAttrs table + * + * NOTE: RFC 1459 sez: anything but a ^G, comma, or space is allowed + * for channel names + */ +const unsigned int CharAttrs[] = { +/* 0 */ CNTRL_C, +/* 1 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 2 */ CNTRL_C|CHAN_C|NONEOS_C, +/* 3 */ CNTRL_C|CHAN_C|NONEOS_C, +/* 4 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 5 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 6 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 7 BEL */ CNTRL_C|NONEOS_C, +/* 8 \b */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 9 \t */ CNTRL_C|SPACE_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 10 \n */ CNTRL_C|SPACE_C|CHAN_C|VCHAN_C|NONEOS_C|EOL_C, +/* 11 \v */ CNTRL_C|SPACE_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 12 \f */ CNTRL_C|SPACE_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 13 \r */ CNTRL_C|SPACE_C|CHAN_C|VCHAN_C|NONEOS_C|EOL_C, +/* 14 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 15 */ CNTRL_C|CHAN_C|NONEOS_C, +/* 16 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 17 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 18 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 19 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 20 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 21 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 22 */ CNTRL_C|CHAN_C|NONEOS_C, +/* 23 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 24 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 25 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 26 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 27 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 28 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 29 */ CNTRL_C|CHAN_C|NONEOS_C, +/* 30 */ CNTRL_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 31 */ CNTRL_C|CHAN_C|NONEOS_C, +/* SP */ PRINT_C|SPACE_C, +/* ! */ PRINT_C|KWILD_C|CHAN_C|VCHAN_C|NONEOS_C, +/* " */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, +/* # */ PRINT_C|KWILD_C|MWILD_C|CHANPFX_C|CHAN_C|VCHAN_C|NONEOS_C, +/* $ */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C, +/* % */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, +/* & */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, +/* ' */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, +/* ( */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, +/* ) */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, +/* * */ PRINT_C|KWILD_C|MWILD_C|CHAN_C|VCHAN_C|NONEOS_C|SERV_C, +/* + */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, +/* , */ PRINT_C|NONEOS_C, +/* - */ PRINT_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* . */ PRINT_C|KWILD_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C|SERV_C, +/* / */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, +/* 0 */ PRINT_C|DIGIT_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* 1 */ PRINT_C|DIGIT_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* 2 */ PRINT_C|DIGIT_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* 3 */ PRINT_C|DIGIT_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* 4 */ PRINT_C|DIGIT_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* 5 */ PRINT_C|DIGIT_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* 6 */ PRINT_C|DIGIT_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* 7 */ PRINT_C|DIGIT_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* 8 */ PRINT_C|DIGIT_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* 9 */ PRINT_C|DIGIT_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* : */ PRINT_C|KWILD_C|CHAN_C|VCHAN_C|NONEOS_C|HOST_C, +/* ; */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, +/* < */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, +/* = */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, +/* > */ PRINT_C|CHAN_C|VCHAN_C|NONEOS_C, +/* ? */ PRINT_C|KWILD_C|MWILD_C|CHAN_C|VCHAN_C|NONEOS_C, +/* @ */ PRINT_C|KWILD_C|CHAN_C|VCHAN_C|NONEOS_C, +/* A */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* B */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* C */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* D */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* E */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* F */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* G */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* H */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* I */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* J */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* K */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* L */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* M */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* N */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* O */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* P */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* Q */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* R */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* S */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* T */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* U */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* V */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* W */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* X */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* Y */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* Z */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* [ */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C, +/* \ */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C, +/* ] */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C, +/* ^ */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C, +/* _ */ PRINT_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C, +/* ` */ PRINT_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C, +/* a */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* b */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* c */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* d */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* e */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* f */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* g */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* h */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* i */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* j */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* k */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* l */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* m */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* n */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* o */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* p */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* q */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* r */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* s */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* t */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* u */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* v */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* w */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* x */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* y */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* z */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C|HOST_C, +/* { */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C, +/* | */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C, +/* } */ PRINT_C|ALPHA_C|NICK_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C, +/* ~ */ PRINT_C|ALPHA_C|CHAN_C|VCHAN_C|NONEOS_C|USER_C, +/* del */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x80 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x81 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x82 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x83 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x84 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x85 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x86 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x87 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x88 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x89 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x8A */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x8B */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x8C */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x8D */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x8E */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x8F */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x90 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x91 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x92 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x93 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x94 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x95 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x96 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x97 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x98 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x99 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x9A */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x9B */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x9C */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x9D */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x9E */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0x9F */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xA0 */ CHAN_C|NONEOS_C, +/* 0xA1 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xA2 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xA3 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xA4 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xA5 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xA6 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xA7 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xA8 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xA9 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xAA */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xAB */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xAC */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xAD */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xAE */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xAF */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xB0 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xB1 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xB2 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xB3 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xB4 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xB5 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xB6 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xB7 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xB8 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xB9 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xBA */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xBB */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xBC */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xBD */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xBE */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xBF */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xC0 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xC1 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xC2 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xC3 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xC4 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xC5 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xC6 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xC7 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xC8 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xC9 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xCA */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xCB */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xCC */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xCD */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xCE */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xCF */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xD0 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xD1 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xD2 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xD3 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xD4 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xD5 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xD6 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xD7 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xD8 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xD9 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xDA */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xDB */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xDC */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xDD */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xDE */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xDF */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xE0 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xE1 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xE2 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xE3 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xE4 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xE5 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xE6 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xE7 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xE8 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xE9 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xEA */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xEB */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xEC */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xED */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xEE */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xEF */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xF0 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xF1 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xF2 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xF3 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xF4 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xF5 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xF6 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xF7 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xF8 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xF9 */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xFA */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xFB */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xFC */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xFD */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xFE */ CHAN_C|VCHAN_C|NONEOS_C, +/* 0xFF */ CHAN_C|VCHAN_C|NONEOS_C +}; diff --git a/src/memory.c b/src/memory.c new file mode 100644 index 0000000..037807a --- /dev/null +++ b/src/memory.c @@ -0,0 +1,114 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * memory.c: Memory utilities. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + + +#include "stdinc.h" +#include "ircd_defs.h" +#include "irc_string.h" +#include "memory.h" +#include "log.h" +#include "restart.h" + + +/* + * MyMalloc - allocate memory, call outofmemory on failure + */ +void * +MyMalloc(size_t size) +{ + void *ret = calloc(1, size); + + if (ret == NULL) + outofmemory(); + + return ret; +} + +/* + * MyRealloc - reallocate memory, call outofmemory on failure + */ +void * +MyRealloc(void *x, size_t y) +{ + void *ret = realloc(x, y); + + if (ret == NULL) + outofmemory(); + + return ret; +} + +void +MyFree(void *x) +{ + if (x) + free(x); +} + +void +_DupString(char **x, const char *y) +{ + (*x) = malloc(strlen(y) + 1); + strcpy((*x), y); +} + +/* outofmemory() + * + * input - NONE + * output - NONE + * side effects - simply try to report there is a problem. + * Abort if it was called more than once + */ +void +outofmemory(void) +{ + static int was_here = 0; + + if (was_here++) + abort(); + + ilog(LOG_TYPE_IRCD, "Out of memory: restarting server..."); + restart("Out of Memory"); +} + +#ifndef NDEBUG +/* + * frob some memory. debugging time. + * -- adrian + */ +void +mem_frob(void *data, int len) +{ + /* correct for Intel only! little endian */ + unsigned char b[4] = { 0xef, 0xbe, 0xad, 0xde }; + int i; + char *cdata = data; + + for (i = 0; i < len; i++) + { + *cdata = b[i % 4]; + cdata++; + } +} +#endif diff --git a/src/messages.tab b/src/messages.tab new file mode 100644 index 0000000..12e22c6 --- /dev/null +++ b/src/messages.tab @@ -0,0 +1,1029 @@ +/************************************************************************ + * IRC - Internet Relay Chat, src/messages.tab + * Copyright (C) 1992 Darren Reed + * + * 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 1, 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. + * + * $Id$ + */ + +static struct NumericInfo replies[] = { +/* 000 */ {NULL, NULL, NULL}, +/* 001 */ {"RPL_WELCOME", ":%s 001 %s :Welcome to the %s Internet Relay Chat Network %s", NULL}, +/* 002 */ {"RPL_YOURHOST", ":%s 002 %s :Your host is %s, running version %s", NULL}, +/* 003 */ {"RPL_CREATED", ":%s 003 %s :This server was created %s", NULL}, +#ifdef HALFOPS +/* 004 */ {"RPL_MYINFO", ":%s 004 %s %s %s %s biklmnoprstveIhORS bkloveIh", NULL}, +#else +/* 004 */ {"RPL_MYINFO", ":%s 004 %s %s %s %s biklmnoprstveIORS bkloveI", NULL}, +#endif +/* 005 */ {"RPL_ISUPPORT", ":%s 005 %s %s :are supported by this server", NULL}, +/* 006 */ {NULL, NULL, NULL}, +/* 007 */ {NULL, NULL, NULL}, +/* 008 */ {NULL, NULL, NULL}, +/* 009 */ {NULL, NULL, NULL}, +/* 010 */ {"RPL_REDIR", ":%s 010 %s %s %d :Please use this Server/Port instead", NULL}, +/* 011 */ {NULL, NULL, NULL}, +/* 012 */ {NULL, NULL, NULL}, +/* 013 */ {NULL, NULL, NULL}, +/* 014 */ {NULL, NULL, NULL}, +/* 015 */ {"RPL_MAP", ":%s 015 %s :%s", NULL}, +/* 016 */ {NULL, NULL, NULL}, +/* 017 */ {"RPL_MAPEND", ":%s 017 %s :End of /MAP", NULL}, +/* 018 */ {NULL, NULL, NULL}, +/* 019 */ {NULL, NULL, NULL}, +/* 020 */ {NULL, NULL, NULL}, +/* 021 */ {NULL, NULL, NULL}, +/* 022 */ {NULL, NULL, NULL}, +/* 023 */ {NULL, NULL, NULL}, +/* 024 */ {NULL, NULL, NULL}, +/* 025 */ {NULL, NULL, NULL}, +/* 026 */ {NULL, NULL, NULL}, +/* 027 */ {NULL, NULL, NULL}, +/* 028 */ {NULL, NULL, NULL}, +/* 029 */ {NULL, NULL, NULL}, +/* 030 */ {NULL, NULL, NULL}, +/* 031 */ {NULL, NULL, NULL}, +/* 032 */ {NULL, NULL, NULL}, +/* 033 */ {NULL, NULL, NULL}, +/* 034 */ {NULL, NULL, NULL}, +/* 035 */ {NULL, NULL, NULL}, +/* 036 */ {NULL, NULL, NULL}, +/* 037 */ {NULL, NULL, NULL}, +/* 038 */ {NULL, NULL, NULL}, +/* 039 */ {NULL, NULL, NULL}, +/* 040 */ {NULL, NULL, NULL}, +/* 041 */ {NULL, NULL, NULL}, +/* 042 */ {"RPL_YOURID", ":%s 042 %s %s :your unique ID", NULL}, +/* 043 */ {NULL, NULL, NULL}, +/* 044 */ {NULL, NULL, NULL}, +/* 045 */ {NULL, NULL, NULL}, +/* 046 */ {NULL, NULL, NULL}, +/* 047 */ {NULL, NULL, NULL}, +/* 048 */ {NULL, NULL, NULL}, +/* 049 */ {NULL, NULL, NULL}, +/* 050 */ {NULL, NULL, NULL}, +/* 051 */ {NULL, NULL, NULL}, +/* 052 */ {NULL, NULL, NULL}, +/* 053 */ {NULL, NULL, NULL}, +/* 054 */ {NULL, NULL, NULL}, +/* 055 */ {NULL, NULL, NULL}, +/* 056 */ {NULL, NULL, NULL}, +/* 057 */ {NULL, NULL, NULL}, +/* 058 */ {NULL, NULL, NULL}, +/* 059 */ {NULL, NULL, NULL}, +/* 060 */ {NULL, NULL, NULL}, +/* 061 */ {NULL, NULL, NULL}, +/* 062 */ {NULL, NULL, NULL}, +/* 063 */ {NULL, NULL, NULL}, +/* 064 */ {NULL, NULL, NULL}, +/* 065 */ {NULL, NULL, NULL}, +/* 066 */ {NULL, NULL, NULL}, +/* 067 */ {NULL, NULL, NULL}, +/* 068 */ {NULL, NULL, NULL}, +/* 069 */ {NULL, NULL, NULL}, +/* 070 */ {NULL, NULL, NULL}, +/* 071 */ {NULL, NULL, NULL}, +/* 072 */ {NULL, NULL, NULL}, +/* 073 */ {NULL, NULL, NULL}, +/* 074 */ {NULL, NULL, NULL}, +/* 075 */ {NULL, NULL, NULL}, +/* 076 */ {NULL, NULL, NULL}, +/* 077 */ {NULL, NULL, NULL}, +/* 078 */ {NULL, NULL, NULL}, +/* 079 */ {NULL, NULL, NULL}, +/* 080 */ {NULL, NULL, NULL}, +/* 081 */ {NULL, NULL, NULL}, +/* 082 */ {NULL, NULL, NULL}, +/* 083 */ {NULL, NULL, NULL}, +/* 084 */ {NULL, NULL, NULL}, +/* 085 */ {NULL, NULL, NULL}, +/* 086 */ {NULL, NULL, NULL}, +/* 087 */ {NULL, NULL, NULL}, +/* 088 */ {NULL, NULL, NULL}, +/* 089 */ {NULL, NULL, NULL}, +/* 090 */ {NULL, NULL, NULL}, +/* 091 */ {NULL, NULL, NULL}, +/* 092 */ {NULL, NULL, NULL}, +/* 093 */ {NULL, NULL, NULL}, +/* 094 */ {NULL, NULL, NULL}, +/* 095 */ {NULL, NULL, NULL}, +/* 096 */ {NULL, NULL, NULL}, +/* 097 */ {NULL, NULL, NULL}, +/* 098 */ {NULL, NULL, NULL}, +/* 099 */ {NULL, NULL, NULL}, +/* 100 */ {NULL, NULL, NULL}, +/* 101 */ {NULL, NULL, NULL}, +/* 102 */ {NULL, NULL, NULL}, +/* 103 */ {NULL, NULL, NULL}, +/* 104 */ {NULL, NULL, NULL}, +/* 105 */ {NULL, NULL, NULL}, +/* 106 */ {NULL, NULL, NULL}, +/* 107 */ {NULL, NULL, NULL}, +/* 108 */ {NULL, NULL, NULL}, +/* 109 */ {NULL, NULL, NULL}, +/* 110 */ {NULL, NULL, NULL}, +/* 111 */ {NULL, NULL, NULL}, +/* 112 */ {NULL, NULL, NULL}, +/* 113 */ {NULL, NULL, NULL}, +/* 114 */ {NULL, NULL, NULL}, +/* 115 */ {NULL, NULL, NULL}, +/* 116 */ {NULL, NULL, NULL}, +/* 117 */ {NULL, NULL, NULL}, +/* 118 */ {NULL, NULL, NULL}, +/* 119 */ {NULL, NULL, NULL}, +/* 120 */ {NULL, NULL, NULL}, +/* 121 */ {NULL, NULL, NULL}, +/* 122 */ {NULL, NULL, NULL}, +/* 123 */ {NULL, NULL, NULL}, +/* 124 */ {NULL, NULL, NULL}, +/* 125 */ {NULL, NULL, NULL}, +/* 126 */ {NULL, NULL, NULL}, +/* 127 */ {NULL, NULL, NULL}, +/* 128 */ {NULL, NULL, NULL}, +/* 129 */ {NULL, NULL, NULL}, +/* 130 */ {NULL, NULL, NULL}, +/* 131 */ {NULL, NULL, NULL}, +/* 132 */ {NULL, NULL, NULL}, +/* 133 */ {NULL, NULL, NULL}, +/* 134 */ {NULL, NULL, NULL}, +/* 135 */ {NULL, NULL, NULL}, +/* 136 */ {NULL, NULL, NULL}, +/* 137 */ {NULL, NULL, NULL}, +/* 138 */ {NULL, NULL, NULL}, +/* 139 */ {NULL, NULL, NULL}, +/* 140 */ {NULL, NULL, NULL}, +/* 141 */ {NULL, NULL, NULL}, +/* 142 */ {NULL, NULL, NULL}, +/* 143 */ {NULL, NULL, NULL}, +/* 144 */ {NULL, NULL, NULL}, +/* 145 */ {NULL, NULL, NULL}, +/* 146 */ {NULL, NULL, NULL}, +/* 147 */ {NULL, NULL, NULL}, +/* 148 */ {NULL, NULL, NULL}, +/* 149 */ {NULL, NULL, NULL}, +/* 150 */ {NULL, NULL, NULL}, +/* 151 */ {NULL, NULL, NULL}, +/* 152 */ {NULL, NULL, NULL}, +/* 153 */ {NULL, NULL, NULL}, +/* 154 */ {NULL, NULL, NULL}, +/* 155 */ {NULL, NULL, NULL}, +/* 156 */ {NULL, NULL, NULL}, +/* 157 */ {NULL, NULL, NULL}, +/* 158 */ {NULL, NULL, NULL}, +/* 159 */ {NULL, NULL, NULL}, +/* 160 */ {NULL, NULL, NULL}, +/* 161 */ {NULL, NULL, NULL}, +/* 162 */ {NULL, NULL, NULL}, +/* 163 */ {NULL, NULL, NULL}, +/* 164 */ {NULL, NULL, NULL}, +/* 165 */ {NULL, NULL, NULL}, +/* 166 */ {NULL, NULL, NULL}, +/* 167 */ {NULL, NULL, NULL}, +/* 168 */ {NULL, NULL, NULL}, +/* 169 */ {NULL, NULL, NULL}, +/* 170 */ {NULL, NULL, NULL}, +/* 171 */ {NULL, NULL, NULL}, +/* 172 */ {NULL, NULL, NULL}, +/* 173 */ {NULL, NULL, NULL}, +/* 174 */ {NULL, NULL, NULL}, +/* 175 */ {NULL, NULL, NULL}, +/* 176 */ {NULL, NULL, NULL}, +/* 177 */ {NULL, NULL, NULL}, +/* 178 */ {NULL, NULL, NULL}, +/* 179 */ {NULL, NULL, NULL}, +/* 180 */ {NULL, NULL, NULL}, +/* 181 */ {NULL, NULL, NULL}, +/* 182 */ {NULL, NULL, NULL}, +/* 183 */ {NULL, NULL, NULL}, +/* 184 */ {NULL, NULL, NULL}, +/* 185 */ {NULL, NULL, NULL}, +/* 186 */ {NULL, NULL, NULL}, +/* 187 */ {NULL, NULL, NULL}, +/* 188 */ {NULL, NULL, NULL}, +/* 189 */ {NULL, NULL, NULL}, +/* 190 */ {NULL, NULL, NULL}, +/* 191 */ {NULL, NULL, NULL}, +/* 192 */ {NULL, NULL, NULL}, +/* 193 */ {NULL, NULL, NULL}, +/* 194 */ {NULL, NULL, NULL}, +/* 195 */ {NULL, NULL, NULL}, +/* 196 */ {NULL, NULL, NULL}, +/* 197 */ {NULL, NULL, NULL}, +/* 198 */ {NULL, NULL, NULL}, +/* 199 */ {NULL, NULL, NULL}, +/* 200 */ {"RPL_TRACELINK", ":%s 200 %s Link %s %s %s", NULL}, +/* 201 */ {"RPL_TRACECONNECTING", ":%s 201 %s Try. %s %s", NULL}, +/* 202 */ {"RPL_TRACEHANDSHAKE", ":%s 202 %s H.S. %s %s", NULL}, +/* 203 */ {"RPL_TRACEUNKNOWN", ":%s 203 %s ???? %s %s (%s) %d", NULL}, +/* 204 */ {"RPL_TRACEOPERATOR", ":%s 204 %s Oper %s %s (%s) %lu %lu", NULL}, +/* 205 */ {"RPL_TRACEUSER", ":%s 205 %s User %s %s (%s) %lu %lu", NULL}, +/* 206 */ {"RPL_TRACESERVER", ":%s 206 %s Serv %s %dS %dC %s %s!%s@%s %lu", NULL}, +/* 207 */ {NULL, NULL, NULL}, +/* 208 */ {"RPL_TRACENEWTYPE", ":%s 208 %s <newtype> 0 %s", NULL}, +/* 209 */ {"RPL_TRACECLASS", ":%s 209 %s Class %s %d", NULL}, +/* 210 */ {NULL, NULL, NULL}, +/* 211 */ {"RPL_STATSLINKINFO", ":%s 211 %s %s %u %u %llu %u %llu :%u %u %s", NULL}, +/* 212 */ {"RPL_STATSCOMMANDS", ":%s 212 %s %s %u %llu :%u", NULL}, +/* 213 */ {"RPL_STATSCLINE", ":%s 213 %s %c %s %s %s %d %s", NULL}, +/* 214 */ {"RPL_STATSNLINE", ":%s 214 %s %c %s * %s %d %s", NULL}, +/* 215 */ {"RPL_STATSILINE", ":%s 215 %s %c %s * %s@%s %d %s", NULL}, +/* 216 */ {"RPL_STATSKLINE", ":%s 216 %s %s %s * %s :%s | %s", NULL}, +/* 217 */ {"RPL_STATSQLINE", ":%s 217 %s %c %s :%s", NULL}, +/* 218 */ {"RPL_STATSYLINE", ":%s 218 %s %c %s %d %d %d %lu %lu %d %d/%d %d/%d %s", NULL}, +/* 219 */ {"RPL_ENDOFSTATS", ":%s 219 %s %c :End of /STATS report", NULL}, +/* 220 */ {"RPL_STATSPLINE", ":%s 220 %s %c %d %s %d %s :%s", NULL}, +/* 221 */ {"RPL_UMODEIS", ":%s 221 %s %s", NULL}, +/* 222 */ {NULL, NULL, NULL}, +/* 223 */ {NULL, NULL, NULL}, +/* 224 */ {NULL, NULL, NULL}, +/* 225 */ {"RPL_STATSDLINE", ":%s 225 %s %c %s :%s | %s", NULL}, +/* 226 */ {"RPL_STATSALINE", ":%s 226 %s %s", NULL}, +/* 227 */ {NULL, NULL, NULL}, +/* 228 */ {NULL, NULL, NULL}, +/* 229 */ {NULL, NULL, NULL}, +/* 230 */ {NULL, NULL, NULL}, +/* 231 */ {NULL, NULL, NULL}, +/* 232 */ {NULL, NULL, NULL}, +/* 233 */ {NULL, NULL, NULL}, +/* 234 */ {NULL, NULL, NULL}, +/* 235 */ {NULL, NULL, NULL}, +/* 236 */ {NULL, NULL, NULL}, +/* 237 */ {NULL, NULL, NULL}, +/* 238 */ {NULL, NULL, NULL}, +/* 239 */ {NULL, NULL, NULL}, +/* 240 */ {NULL, NULL, NULL}, +/* 241 */ {"RPL_STATSLLINE", ":%s 241 %s %c %s * %s %d %s", NULL}, +/* 242 */ {"RPL_STATSUPTIME", ":%s 242 %s :Server Up %d days, %d:%02d:%02d", NULL}, +/* 243 */ {"RPL_STATSOLINE", ":%s 243 %s %c %s@%s * %s %s %s", NULL}, +/* 244 */ {"RPL_STATSHLINE", ":%s 244 %s %c %s * %s %d %s", NULL}, +/* 245 */ {"RPL_STATSSLINE", NULL, NULL}, +/* 246 */ {"RPL_STATSSERVICE", ":%s 246 %s %c %s * %s %d %d", NULL}, +/* 247 */ {"RPL_STATSXLINE", ":%s 247 %s %s %d %s :%s", NULL}, +/* 248 */ {"RPL_STATSULINE", ":%s 248 %s U %s %s@%s %s", NULL}, +/* 249 */ {NULL, NULL, NULL}, +/* 250 */ {"RPL_STATSCONN", ":%s 250 %s :Highest connection count: %d (%d clients) (%llu connections received)", NULL}, +/* 251 */ {"RPL_LUSERCLIENT", ":%s 251 %s :There are %d users and %d invisible on %d servers", NULL}, +/* 252 */ {"RPL_LUSEROP", ":%s 252 %s %d :IRC Operators online", NULL}, +/* 253 */ {"RPL_LUSERUNKNOWN", ":%s 253 %s %d :unknown connection(s)", NULL}, +/* 254 */ {"RPL_LUSERCHANNELS", ":%s 254 %s %d :channels formed", NULL}, +/* 255 */ {"RPL_LUSERME", ":%s 255 %s :I have %d clients and %d servers", NULL}, +/* 256 */ {"RPL_ADMINME", ":%s 256 %s :Administrative info about %s", NULL}, +/* 257 */ {"RPL_ADMINLOC1", ":%s 257 %s :%s", NULL}, +/* 258 */ {"RPL_ADMINLOC2", ":%s 258 %s :%s", NULL}, +/* 259 */ {"RPL_ADMINEMAIL", ":%s 259 %s :%s", NULL}, +/* 260 */ {NULL, NULL, NULL}, +/* 261 */ {NULL, NULL, NULL}, +/* 262 */ {"RPL_ENDOFTRACE", ":%s 262 %s %s :End of TRACE", NULL}, +/* 263 */ {"RPL_LOAD2HI", ":%s 263 %s :Server load is temporarily too heavy. Please wait a while and try again.", NULL}, +/* 264 */ {NULL, NULL, NULL}, +/* 265 */ {"RPL_LOCALUSERS", ":%s 265 %s :Current local users: %d Max: %d", NULL}, +/* 266 */ {"RPL_GLOBALUSERS", ":%s 266 %s :Current global users: %d Max: %d", NULL}, +/* 267 */ {NULL, NULL, NULL}, +/* 268 */ {NULL, NULL, NULL}, +/* 269 */ {NULL, NULL, NULL}, +/* 270 */ {NULL, NULL, NULL}, +/* 271 */ {NULL, NULL, NULL}, +/* 272 */ {NULL, NULL, NULL}, +/* 273 */ {NULL, NULL, NULL}, +/* 274 */ {NULL, NULL, NULL}, +/* 275 */ {NULL, NULL, NULL}, +/* 276 */ {NULL, NULL, NULL}, +/* 277 */ {NULL, NULL, NULL}, +/* 278 */ {NULL, NULL, NULL}, +/* 279 */ {NULL, NULL, NULL}, +/* 280 */ {NULL, NULL, NULL}, +/* 281 */ {"RPL_ACCEPTLIST", ":%s 281 %s :%s", NULL}, +/* 282 */ {"RPL_ENDOFACCEPT", ":%s 282 %s :End of /ACCEPT list.", NULL}, +/* 283 */ {NULL, NULL, NULL}, +/* 284 */ {NULL, NULL, NULL}, +/* 285 */ {NULL, NULL, NULL}, +/* 286 */ {NULL, NULL, NULL}, +/* 287 */ {NULL, NULL, NULL}, +/* 288 */ {NULL, NULL, NULL}, +/* 289 */ {NULL, NULL, NULL}, +/* 290 */ {NULL, NULL, NULL}, +/* 291 */ {NULL, NULL, NULL}, +/* 292 */ {NULL, NULL, NULL}, +/* 293 */ {NULL, NULL, NULL}, +/* 294 */ {NULL, NULL, NULL}, +/* 295 */ {NULL, NULL, NULL}, +/* 296 */ {NULL, NULL, NULL}, +/* 297 */ {NULL, NULL, NULL}, +/* 298 */ {NULL, NULL, NULL}, +/* 299 */ {NULL, NULL, NULL}, +/* 300 */ {NULL, NULL, NULL}, +/* 301 */ {"RPL_AWAY", ":%s 301 %s %s :%s", NULL}, +/* 302 */ {"RPL_USERHOST", ":%s 302 %s :%s", NULL}, +/* 303 */ {"RPL_ISON", ":%s 303 %s :", NULL}, +/* 304 */ {"RPL_TEXT", NULL, NULL}, +/* 305 */ {"RPL_UNAWAY", ":%s 305 %s :You are no longer marked as being away", NULL}, +/* 306 */ {"RPL_NOWAWAY", ":%s 306 %s :You have been marked as being away", NULL}, +/* 307 */ {"RPL_WHOISREGNICK", ":%s 307 %s %s :has identified for this nick", NULL}, +/* 308 */ {"RPL_WHOISADMIN", ":%s 313 %s %s :is a Server Administrator", NULL}, +/* 309 */ {NULL, NULL, NULL}, +/* 310 */ {NULL, NULL, NULL}, +/* 311 */ {"RPL_WHOISUSER", ":%s 311 %s %s %s %s * :%s", NULL}, +/* 312 */ {"RPL_WHOISSERVER", ":%s 312 %s %s %s :%s", NULL}, +/* 313 */ {"RPL_WHOISOPERATOR", ":%s 313 %s %s :is an IRC Operator", NULL}, +/* 314 */ {"RPL_WHOWASUSER", ":%s 314 %s %s %s %s * :%s", NULL}, +/* 315 */ {"RPL_ENDOFWHO", ":%s 315 %s %s :End of /WHO list.", NULL}, +/* 316 */ {"RPL_WHOISCHANOP", NULL, NULL}, +/* 317 */ {"RPL_WHOISIDLE", ":%s 317 %s %s %d %d :seconds idle, signon time", NULL}, +/* 318 */ {"RPL_ENDOFWHOIS", ":%s 318 %s %s :End of /WHOIS list.", NULL}, +/* 319 */ {"RPL_WHOISCHANNELS", ":%s 319 %s %s :%s", NULL}, +/* 320 */ {NULL, NULL, NULL}, +/* 321 */ {"RPL_LISTSTART", ":%s 321 %s Channel :Users Name", NULL}, +/* 322 */ {"RPL_LIST", ":%s 322 %s %s %d :%s", NULL}, +/* 323 */ {"RPL_LISTEND", ":%s 323 %s :End of /LIST", NULL}, +/* 324 */ {"RPL_CHANNELMODEIS", ":%s 324 %s %s %s %s", NULL}, +/* 325 */ {NULL, NULL, NULL}, +/* 326 */ {NULL, NULL, NULL}, +/* 327 */ {NULL, NULL, NULL}, +/* 328 */ {NULL, NULL, NULL}, +/* 329 */ {"RPL_CREATIONTIME", ":%s 329 %s %s %lu", NULL}, +/* 330 */ {NULL, NULL, NULL}, +/* 331 */ {"RPL_NOTOPIC", ":%s 331 %s %s :No topic is set.", NULL}, +/* 332 */ {"RPL_TOPIC", ":%s 332 %s %s :%s", NULL}, +/* 333 */ {"RPL_TOPICWHOTIME", ":%s 333 %s %s %s %lu", NULL}, +/* 334 */ {NULL, NULL, NULL}, +/* 335 */ {NULL, NULL, NULL}, +/* 336 */ {NULL, NULL, NULL}, +/* 337 */ {NULL, NULL, NULL}, +/* 338 */ {"RPL_WHOISACTUALLY", ":%s 338 %s %s %s :actually using host", NULL}, +/* 339 */ {NULL, NULL, NULL}, +/* 340 */ {NULL, NULL, NULL}, +/* 341 */ {"RPL_INVITING", ":%s 341 %s %s %s", NULL}, +/* 342 */ {NULL, NULL, NULL}, +/* 343 */ {NULL, NULL, NULL}, +/* 344 */ {NULL, NULL, NULL}, +/* 345 */ {NULL, NULL, NULL}, +/* 346 */ {"RPL_INVEXLIST", ":%s 346 %s %s %s!%s@%s %s %lu", NULL}, +/* 347 */ {"RPL_ENDOFINVEXLIST", ":%s 347 %s %s :End of Channel Invite List", NULL}, +/* 348 */ {"RPL_EXCEPTLIST", ":%s 348 %s %s %s!%s@%s %s %lu", NULL}, +/* 349 */ {"RPL_ENDOFEXCEPTLIST", ":%s 349 %s %s :End of Channel Exception List", NULL}, +/* 350 */ {NULL, NULL, NULL}, +/* 351 */ {"RPL_VERSION", ":%s 351 %s %s(%s). %s :%s%s", NULL}, +/* 352 */ {"RPL_WHOREPLY", ":%s 352 %s %s %s %s %s %s %s :%d %s", NULL}, +/* 353 */ {"RPL_NAMREPLY", ":%s 353 %s %s %s :", NULL}, +/* 354 */ {NULL, NULL, NULL}, +/* 355 */ {NULL, NULL, NULL}, +/* 356 */ {NULL, NULL, NULL}, +/* 357 */ {NULL, NULL, NULL}, +/* 358 */ {NULL, NULL, NULL}, +/* 359 */ {NULL, NULL, NULL}, +/* 360 */ {NULL, NULL, NULL}, +/* 361 */ {NULL, NULL, NULL}, +/* 362 */ {"RPL_CLOSING", ":%s 362 %s %s :Closed. Status = %d", NULL}, +/* 363 */ {"RPL_CLOSEEND", ":%s 363 %s %d: Connections Closed", NULL}, +/* 364 */ {"RPL_LINKS", ":%s 364 %s %s %s :%d %s", NULL}, +/* 365 */ {"RPL_ENDOFLINKS", ":%s 365 %s %s :End of /LINKS list.", NULL}, +/* 366 */ {"RPL_ENDOFNAMES", ":%s 366 %s %s :End of /NAMES list.", NULL}, +/* 367 */ {"RPL_BANLIST", ":%s 367 %s %s %s!%s@%s %s %lu", NULL}, +/* 368 */ {"RPL_ENDOFBANLIST", ":%s 368 %s %s :End of Channel Ban List", NULL}, +/* 369 */ {"RPL_ENDOFWHOWAS", ":%s 369 %s %s :End of WHOWAS", NULL}, +/* 370 */ {NULL, NULL, NULL}, +/* 371 */ {"RPL_INFO", ":%s 371 %s :%s", NULL}, +/* 372 */ {"RPL_MOTD", ":%s 372 %s :- %s", NULL}, +/* 373 */ {"RPL_INFOSTART", ":%s 373 %s :Server INFO", NULL}, +/* 374 */ {"RPL_ENDOFINFO", ":%s 374 %s :End of /INFO list.", NULL}, +/* 375 */ {"RPL_MOTDSTART", ":%s 375 %s :- %s Message of the Day - ", NULL}, +/* 376 */ {"RPL_ENDOFMOTD", ":%s 376 %s :End of /MOTD command.", NULL}, +/* 377 */ {NULL, NULL, NULL}, +/* 378 */ {NULL, NULL, NULL}, +/* 379 */ {NULL, NULL, NULL}, +/* 380 */ {NULL, NULL, NULL}, +/* 381 */ {"RPL_YOUREOPER", ":%s 381 %s :You have entered... the Twilight Zone!", NULL}, +/* 382 */ {"RPL_REHASHING", ":%s 382 %s %s :Rehashing", NULL}, +/* 383 */ {NULL, NULL, NULL}, +/* 384 */ {NULL, NULL, NULL}, +/* 385 */ {NULL, NULL, NULL}, +/* 386 */ {NULL, ":%s 386 %s :%s", NULL}, +/* 387 */ {NULL, NULL, NULL}, +/* 388 */ {NULL, NULL, NULL}, +/* 389 */ {NULL, NULL, NULL}, +/* 390 */ {NULL, NULL, NULL}, +/* 391 */ {"RPL_TIME", ":%s 391 %s %s :%s", NULL}, +/* 392 */ {NULL, NULL, NULL}, +/* 393 */ {NULL, NULL, NULL}, +/* 394 */ {NULL, NULL, NULL}, +/* 395 */ {NULL, NULL, NULL}, +/* 396 */ {"RPL_HOSTHIDDEN", ":%s 396 %s %s :is now your hidden host", NULL}, +/* 397 */ {NULL, NULL, NULL}, +/* 398 */ {NULL, NULL, NULL}, +/* 399 */ {NULL, NULL, NULL}, +/* 400 */ {NULL, NULL, NULL}, +/* 401 */ {"ERR_NOSUCHNICK", ":%s 401 %s %s :No such nick/channel", NULL}, +/* 402 */ {"ERR_NOSUCHSERVER", ":%s 402 %s %s :No such server", NULL}, +/* 403 */ {"ERR_NOSUCHCHANNEL", ":%s 403 %s %s :No such channel", NULL}, +/* 404 */ {"ERR_CANNOTSENDTOCHAN", ":%s 404 %s %s :Cannot send to channel", NULL}, +/* 405 */ {"ERR_TOOMANYCHANNELS", ":%s 405 %s %s :You have joined too many channels", NULL}, +/* 406 */ {"ERR_WASNOSUCHNICK", ":%s 406 %s %s :There was no such nickname", NULL}, +/* 407 */ {"ERR_TOOMANYTARGETS", ":%s 407 %s %s :Too many recipients. Only %d processed", NULL}, +/* 408 */ {NULL, NULL, NULL}, +/* 409 */ {"ERR_NOORIGIN", ":%s 409 %s :No origin specified", NULL}, +/* 410 */ {"ERR_INVALIDCAPCMD", ":%s 410 %s %s :Invalid CAP subcommand", NULL}, +/* 411 */ {"ERR_NORECIPIENT", ":%s 411 %s :No recipient given (%s)", NULL}, +/* 412 */ {"ERR_NOTEXTTOSEND", ":%s 412 %s :No text to send", NULL}, +/* 413 */ {"ERR_NOTOPLEVEL", ":%s 413 %s %s :No toplevel domain specified", NULL}, +/* 414 */ {"ERR_WILDTOPLEVEL", ":%s 414 %s %s :Wildcard in toplevel Domain", NULL}, +/* 415 */ {NULL, NULL, NULL}, +/* 416 */ {NULL, NULL, NULL}, +/* 417 */ {NULL, NULL, NULL}, +/* 418 */ {NULL, NULL, NULL}, +/* 419 */ {NULL, NULL, NULL}, +/* 420 */ {NULL, NULL, NULL}, +/* 421 */ {"ERR_UNKNOWNCOMMAND", ":%s 421 %s %s :Unknown command", NULL}, +/* 422 */ {"ERR_NOMOTD", ":%s 422 %s :MOTD File is missing", NULL}, +/* 423 */ {"ERR_NOADMININFO", ":%s 423 %s %s :No administrative info available", NULL}, +/* 424 */ {NULL, NULL, NULL}, +/* 425 */ {NULL, NULL, NULL}, +/* 426 */ {NULL, NULL, NULL}, +/* 427 */ {NULL, NULL, NULL}, +/* 428 */ {NULL, NULL, NULL}, +/* 429 */ {NULL, NULL, NULL}, +/* 430 */ {NULL, NULL, NULL}, +/* 431 */ {"ERR_NONICKNAMEGIVEN", ":%s 431 %s :No nickname given", NULL}, +/* 432 */ {"ERR_ERRONEUSNICKNAME", ":%s 432 %s %s :Erroneous Nickname", NULL}, +/* 433 */ {"ERR_NICKNAMEINUSE", ":%s 433 %s %s :Nickname is already in use.", NULL}, +/* 434 */ {NULL, NULL, NULL}, +/* 435 */ {NULL, NULL, NULL}, +/* 436 */ {"ERR_NICKCOLLISION", ":%s 436 %s %s :Nickname collision KILL", NULL}, +/* 437 */ {"ERR_UNAVAILRESOURCE", ":%s 437 %s %s :Nick/channel is temporarily unavailable", NULL}, +/* 438 */ {"ERR_NICKTOOFAST", ":%s 438 %s %s %s :Nick change too fast. Please wait %d seconds.", NULL}, +/* 439 */ {NULL, NULL, NULL}, +/* 440 */ {"ERR_SERVICESDOWN", ":%s 440 %s %s :Services is currently down.", NULL}, +/* 441 */ {"ERR_USERNOTINCHANNEL", ":%s 441 %s %s %s :They aren't on that channel", NULL}, +/* 442 */ {"ERR_NOTONCHANNEL", ":%s 442 %s %s :You're not on that channel", NULL}, +/* 443 */ {"ERR_USERONCHANNEL", ":%s 443 %s %s %s :is already on channel", NULL}, +/* 444 */ {NULL, NULL, NULL}, +/* 445 */ {NULL, NULL, NULL}, +/* 446 */ {NULL, NULL, NULL}, +/* 447 */ {NULL, NULL, NULL}, +/* 448 */ {NULL, NULL, NULL}, +/* 449 */ {NULL, NULL, NULL}, +/* 450 */ {NULL, NULL, NULL}, +/* 451 */ {"ERR_NOTREGISTERED", ":%s 451 %s :You have not registered", NULL}, +/* 452 */ {NULL, NULL, NULL}, +/* 453 */ {NULL, NULL, NULL}, +/* 454 */ {NULL, NULL, NULL}, +/* 455 */ {NULL, NULL, NULL}, +/* 456 */ {"ERR_ACCEPTFULL", ":%s 456 %s :Accept list is full", NULL}, +/* 457 */ {"ERR_ACCEPTEXIST", ":%s 457 %s %s!%s@%s :is already on your accept list", NULL}, +/* 458 */ {"ERR_ACCEPTNOT", ":%s 458 %s %s!%s@%s :is not on your accept list", NULL}, +/* 459 */ {NULL, NULL, NULL}, +/* 460 */ {NULL, NULL, NULL}, +/* 461 */ {"ERR_NEEDMOREPARAMS", ":%s 461 %s %s :Not enough parameters", NULL}, +/* 462 */ {"ERR_ALREADYREGISTRED", ":%s 462 %s :You may not reregister", NULL}, +/* 463 */ {NULL, NULL, NULL}, +/* 464 */ {"ERR_PASSWDMISMATCH", ":%s 464 %s :Password Incorrect", NULL}, +/* 465 */ {"ERR_YOUREBANNEDCREEP", ":%s 465 %s :You are banned from this server- %s", NULL}, +/* 466 */ {NULL, NULL, NULL}, +/* 467 */ {NULL, NULL, NULL}, +/* 468 */ {"ERR_ONLYSERVERSCANCHANGE", ":%s 468 %s %s :Only servers can change that mode", NULL}, +/* 469 */ {NULL, NULL, NULL}, +/* 470 */ {"ERR_OPERONLYCHAN", ":%s 470 %s %s :Cannot join channel (+O)", NULL}, +/* 471 */ {"ERR_CHANNELISFULL", ":%s 471 %s %s :Cannot join channel (+l)", NULL}, +/* 472 */ {"ERR_UNKNOWNMODE", ":%s 472 %s %c :is unknown mode char to me", NULL}, +/* 473 */ {"ERR_INVITEONLYCHAN", ":%s 473 %s %s :Cannot join channel (+i)", NULL}, +/* 474 */ {"ERR_BANNEDFROMCHAN", ":%s 474 %s %s :Cannot join channel (+b)", NULL}, +/* 475 */ {"ERR_BADCHANNELKEY", ":%s 475 %s %s :Cannot join channel (+k)", NULL}, +/* 476 */ {NULL, NULL, NULL}, +/* 477 */ {"ERR_NEEDREGGEDNICK", ":%s 477 %s %s :You need to identify to a registered nick to join or speak in that " + "channel.", NULL}, +/* 478 */ {"ERR_BANLISTFULL", ":%s 478 %s %s %s :Channel ban list is full", NULL}, +/* 479 */ {"ERR_BADCHANNAME", ":%s 479 %s %s :Illegal channel name", NULL}, +/* 480 */ {"ERR_SSLONLYCHAN", ":%s 480 %s %s :Cannot join channel (+S)", NULL}, +/* 481 */ {"ERR_NOPRIVILEGES", ":%s 481 %s :Permission Denied - You're not an IRC operator", NULL}, +/* 482 */ {"ERR_CHANOPRIVSNEEDED", ":%s 482 %s %s :You're not channel operator", NULL}, +/* 483 */ {"ERR_CANTKILLSERVER", ":%s 483 %s :You can't kill a server!", NULL}, +/* 484 */ {"ERR_RESTRICTED", ":%s 484 %s :You are restricted", NULL}, +/* 485 */ {NULL, NULL, NULL}, +/* 486 */ {"ERR_NONONREG", ":%s 486 %s %s :You must identify to a registered " + "nick to private message that person", NULL}, +/* 487 */ {NULL, NULL, NULL}, +/* 488 */ {NULL, NULL, NULL}, +/* 489 */ {NULL, NULL, NULL}, +/* 490 */ {NULL, NULL, NULL}, +/* 491 */ {"ERR_NOOPERHOST", ":%s 491 %s :Only few of mere mortals may try to enter the twilight zone", NULL}, +/* 492 */ {NULL, NULL, NULL}, +/* 493 */ {NULL, NULL, NULL}, +/* 494 */ {NULL, NULL, NULL}, +/* 495 */ {NULL, NULL, NULL}, +/* 496 */ {NULL, NULL, NULL}, +/* 497 */ {NULL, NULL, NULL}, +/* 498 */ {NULL, NULL, NULL}, +/* 499 */ {NULL, NULL, NULL}, +/* 500 */ {NULL, NULL, NULL}, +/* 501 */ {"ERR_UMODEUNKNOWNFLAG", ":%s 501 %s :Unknown MODE flag", NULL}, +/* 502 */ {"ERR_USERSDONTMATCH", ":%s 502 %s :Can't change mode for other users", NULL}, +/* 503 */ {"ERR_GHOSTEDCLIENT", ":%s 503 %s :Message could not be delivered to %s", NULL}, +/* 504 */ {"ERR_USERNOTONSERV", ":%s 504 %s %s :User is not on this server", NULL}, +/* 505 */ {NULL, NULL, NULL}, +/* 506 */ {NULL, NULL, NULL}, +/* 507 */ {NULL, NULL, NULL}, +/* 508 */ {NULL, NULL, NULL}, +/* 509 */ {NULL, NULL, NULL}, +/* 510 */ {NULL, NULL, NULL}, +/* 511 */ {NULL, NULL, NULL}, +/* 512 */ {"ERR_TOOMANYWATCH", ":%s 512 %s %s :Maximum size for WATCH-list is %d entries", NULL}, +/* 513 */ {"ERR_WRONGPONG", ":%s 513 %s :To connect type /QUOTE PONG %lu", NULL}, +/* 514 */ {NULL, NULL, NULL}, +/* 515 */ {NULL, NULL, NULL}, +/* 516 */ {NULL, NULL, NULL}, +/* 517 */ {NULL, NULL, NULL}, +/* 518 */ {NULL, NULL, NULL}, +/* 519 */ {NULL, NULL, NULL}, +/* 520 */ {NULL, NULL, NULL}, +/* 521 */ {"ERR_LISTSYNTAX", ":%s 521 %s :Bad list syntax, type /QUOTE HELP LIST", NULL}, +/* 522 */ {NULL, NULL, NULL}, +/* 523 */ {NULL, NULL, NULL}, +/* 524 */ {"ERR_HELPNOTFOUND", ":%s 524 %s %s :Help not found", NULL}, +/* 525 */ {NULL, NULL, NULL}, +/* 526 */ {NULL, NULL, NULL}, +/* 527 */ {NULL, NULL, NULL}, +/* 528 */ {NULL, NULL, NULL}, +/* 529 */ {NULL, NULL, NULL}, +/* 530 */ {NULL, NULL, NULL}, +/* 531 */ {NULL, NULL, NULL}, +/* 532 */ {NULL, NULL, NULL}, +/* 533 */ {NULL, NULL, NULL}, +/* 534 */ {NULL, NULL, NULL}, +/* 535 */ {NULL, NULL, NULL}, +/* 536 */ {NULL, NULL, NULL}, +/* 537 */ {NULL, NULL, NULL}, +/* 538 */ {NULL, NULL, NULL}, +/* 539 */ {NULL, NULL, NULL}, +/* 540 */ {NULL, NULL, NULL}, +/* 541 */ {NULL, NULL, NULL}, +/* 542 */ {NULL, NULL, NULL}, +/* 543 */ {NULL, NULL, NULL}, +/* 544 */ {NULL, NULL, NULL}, +/* 545 */ {NULL, NULL, NULL}, +/* 546 */ {NULL, NULL, NULL}, +/* 547 */ {NULL, NULL, NULL}, +/* 548 */ {NULL, NULL, NULL}, +/* 549 */ {NULL, NULL, NULL}, +/* 550 */ {NULL, NULL, NULL}, +/* 551 */ {NULL, NULL, NULL}, +/* 552 */ {NULL, NULL, NULL}, +/* 553 */ {NULL, NULL, NULL}, +/* 554 */ {NULL, NULL, NULL}, +/* 555 */ {NULL, NULL, NULL}, +/* 556 */ {NULL, NULL, NULL}, +/* 557 */ {NULL, NULL, NULL}, +/* 558 */ {NULL, NULL, NULL}, +/* 559 */ {NULL, NULL, NULL}, +/* 560 */ {NULL, NULL, NULL}, +/* 561 */ {NULL, NULL, NULL}, +/* 562 */ {NULL, NULL, NULL}, +/* 563 */ {NULL, NULL, NULL}, +/* 564 */ {NULL, NULL, NULL}, +/* 565 */ {NULL, NULL, NULL}, +/* 566 */ {NULL, NULL, NULL}, +/* 567 */ {NULL, NULL, NULL}, +/* 568 */ {NULL, NULL, NULL}, +/* 569 */ {NULL, NULL, NULL}, +/* 570 */ {NULL, NULL, NULL}, +/* 571 */ {NULL, NULL, NULL}, +/* 572 */ {NULL, NULL, NULL}, +/* 573 */ {NULL, NULL, NULL}, +/* 574 */ {NULL, NULL, NULL}, +/* 575 */ {NULL, NULL, NULL}, +/* 576 */ {NULL, NULL, NULL}, +/* 577 */ {NULL, NULL, NULL}, +/* 578 */ {NULL, NULL, NULL}, +/* 579 */ {NULL, NULL, NULL}, +/* 580 */ {NULL, NULL, NULL}, +/* 581 */ {NULL, NULL, NULL}, +/* 582 */ {NULL, NULL, NULL}, +/* 583 */ {NULL, NULL, NULL}, +/* 584 */ {NULL, NULL, NULL}, +/* 585 */ {NULL, NULL, NULL}, +/* 586 */ {NULL, NULL, NULL}, +/* 587 */ {NULL, NULL, NULL}, +/* 588 */ {NULL, NULL, NULL}, +/* 589 */ {NULL, NULL, NULL}, +/* 590 */ {NULL, NULL, NULL}, +/* 591 */ {NULL, NULL, NULL}, +/* 592 */ {NULL, NULL, NULL}, +/* 593 */ {NULL, NULL, NULL}, +/* 594 */ {NULL, NULL, NULL}, +/* 595 */ {NULL, NULL, NULL}, +/* 596 */ {NULL, NULL, NULL}, +/* 597 */ {NULL, NULL, NULL}, +/* 598 */ {NULL, NULL, NULL}, +/* 599 */ {NULL, NULL, NULL}, +/* 600 */ {"RPL_LOGON", ":%s 600 %s %s %s %s %d :logged online", NULL}, +/* 601 */ {"RPL_LOGOFF", ":%s 601 %s %s %s %s %d :logged offline", NULL}, +/* 602 */ {"RPL_WATCHOFF", ":%s 602 %s %s %s %s %d :stopped watching", NULL}, +/* 603 */ {"RPL_WATCHSTAT", ":%s 603 %s :You have %u and are on %u WATCH entries", NULL}, +/* 604 */ {"RPL_NOWON", ":%s 604 %s %s %s %s %d :is online", NULL}, +/* 605 */ {"RPL_NOWOFF", ":%s 605 %s %s %s %s %d :is offline", NULL}, +/* 606 */ {"RPL_WATCHLIST", ":%s 606 %s :%s", NULL}, +/* 607 */ {"RPL_ENDOFWATCHLIST", ":%s 607 %s :End of WATCH %c", NULL}, +/* 608 */ {NULL, NULL, NULL}, +/* 609 */ {NULL, NULL, NULL}, +/* 610 */ {NULL, NULL, NULL}, +/* 611 */ {NULL, NULL, NULL}, +/* 612 */ {NULL, NULL, NULL}, +/* 613 */ {NULL, NULL, NULL}, +/* 614 */ {NULL, NULL, NULL}, +/* 615 */ {NULL, NULL, NULL}, +/* 616 */ {NULL, NULL, NULL}, +/* 617 */ {NULL, NULL, NULL}, +/* 618 */ {NULL, NULL, NULL}, +/* 619 */ {NULL, NULL, NULL}, +/* 620 */ {NULL, NULL, NULL}, +/* 621 */ {NULL, NULL, NULL}, +/* 622 */ {NULL, NULL, NULL}, +/* 623 */ {NULL, NULL, NULL}, +/* 624 */ {NULL, NULL, NULL}, +/* 625 */ {NULL, NULL, NULL}, +/* 626 */ {NULL, NULL, NULL}, +/* 627 */ {NULL, NULL, NULL}, +/* 628 */ {NULL, NULL, NULL}, +/* 629 */ {NULL, NULL, NULL}, +/* 630 */ {NULL, NULL, NULL}, +/* 631 */ {NULL, NULL, NULL}, +/* 632 */ {NULL, NULL, NULL}, +/* 633 */ {NULL, NULL, NULL}, +/* 634 */ {NULL, NULL, NULL}, +/* 635 */ {NULL, NULL, NULL}, +/* 636 */ {NULL, NULL, NULL}, +/* 637 */ {NULL, NULL, NULL}, +/* 638 */ {NULL, NULL, NULL}, +/* 639 */ {NULL, NULL, NULL}, +/* 640 */ {NULL, NULL, NULL}, +/* 641 */ {NULL, NULL, NULL}, +/* 642 */ {NULL, NULL, NULL}, +/* 643 */ {NULL, NULL, NULL}, +/* 644 */ {NULL, NULL, NULL}, +/* 645 */ {NULL, NULL, NULL}, +/* 646 */ {NULL, NULL, NULL}, +/* 647 */ {NULL, NULL, NULL}, +/* 648 */ {NULL, NULL, NULL}, +/* 649 */ {NULL, NULL, NULL}, +/* 650 */ {NULL, NULL, NULL}, +/* 651 */ {NULL, NULL, NULL}, +/* 652 */ {NULL, NULL, NULL}, +/* 653 */ {NULL, NULL, NULL}, +/* 654 */ {NULL, NULL, NULL}, +/* 655 */ {NULL, NULL, NULL}, +/* 656 */ {NULL, NULL, NULL}, +/* 657 */ {NULL, NULL, NULL}, +/* 658 */ {NULL, NULL, NULL}, +/* 659 */ {NULL, NULL, NULL}, +/* 660 */ {NULL, NULL, NULL}, +/* 661 */ {NULL, NULL, NULL}, +/* 662 */ {NULL, NULL, NULL}, +/* 663 */ {NULL, NULL, NULL}, +/* 664 */ {NULL, NULL, NULL}, +/* 665 */ {NULL, NULL, NULL}, +/* 666 */ {NULL, NULL, NULL}, +/* 667 */ {NULL, NULL, NULL}, +/* 668 */ {NULL, NULL, NULL}, +/* 669 */ {NULL, NULL, NULL}, +/* 670 */ {NULL, NULL, NULL}, +/* 671 */ {"RPL_WHOISSECURE", ":%s 671 %s %s :is connected via SSL (secure link)", NULL}, +/* 672 */ {NULL, NULL, NULL}, +/* 673 */ {NULL, NULL, NULL}, +/* 674 */ {NULL, NULL, NULL}, +/* 675 */ {NULL, NULL, NULL}, +/* 676 */ {NULL, NULL, NULL}, +/* 677 */ {NULL, NULL, NULL}, +/* 678 */ {NULL, NULL, NULL}, +/* 679 */ {NULL, NULL, NULL}, +/* 680 */ {NULL, NULL, NULL}, +/* 681 */ {NULL, NULL, NULL}, +/* 682 */ {NULL, NULL, NULL}, +/* 683 */ {NULL, NULL, NULL}, +/* 684 */ {NULL, NULL, NULL}, +/* 685 */ {NULL, NULL, NULL}, +/* 686 */ {NULL, NULL, NULL}, +/* 687 */ {NULL, NULL, NULL}, +/* 688 */ {NULL, NULL, NULL}, +/* 689 */ {NULL, NULL, NULL}, +/* 690 */ {NULL, NULL, NULL}, +/* 691 */ {NULL, NULL, NULL}, +/* 692 */ {NULL, NULL, NULL}, +/* 693 */ {NULL, NULL, NULL}, +/* 694 */ {NULL, NULL, NULL}, +/* 695 */ {NULL, NULL, NULL}, +/* 696 */ {NULL, NULL, NULL}, +/* 697 */ {NULL, NULL, NULL}, +/* 698 */ {NULL, NULL, NULL}, +/* 699 */ {NULL, NULL, NULL}, +/* 700 */ {NULL, NULL, NULL}, +/* 701 */ {NULL, NULL, NULL}, +/* 702 */ {"RPL_MODLIST", ":%s 702 %s %s %p %s %s", NULL}, +/* 703 */ {"RPL_ENDOFMODLIST", ":%s 703 %s :End of /MODLIST.", NULL}, +/* 704 */ {"RPL_HELPSTART", ":%s 704 %s %s :%s", NULL}, +/* 705 */ {"RPL_HELPTXT", ":%s 705 %s %s :%s", NULL}, +/* 706 */ {"RPL_ENDOFHELP", ":%s 706 %s %s :End of /HELP.", NULL}, +/* 707 */ {NULL, NULL, NULL}, +/* 708 */ {"RPL_ETRACE_FULL", ":%s 708 %s %s %s %s %s %s %s %s %s :%s", NULL}, +/* 709 */ {"RPL_ETRACE", ":%s 709 %s %s %s %s %s %s %s :%s", NULL}, +/* 710 */ {"RPL_KNOCK", ":%s 710 %s %s %s!%s@%s :has asked for an invite.", NULL}, +/* 711 */ {"RPL_KNOCKDLVR", ":%s 711 %s %s :Your KNOCK has been delivered.", NULL}, +/* 712 */ {"ERR_TOOMANYKNOCK", ":%s 712 %s %s :Too many KNOCKs (%s).", NULL}, +/* 713 */ {"ERR_CHANOPEN", ":%s 713 %s %s :Channel is open.", NULL}, +/* 714 */ {"ERR_KNOCKONCHAN", ":%s 714 %s %s :You are already on that channel.", NULL}, +/* 715 */ {NULL, NULL, NULL}, +/* 716 */ {"RPL_TARGUMODEG", ":%s 716 %s %s :is in +g mode (server side ignore)", NULL}, +/* 717 */ {"RPL_TARGNOTIFY", ":%s 717 %s %s :has been informed that you messaged them.", NULL}, +/* 718 */ {"RPL_UMODEGMSG", ":%s 718 %s %s :is messaging you, and you are umode +g.", NULL}, +/* 719 */ {NULL, NULL, NULL}, +/* 720 */ {NULL, NULL, NULL}, +/* 721 */ {NULL, NULL, NULL}, +/* 722 */ {NULL, NULL, NULL}, +/* 723 */ {"ERR_NOPRIVS", ":%s 723 %s %s :Insufficient oper privs.", NULL }, +/* 724 */ {"RPL_TESTMASK", ":%s 724 %s %s!%s@%s %u %u :Local/remote clients match.", NULL }, +/* 725 */ {"RPL_TESTLINE", ":%s 725 %s %c %ld %s :%s | %s", NULL }, +/* 726 */ {"RPL_NOTESTLINE", ":%s 726 %s %s :No matches", NULL }, +/* 727 */ {NULL, NULL, NULL}, +/* 728 */ {NULL, NULL, NULL}, +/* 729 */ {NULL, NULL, NULL}, +/* 730 */ {NULL, NULL, NULL}, +/* 731 */ {NULL, NULL, NULL}, +/* 732 */ {NULL, NULL, NULL}, +/* 733 */ {NULL, NULL, NULL}, +/* 734 */ {NULL, NULL, NULL}, +/* 735 */ {NULL, NULL, NULL}, +/* 736 */ {NULL, NULL, NULL}, +/* 737 */ {NULL, NULL, NULL}, +/* 738 */ {NULL, NULL, NULL}, +/* 739 */ {NULL, NULL, NULL}, +/* 740 */ {NULL, NULL, NULL}, +/* 741 */ {NULL, NULL, NULL}, +/* 742 */ {NULL, NULL, NULL}, +/* 743 */ {NULL, NULL, NULL}, +/* 744 */ {NULL, NULL, NULL}, +/* 745 */ {NULL, NULL, NULL}, +/* 746 */ {NULL, NULL, NULL}, +/* 747 */ {NULL, NULL, NULL}, +/* 748 */ {NULL, NULL, NULL}, +/* 749 */ {NULL, NULL, NULL}, +/* 750 */ {NULL, NULL, NULL}, +/* 751 */ {NULL, NULL, NULL}, +/* 752 */ {NULL, NULL, NULL}, +/* 753 */ {NULL, NULL, NULL}, +/* 754 */ {NULL, NULL, NULL}, +/* 755 */ {NULL, NULL, NULL}, +/* 756 */ {NULL, NULL, NULL}, +/* 757 */ {NULL, NULL, NULL}, +/* 758 */ {NULL, NULL, NULL}, +/* 759 */ {NULL, NULL, NULL}, +/* 760 */ {NULL, NULL, NULL}, +/* 761 */ {NULL, NULL, NULL}, +/* 762 */ {NULL, NULL, NULL}, +/* 763 */ {NULL, NULL, NULL}, +/* 764 */ {NULL, NULL, NULL}, +/* 765 */ {NULL, NULL, NULL}, +/* 766 */ {NULL, NULL, NULL}, +/* 767 */ {NULL, NULL, NULL}, +/* 768 */ {NULL, NULL, NULL}, +/* 769 */ {NULL, NULL, NULL}, +/* 770 */ {NULL, NULL, NULL}, +/* 771 */ {NULL, NULL, NULL}, +/* 772 */ {NULL, NULL, NULL}, +/* 773 */ {NULL, NULL, NULL}, +/* 774 */ {NULL, NULL, NULL}, +/* 775 */ {NULL, NULL, NULL}, +/* 776 */ {NULL, NULL, NULL}, +/* 777 */ {NULL, NULL, NULL}, +/* 778 */ {NULL, NULL, NULL}, +/* 779 */ {NULL, NULL, NULL}, +/* 780 */ {NULL, NULL, NULL}, +/* 781 */ {NULL, NULL, NULL}, +/* 782 */ {NULL, NULL, NULL}, +/* 783 */ {NULL, NULL, NULL}, +/* 784 */ {NULL, NULL, NULL}, +/* 785 */ {NULL, NULL, NULL}, +/* 786 */ {NULL, NULL, NULL}, +/* 787 */ {NULL, NULL, NULL}, +/* 788 */ {NULL, NULL, NULL}, +/* 789 */ {NULL, NULL, NULL}, +/* 790 */ {NULL, NULL, NULL}, +/* 791 */ {NULL, NULL, NULL}, +/* 792 */ {NULL, NULL, NULL}, +/* 793 */ {NULL, NULL, NULL}, +/* 794 */ {NULL, NULL, NULL}, +/* 795 */ {NULL, NULL, NULL}, +/* 796 */ {NULL, NULL, NULL}, +/* 797 */ {NULL, NULL, NULL}, +/* 798 */ {NULL, NULL, NULL}, +/* 799 */ {NULL, NULL, NULL}, +/* 800 */ {NULL, NULL, NULL}, +/* 801 */ {NULL, NULL, NULL}, +/* 802 */ {NULL, NULL, NULL}, +/* 803 */ {NULL, NULL, NULL}, +/* 804 */ {NULL, NULL, NULL}, +/* 805 */ {NULL, NULL, NULL}, +/* 806 */ {NULL, NULL, NULL}, +/* 807 */ {NULL, NULL, NULL}, +/* 808 */ {NULL, NULL, NULL}, +/* 809 */ {NULL, NULL, NULL}, +/* 810 */ {NULL, NULL, NULL}, +/* 811 */ {NULL, NULL, NULL}, +/* 812 */ {NULL, NULL, NULL}, +/* 813 */ {NULL, NULL, NULL}, +/* 814 */ {NULL, NULL, NULL}, +/* 815 */ {NULL, NULL, NULL}, +/* 816 */ {NULL, NULL, NULL}, +/* 817 */ {NULL, NULL, NULL}, +/* 818 */ {NULL, NULL, NULL}, +/* 819 */ {NULL, NULL, NULL}, +/* 820 */ {NULL, NULL, NULL}, +/* 821 */ {NULL, NULL, NULL}, +/* 822 */ {NULL, NULL, NULL}, +/* 823 */ {NULL, NULL, NULL}, +/* 824 */ {NULL, NULL, NULL}, +/* 825 */ {NULL, NULL, NULL}, +/* 826 */ {NULL, NULL, NULL}, +/* 827 */ {NULL, NULL, NULL}, +/* 828 */ {NULL, NULL, NULL}, +/* 829 */ {NULL, NULL, NULL}, +/* 830 */ {NULL, NULL, NULL}, +/* 831 */ {NULL, NULL, NULL}, +/* 832 */ {NULL, NULL, NULL}, +/* 833 */ {NULL, NULL, NULL}, +/* 834 */ {NULL, NULL, NULL}, +/* 835 */ {NULL, NULL, NULL}, +/* 836 */ {NULL, NULL, NULL}, +/* 837 */ {NULL, NULL, NULL}, +/* 838 */ {NULL, NULL, NULL}, +/* 839 */ {NULL, NULL, NULL}, +/* 840 */ {NULL, NULL, NULL}, +/* 841 */ {NULL, NULL, NULL}, +/* 842 */ {NULL, NULL, NULL}, +/* 843 */ {NULL, NULL, NULL}, +/* 844 */ {NULL, NULL, NULL}, +/* 845 */ {NULL, NULL, NULL}, +/* 846 */ {NULL, NULL, NULL}, +/* 847 */ {NULL, NULL, NULL}, +/* 848 */ {NULL, NULL, NULL}, +/* 849 */ {NULL, NULL, NULL}, +/* 850 */ {NULL, NULL, NULL}, +/* 851 */ {NULL, NULL, NULL}, +/* 852 */ {NULL, NULL, NULL}, +/* 853 */ {NULL, NULL, NULL}, +/* 854 */ {NULL, NULL, NULL}, +/* 855 */ {NULL, NULL, NULL}, +/* 856 */ {NULL, NULL, NULL}, +/* 857 */ {NULL, NULL, NULL}, +/* 858 */ {NULL, NULL, NULL}, +/* 859 */ {NULL, NULL, NULL}, +/* 860 */ {NULL, NULL, NULL}, +/* 861 */ {NULL, NULL, NULL}, +/* 862 */ {NULL, NULL, NULL}, +/* 863 */ {NULL, NULL, NULL}, +/* 864 */ {NULL, NULL, NULL}, +/* 865 */ {NULL, NULL, NULL}, +/* 866 */ {NULL, NULL, NULL}, +/* 867 */ {NULL, NULL, NULL}, +/* 868 */ {NULL, NULL, NULL}, +/* 869 */ {NULL, NULL, NULL}, +/* 870 */ {NULL, NULL, NULL}, +/* 871 */ {NULL, NULL, NULL}, +/* 872 */ {NULL, NULL, NULL}, +/* 873 */ {NULL, NULL, NULL}, +/* 874 */ {NULL, NULL, NULL}, +/* 875 */ {NULL, NULL, NULL}, +/* 876 */ {NULL, NULL, NULL}, +/* 877 */ {NULL, NULL, NULL}, +/* 878 */ {NULL, NULL, NULL}, +/* 879 */ {NULL, NULL, NULL}, +/* 880 */ {NULL, NULL, NULL}, +/* 881 */ {NULL, NULL, NULL}, +/* 882 */ {NULL, NULL, NULL}, +/* 883 */ {NULL, NULL, NULL}, +/* 884 */ {NULL, NULL, NULL}, +/* 885 */ {NULL, NULL, NULL}, +/* 886 */ {NULL, NULL, NULL}, +/* 887 */ {NULL, NULL, NULL}, +/* 888 */ {NULL, NULL, NULL}, +/* 889 */ {NULL, NULL, NULL}, +/* 890 */ {NULL, NULL, NULL}, +/* 891 */ {NULL, NULL, NULL}, +/* 892 */ {NULL, NULL, NULL}, +/* 893 */ {NULL, NULL, NULL}, +/* 894 */ {NULL, NULL, NULL}, +/* 895 */ {NULL, NULL, NULL}, +/* 896 */ {NULL, NULL, NULL}, +/* 897 */ {NULL, NULL, NULL}, +/* 898 */ {NULL, NULL, NULL}, +/* 899 */ {NULL, NULL, NULL}, +/* 900 */ {NULL, NULL, NULL}, +/* 901 */ {NULL, NULL, NULL}, +/* 902 */ {NULL, NULL, NULL}, +/* 903 */ {NULL, NULL, NULL}, +/* 904 */ {NULL, NULL, NULL}, +/* 905 */ {NULL, NULL, NULL}, +/* 906 */ {NULL, NULL, NULL}, +/* 907 */ {NULL, NULL, NULL}, +/* 908 */ {NULL, NULL, NULL}, +/* 909 */ {NULL, NULL, NULL}, +/* 910 */ {NULL, NULL, NULL}, +/* 911 */ {NULL, NULL, NULL}, +/* 912 */ {NULL, NULL, NULL}, +/* 913 */ {NULL, NULL, NULL}, +/* 914 */ {NULL, NULL, NULL}, +/* 915 */ {NULL, NULL, NULL}, +/* 916 */ {NULL, NULL, NULL}, +/* 917 */ {NULL, NULL, NULL}, +/* 918 */ {NULL, NULL, NULL}, +/* 919 */ {NULL, NULL, NULL}, +/* 920 */ {NULL, NULL, NULL}, +/* 921 */ {NULL, NULL, NULL}, +/* 922 */ {NULL, NULL, NULL}, +/* 923 */ {NULL, NULL, NULL}, +/* 924 */ {NULL, NULL, NULL}, +/* 925 */ {NULL, NULL, NULL}, +/* 926 */ {NULL, NULL, NULL}, +/* 927 */ {NULL, NULL, NULL}, +/* 928 */ {NULL, NULL, NULL}, +/* 929 */ {NULL, NULL, NULL}, +/* 930 */ {NULL, NULL, NULL}, +/* 931 */ {NULL, NULL, NULL}, +/* 932 */ {NULL, NULL, NULL}, +/* 933 */ {NULL, NULL, NULL}, +/* 934 */ {NULL, NULL, NULL}, +/* 935 */ {NULL, NULL, NULL}, +/* 936 */ {NULL, NULL, NULL}, +/* 937 */ {NULL, NULL, NULL}, +/* 938 */ {NULL, NULL, NULL}, +/* 939 */ {NULL, NULL, NULL}, +/* 940 */ {NULL, NULL, NULL}, +/* 941 */ {NULL, NULL, NULL}, +/* 942 */ {NULL, NULL, NULL}, +/* 943 */ {NULL, NULL, NULL}, +/* 944 */ {NULL, NULL, NULL}, +/* 945 */ {NULL, NULL, NULL}, +/* 946 */ {NULL, NULL, NULL}, +/* 947 */ {NULL, NULL, NULL}, +/* 948 */ {NULL, NULL, NULL}, +/* 949 */ {NULL, NULL, NULL}, +/* 950 */ {NULL, NULL, NULL}, +/* 951 */ {NULL, NULL, NULL}, +/* 952 */ {NULL, NULL, NULL}, +/* 953 */ {NULL, NULL, NULL}, +/* 954 */ {NULL, NULL, NULL}, +/* 955 */ {NULL, NULL, NULL}, +/* 956 */ {NULL, NULL, NULL}, +/* 957 */ {NULL, NULL, NULL}, +/* 958 */ {NULL, NULL, NULL}, +/* 959 */ {NULL, NULL, NULL}, +/* 960 */ {NULL, NULL, NULL}, +/* 961 */ {NULL, NULL, NULL}, +/* 962 */ {NULL, NULL, NULL}, +/* 963 */ {NULL, NULL, NULL}, +/* 964 */ {NULL, NULL, NULL}, +/* 965 */ {NULL, NULL, NULL}, +/* 966 */ {NULL, NULL, NULL}, +/* 967 */ {NULL, NULL, NULL}, +/* 968 */ {NULL, NULL, NULL}, +/* 969 */ {NULL, NULL, NULL}, +/* 970 */ {NULL, NULL, NULL}, +/* 971 */ {NULL, NULL, NULL}, +/* 972 */ {NULL, NULL, NULL}, +/* 973 */ {NULL, NULL, NULL}, +/* 974 */ {NULL, NULL, NULL}, +/* 975 */ {NULL, NULL, NULL}, +/* 976 */ {NULL, NULL, NULL}, +/* 977 */ {NULL, NULL, NULL}, +/* 978 */ {NULL, NULL, NULL}, +/* 979 */ {NULL, NULL, NULL}, +/* 980 */ {NULL, NULL, NULL}, +/* 981 */ {NULL, NULL, NULL}, +/* 982 */ {NULL, NULL, NULL}, +/* 983 */ {NULL, NULL, NULL}, +/* 984 */ {NULL, NULL, NULL}, +/* 985 */ {NULL, NULL, NULL}, +/* 986 */ {NULL, NULL, NULL}, +/* 987 */ {NULL, NULL, NULL}, +/* 988 */ {NULL, NULL, NULL}, +/* 989 */ {NULL, NULL, NULL}, +/* 990 */ {NULL, NULL, NULL}, +/* 991 */ {NULL, NULL, NULL}, +/* 992 */ {NULL, NULL, NULL}, +/* 993 */ {NULL, NULL, NULL}, +/* 994 */ {NULL, NULL, NULL}, +/* 995 */ {NULL, NULL, NULL}, +/* 996 */ {NULL, NULL, NULL}, +/* 997 */ {NULL, NULL, NULL}, +/* 998 */ {NULL, NULL, NULL}, +/* 999 */ {NULL, NULL, NULL} +}; diff --git a/src/modules.c b/src/modules.c new file mode 100644 index 0000000..8a5ab1b --- /dev/null +++ b/src/modules.c @@ -0,0 +1,401 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * modules.c: A module loader. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "ltdl.h" + +#include "stdinc.h" +#include "list.h" +#include "modules.h" +#include "log.h" +#include "ircd.h" +#include "client.h" +#include "send.h" +#include "conf.h" +#include "numeric.h" +#include "parse.h" +#include "ircd_defs.h" +#include "irc_string.h" +#include "memory.h" + + +dlink_list modules_list = { NULL, NULL, 0 }; + +static const char *unknown_ver = "<unknown>"; + +static const char *core_module_table[] = +{ + "m_die.la", + "m_error.la", + "m_join.la", + "m_kick.la", + "m_kill.la", + "m_message.la", + "m_mode.la", + "m_nick.la", + "m_part.la", + "m_quit.la", + "m_server.la", + "m_sjoin.la", + "m_squit.la", + NULL +}; + +static dlink_list mod_paths = { NULL, NULL, 0 }; +static dlink_list conf_modules = { NULL, NULL, 0 }; + +int +modules_valid_suffix(const char *name) +{ + return ((name = strrchr(name, '.'))) && !strcmp(name, ".la"); +} + +/* unload_one_module() + * + * inputs - name of module to unload + * - 1 to say modules unloaded, 0 to not + * output - 0 if successful, -1 if error + * side effects - module is unloaded + */ +int +unload_one_module(const char *name, int warn) +{ + struct module *modp = NULL; + + if ((modp = findmodule_byname(name)) == NULL) + return -1; + + if (modp->modexit) + modp->modexit(); + + assert(dlink_list_length(&modules_list) > 0); + dlinkDelete(&modp->node, &modules_list); + MyFree(modp->name); + + lt_dlclose(modp->handle); + + if (warn == 1) + { + ilog(LOG_TYPE_IRCD, "Module %s unloaded", name); + sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s unloaded", name); + } + + return 0; +} + +/* load_a_module() + * + * inputs - path name of module, int to notice, int of core + * output - -1 if error 0 if success + * side effects - loads a module if successful + */ +int +load_a_module(const char *path, int warn) +{ + lt_dlhandle tmpptr = NULL; + const char *mod_basename = NULL; + struct module *modp = NULL; + + if (findmodule_byname((mod_basename = libio_basename(path)))) + return 1; + + if (!(tmpptr = lt_dlopen(path))) { + const char *err = ((err = lt_dlerror())) ? err : "<unknown>"; + + sendto_realops_flags(UMODE_ALL, L_ALL, "Error loading module %s: %s", + mod_basename, err); + ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err); + return -1; + } + + if ((modp = lt_dlsym(tmpptr, "module_entry")) == NULL) + { + const char *err = ((err = lt_dlerror())) ? err : "<unknown>"; + + sendto_realops_flags(UMODE_ALL, L_ALL, "Error loading module %s: %s", + mod_basename, err); + ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err); + lt_dlclose(tmpptr); + return -1; + } + + modp->handle = tmpptr; + + if (EmptyString(modp->version)) + modp->version = unknown_ver; + + DupString(modp->name, mod_basename); + dlinkAdd(modp, &modp->node, &modules_list); + + if (modp->modinit) + modp->modinit(); + + if (warn == 1) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "Module %s [version: %s handle: %p] loaded.", + modp->name, modp->version, tmpptr); + ilog(LOG_TYPE_IRCD, "Module %s [version: %s handle: %p] loaded.", + modp->name, modp->version, tmpptr); + } + + return 0; +} + +/* + * modules_init + * + * input - NONE + * output - NONE + * side effects - The basic module manipulation modules are loaded + */ +void +modules_init(void) +{ + if (lt_dlinit()) + { + ilog(LOG_TYPE_IRCD, "Couldn't initialize the libltdl run time dynamic" + " link library. Exiting."); + exit(0); + } +} + +/* mod_find_path() + * + * input - path + * output - none + * side effects - returns a module path from path + */ +static struct module_path * +mod_find_path(const char *path) +{ + dlink_node *ptr; + + DLINK_FOREACH(ptr, mod_paths.head) + { + struct module_path *mpath = ptr->data; + + if (!strcmp(path, mpath->path)) + return mpath; + } + + return NULL; +} + +/* mod_add_path() + * + * input - path + * output - NONE + * side effects - adds path to list + */ +void +mod_add_path(const char *path) +{ + struct module_path *pathst; + + if (mod_find_path(path)) + return; + + pathst = MyMalloc(sizeof(struct module_path)); + + strlcpy(pathst->path, path, sizeof(pathst->path)); + dlinkAdd(pathst, &pathst->node, &mod_paths); +} + +/* add_conf_module + * + * input - module name + * output - NONE + * side effects - adds module to conf_mod + */ +void +add_conf_module(const char *name) +{ + struct module_path *pathst; + + pathst = MyMalloc(sizeof(struct module_path)); + + strlcpy(pathst->path, name, sizeof(pathst->path)); + dlinkAdd(pathst, &pathst->node, &conf_modules); +} + +/* mod_clear_paths() + * + * input - NONE + * output - NONE + * side effects - clear the lists of paths and conf modules + */ +void +mod_clear_paths(void) +{ + dlink_node *ptr = NULL, *next_ptr = NULL; + + DLINK_FOREACH_SAFE(ptr, next_ptr, mod_paths.head) + { + dlinkDelete(ptr, &mod_paths); + MyFree(ptr->data); + } + + DLINK_FOREACH_SAFE(ptr, next_ptr, conf_modules.head) + { + dlinkDelete(ptr, &conf_modules); + MyFree(ptr->data); + } +} + +/* findmodule_byname + * + * input - name of module + * output - NULL if not found or pointer to module + * side effects - NONE + */ +struct module * +findmodule_byname(const char *name) +{ + dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, modules_list.head) + { + struct module *modp = ptr->data; + + if (strcmp(modp->name, name) == 0) + return modp; + } + + return NULL; +} + +/* load_all_modules() + * + * input - int flag warn + * output - NONE + * side effects - load all modules found in autoload directory + */ +void +load_all_modules(int warn) +{ + DIR *system_module_dir = NULL; + struct dirent *ldirent = NULL; + char module_fq_name[PATH_MAX + 1]; + + if ((system_module_dir = opendir(AUTOMODPATH)) == NULL) + { + ilog(LOG_TYPE_IRCD, "Could not load modules from %s: %s", + AUTOMODPATH, strerror(errno)); + return; + } + + while ((ldirent = readdir(system_module_dir)) != NULL) + { + if (modules_valid_suffix(ldirent->d_name)) + { + snprintf(module_fq_name, sizeof(module_fq_name), "%s/%s", + AUTOMODPATH, ldirent->d_name); + load_a_module(module_fq_name, warn); + } + } + + closedir(system_module_dir); +} + +/* load_conf_modules() + * + * input - NONE + * output - NONE + * side effects - load modules given in ircd.conf + */ +void +load_conf_modules(void) +{ + dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, conf_modules.head) + { + struct module_path *mpath = ptr->data; + + if (findmodule_byname(mpath->path) == NULL) + load_one_module(mpath->path); + } +} + +/* load_core_modules() + * + * input - int flag warn + * output - NONE + * side effects - core modules are loaded, if any fail, kill ircd + */ +void +load_core_modules(int warn) +{ + char module_name[PATH_MAX + 1]; + int i = 0; + + for (; core_module_table[i]; ++i) + { + snprintf(module_name, sizeof(module_name), "%s%s", + MODPATH, core_module_table[i]); + + if (load_a_module(module_name, warn) == -1) + { + ilog(LOG_TYPE_IRCD, "Error loading core module %s: terminating ircd", + core_module_table[i]); + exit(EXIT_FAILURE); + } + } +} + +/* load_one_module() + * + * input - pointer to path + * - flagged as core module or not + * output - -1 if error + * side effects - module is loaded if found. + */ +int +load_one_module(const char *path) +{ + dlink_node *ptr = NULL; + char modpath[PATH_MAX + 1]; + struct stat statbuf; + + DLINK_FOREACH(ptr, mod_paths.head) + { + const struct module_path *mpath = ptr->data; + + snprintf(modpath, sizeof(modpath), "%s/%s", mpath->path, path); + + if (!modules_valid_suffix(path)) + continue; + + if (strstr(modpath, "../") == NULL && + strstr(modpath, "/..") == NULL) + if (!stat(modpath, &statbuf)) + if (S_ISREG(statbuf.st_mode)) /* Regular files only please */ + return load_a_module(modpath, 1); + } + + sendto_realops_flags(UMODE_ALL, L_ALL, + "Cannot locate module %s", path); + ilog(LOG_TYPE_IRCD, "Cannot locate module %s", path); + return -1; +} diff --git a/src/motd.c b/src/motd.c new file mode 100644 index 0000000..a4c2612 --- /dev/null +++ b/src/motd.c @@ -0,0 +1,283 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * motd.c: Message of the day functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "motd.h" +#include "ircd.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "conf.h" +#include "send.h" +#include "numeric.h" +#include "client.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "memory.h" +#include "s_serv.h" + +/* +** init_message_file +** +*/ +void +init_message_file(MotdType motdType, const char *fileName, MessageFile *motd) +{ + strlcpy(motd->fileName, fileName, sizeof(motd->fileName)); + motd->motdType = motdType; + motd->contentsOfFile = NULL; + motd->lastChangedDate[0] = '\0'; +} + +/* +** send_message_file +** +** This function split off so a server notice could be generated on a +** user requested motd, but not on each connecting client. +*/ +int +send_message_file(struct Client *source_p, MessageFile *motdToPrint) +{ + MessageFileLine *linePointer; + MotdType motdType; + const char *from, *to; + + if (motdToPrint == NULL) + return(-1); + + motdType = motdToPrint->motdType; + + from = ID_or_name(&me, source_p->from); + to = ID_or_name(source_p, source_p->from); + + switch (motdType) + { + case USER_MOTD: + if (motdToPrint->contentsOfFile == NULL) + sendto_one(source_p, form_str(ERR_NOMOTD), from, to); + else + { + sendto_one(source_p, form_str(RPL_MOTDSTART), + from, to, me.name); + + for (linePointer = motdToPrint->contentsOfFile; linePointer; + linePointer = linePointer->next) + { + sendto_one(source_p, form_str(RPL_MOTD), + from, to, linePointer->line); + } + + sendto_one(source_p, form_str(RPL_ENDOFMOTD), from, to); + } + break; + + case USER_LINKS: + if (motdToPrint->contentsOfFile != NULL) + { + for (linePointer = motdToPrint->contentsOfFile; linePointer; + linePointer = linePointer->next) + { + sendto_one(source_p, ":%s 364 %s %s", /* XXX */ + from, to, linePointer->line); + } + } + break; + + case ISSUPPORT: + if (motdToPrint->contentsOfFile != NULL) + { + for (linePointer = motdToPrint->contentsOfFile; linePointer; + linePointer = linePointer->next) + { + sendto_one(source_p, form_str(RPL_ISUPPORT), + me.name, source_p->name, linePointer->line); + } + } + break; + + default: + break; + } + + return(0); +} + +/* + * read_message_file() - original From CoMSTuD, added Aug 29, 1996 + * + * inputs - pointer to MessageFileptr + * output - + * side effects - + */ +int +read_message_file(MessageFile *MessageFileptr) +{ + struct stat sb; + struct tm *local_tm; + + /* used to clear out old MessageFile entries */ + MessageFileLine *mptr = 0; + MessageFileLine *next_mptr = 0; + + /* used to add new MessageFile entries */ + MessageFileLine *newMessageLine = 0; + MessageFileLine *currentMessageLine = 0; + + char buffer[MESSAGELINELEN]; + char *p; + FILE *file; + + for (mptr = MessageFileptr->contentsOfFile; mptr; mptr = next_mptr) + { + next_mptr = mptr->next; + MyFree(mptr); + } + + MessageFileptr->contentsOfFile = NULL; + + if (stat(MessageFileptr->fileName, &sb) < 0) + return(-1); + + local_tm = localtime(&sb.st_mtime); + + if (local_tm) + ircsprintf(MessageFileptr->lastChangedDate, + "%d/%d/%d %d:%02d", + local_tm->tm_mday, + local_tm->tm_mon + 1, + 1900 + local_tm->tm_year, + local_tm->tm_hour, + local_tm->tm_min); + + if ((file = fopen(MessageFileptr->fileName, "r")) == NULL) + return(-1); + + while (fgets(buffer, sizeof(buffer), file)) + { + if ((p = strchr(buffer, '\n')) != NULL) + *p = '\0'; + + newMessageLine = (MessageFileLine *)MyMalloc(sizeof(MessageFileLine)); + strlcpy(newMessageLine->line, buffer, sizeof(newMessageLine->line)); + newMessageLine->next = NULL; + + if (MessageFileptr->contentsOfFile != NULL) + { + if (currentMessageLine) + currentMessageLine->next = newMessageLine; + + currentMessageLine = newMessageLine; + } + else + { + MessageFileptr->contentsOfFile = newMessageLine; + currentMessageLine = newMessageLine; + } + } + + fclose(file); + return(0); +} + +/* + * init_MessageLine + * + * inputs - NONE + * output - pointer to new MessageFile + * side effects - Use this when an internal Message File is wanted + * without reading an actual file. The MessageFile + * is init'ed, but must have content added to it through + * addto_MessageLine() + */ + +MessageFile * +init_MessageLine(void) +{ + MessageFile *mf; + MessageFileLine *mptr = NULL; + + mf = MyMalloc(sizeof(MessageFile)); + mf->motdType = ISSUPPORT; /* XXX maybe pass it alone in args? */ + mptr = MyMalloc(sizeof(MessageFileLine)); + mf->contentsOfFile = mptr; + return(mf); +} + +/* + * addto_MessageLine + * + * inputs - Pointer to existing MessageFile + * - New string to add to this MessageFile + * output - NONE + * side effects - Use this when an internal MessageFile is wanted + * without reading an actual file. Content is added + * to this MessageFile through this function. + */ + +void +addto_MessageLine(MessageFile *mf, const char *str) +{ + MessageFileLine *mptr = mf->contentsOfFile; + MessageFileLine *nmptr = NULL; + + if (mptr == NULL) + { + mptr = MyMalloc(sizeof(MessageFileLine)); + strcpy(mptr->line, str); + mf->contentsOfFile = mptr; + } + else + { + while (mptr->next != NULL) + mptr = mptr->next; + nmptr = MyMalloc(sizeof(MessageFileLine)); + strcpy(nmptr->line, str); + mptr->next = nmptr; + } +} + +/* + * destroy_MessageLine(MessageFile *mf) + * + * inputs - pointer to the MessageFile to destroy + * output - NONE + * side effects - All the MessageLines attached to the given mf + * Are freed then one MessageLine is recreated + */ +void +destroy_MessageLine(MessageFile *mf) +{ + MessageFileLine *mptr = mf->contentsOfFile; + MessageFileLine *nmptr = NULL; + + if (mptr == NULL) + return; + + for (mptr = mf->contentsOfFile; mptr != NULL; mptr = nmptr) + { + nmptr = mptr->next; + MyFree(mptr); + } + mf->contentsOfFile = NULL; +} diff --git a/src/numeric.c b/src/numeric.c new file mode 100644 index 0000000..2a1042d --- /dev/null +++ b/src/numeric.c @@ -0,0 +1,226 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * numeric.c: Numeric handling functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" + +#include "numeric.h" +#include "irc_string.h" +#include "memory.h" +#include "log.h" +#include "send.h" +#include "client.h" +#include "messages.tab" + +static char used_locale[LOCALE_LENGTH] = "standard"; + +/* + * form_str + * + * inputs - numeric + * output - corresponding string + * side effects - NONE + */ +const char* form_str(int numeric) +{ + assert(-1 < numeric); + assert(numeric < ERR_LAST_ERR_MSG); + + if (numeric > ERR_LAST_ERR_MSG) + numeric = ERR_LAST_ERR_MSG; + if (numeric < 0) + numeric = ERR_LAST_ERR_MSG; + + assert(replies[numeric].standard != NULL); + + return (replies[numeric].translated != NULL ? replies[numeric].translated : + replies[numeric].standard); +} + +/* Attempts to change a numeric with index "reply" to "new_reply". + * Returns 1 if ok, 0 otherwise. + */ +static int +change_reply(const char *locale, int linecnt, int reply, char *new_reply) +{ + int found; + char *new = new_reply; + const char *old = replies[reply].standard; + + for (; *new; new++) + { + if (*new == '%') + { + if (!*++new) break; + if (*new != '%') + { + /* We've just found a format symbol. Check if it is the next format + * symbol in the original reply. + */ + for (; *new >= '0' && *new <= '9'; new++); /* skip size prefix */ + found = 0; + for (; *old; old++) + { + if (*old == '%') + { + if (!*++old) break; /* shouldn't happen */ + if (*old != '%') + { + for (; *old >= '0' && *old <= '9'; old++); /* skip size prefix */ + if (*new != *old++) + { + ilog(LOG_TYPE_IRCD, "Incompatible format symbols (%s.lang, %d)", + locale, linecnt); + return 0; + } + found = 1; + break; + } + } + } + if (!found) + { + ilog(LOG_TYPE_IRCD, "Too many format symbols (%s.lang, %d)", locale, linecnt); + return(0); + } + } + } + } + + MyFree(replies[reply].translated); + DupString(replies[reply].translated, new_reply); + return(1); +} + +/* Loads a language file. Errors are logged into the log file. */ +void +set_locale(const char *locale) +{ + int i, res = 1, linecnt = 0; + char buffer[IRCD_BUFSIZE + 1]; + char *ident, *reply; + FILE *f; + + /* Restore standard replies */ + for (i = 0; i <= ERR_LAST_ERR_MSG; i++) /* 0 isn't a magic number! ;> */ + { + if (replies[i].translated != NULL) + { + MyFree(replies[i].translated); + replies[i].translated = NULL; + } + } + + if (strchr(locale, '/') != NULL) + { + strlcpy(used_locale, "standard", sizeof(used_locale)); /* XXX paranoid */ + return; + } + + /* yes, I know - the slash isn't necessary. But I have to be sure + * that it'll work even if some lame admin won't put "/" at the end + * of MSGPATH. + */ + snprintf(buffer, sizeof(buffer), "%s/%s.lang", MSGPATH, locale); + if ((f = fopen(buffer, "r")) == NULL) + { + strlcpy(used_locale, "standard", sizeof(used_locale)); /* XXX */ + return; + } + + /* Process the language file */ + while (fgets(buffer, sizeof(buffer), f)) + { + ++linecnt; + if (buffer[0] == ';') + continue; /* that's a comment */ + + if ((ident = strpbrk(buffer, "\r\n")) != NULL) + *ident = '\0'; + + /* skip spaces if there are any */ + for (ident = buffer; *ident == ' ' || *ident == '\t'; ident++)/* null */; + if (*ident == '\0') + continue; /* empty line */ + + /* skip after the reply identificator */ + for (reply = ident; *reply != ' ' && *reply != '\t' && *reply != ':'; + reply++) + if (*reply == '\0') goto error; + + if (*reply == ' ' || *reply == '\t') + { + for (*reply++ = '\0'; *reply == ' ' || *reply == '\t'; reply++); + if (*reply != ':') + { + error: + ilog(LOG_TYPE_IRCD, "Invalid line in language file (%s.lang, %d)", + locale, linecnt); + res = 0; + continue; + } + } + else + *reply++ = '\0'; + if (*ident == '\0') + goto error; + + /* skip to the beginning of reply */ + while (*reply == ' ' || *reply == '\t') reply++; + if (*reply == '\0') + goto error; + + for (i = 0; i <= ERR_LAST_ERR_MSG; i++) + { + if (replies[i].name != NULL) + { + if (irccmp(replies[i].name, ident) == 0) + { + if (!change_reply(locale, linecnt, i, reply)) res = 0; + i = -1; + break; + } + } + } + if (i != -1) + { + ilog(LOG_TYPE_IRCD, + "Unknown numeric %s (%s.lang, %d)", ident, locale, linecnt); + res = 0; + } + } + fclose(f); + + strlcpy(used_locale, locale, sizeof(used_locale)); + if (!res) + sendto_realops_flags(UMODE_ALL, L_ADMIN, "Language file [%s] contains " + "errors, check server log file for more details", + used_locale); +} + +/* Returns the name of current locale. */ +const char * +get_locale(void) +{ + return used_locale; +} diff --git a/src/packet.c b/src/packet.c new file mode 100644 index 0000000..aeb4ac6 --- /dev/null +++ b/src/packet.c @@ -0,0 +1,414 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * packet.c: Packet handlers. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ +#include "stdinc.h" +#include "list.h" +#include "s_bsd.h" +#include "conf.h" +#include "s_serv.h" +#include "client.h" +#include "ircd.h" +#include "parse.h" +#include "fdlist.h" +#include "packet.h" +#include "irc_string.h" +#include "memory.h" +#include "hook.h" +#include "send.h" +#include "s_misc.h" + +#define READBUF_SIZE 16384 + +struct Callback *iorecv_cb = NULL; + +static char readBuf[READBUF_SIZE]; +static void client_dopacket(struct Client *, char *, size_t); + +/* extract_one_line() + * + * inputs - pointer to a dbuf queue + * - pointer to buffer to copy data to + * output - length of <buffer> + * side effects - one line is copied and removed from the dbuf + */ +static int +extract_one_line(struct dbuf_queue *qptr, char *buffer) +{ + struct dbuf_block *block; + int line_bytes = 0, empty_bytes = 0, phase = 0; + unsigned int idx; + + char c; + dlink_node *ptr; + + /* + * Phase 0: "empty" characters before the line + * Phase 1: copying the line + * Phase 2: "empty" characters after the line + * (delete them as well and free some space in the dbuf) + * + * Empty characters are CR, LF and space (but, of course, not + * in the middle of a line). We try to remove as much of them as we can, + * since they simply eat server memory. + * + * --adx + */ + DLINK_FOREACH(ptr, qptr->blocks.head) + { + block = ptr->data; + + for (idx = 0; idx < block->size; idx++) + { + c = block->data[idx]; + if (IsEol(c) || (c == ' ' && phase != 1)) + { + empty_bytes++; + if (phase == 1) + phase = 2; + } + else switch (phase) + { + case 0: phase = 1; + case 1: if (line_bytes++ < IRCD_BUFSIZE - 2) + *buffer++ = c; + break; + case 2: *buffer = '\0'; + dbuf_delete(qptr, line_bytes + empty_bytes); + return IRCD_MIN(line_bytes, IRCD_BUFSIZE - 2); + } + } + } + + /* + * Now, if we haven't reached phase 2, ignore all line bytes + * that we have read, since this is a partial line case. + */ + if (phase != 2) + line_bytes = 0; + else + *buffer = '\0'; + + /* Remove what is now unnecessary */ + dbuf_delete(qptr, line_bytes + empty_bytes); + return IRCD_MIN(line_bytes, IRCD_BUFSIZE - 2); +} + +/* + * parse_client_queued - parse client queued messages + */ +static void +parse_client_queued(struct Client *client_p) +{ + int dolen = 0; + int checkflood = 1; + struct LocalUser *lclient_p = client_p->localClient; + + if (IsUnknown(client_p)) + { + int i = 0; + + for(;;) + { + if (IsDefunct(client_p)) + return; + + /* rate unknown clients at MAX_FLOOD per loop */ + if (i >= MAX_FLOOD) + break; + + dolen = extract_one_line(&lclient_p->buf_recvq, readBuf); + if (dolen == 0) + break; + + client_dopacket(client_p, readBuf, dolen); + i++; + + /* if they've dropped out of the unknown state, break and move + * to the parsing for their appropriate status. --fl + */ + if(!IsUnknown(client_p)) + break; + } + } + + if (IsServer(client_p) || IsConnecting(client_p) || IsHandshake(client_p)) + { + while (1) + { + if (IsDefunct(client_p)) + return; + if ((dolen = extract_one_line(&lclient_p->buf_recvq, + readBuf)) == 0) + break; + client_dopacket(client_p, readBuf, dolen); + } + } + else if (IsClient(client_p)) + { + if (ConfigFileEntry.no_oper_flood && (HasUMode(client_p, UMODE_OPER) || IsCanFlood(client_p))) + { + if (ConfigFileEntry.true_no_oper_flood) + checkflood = -1; + else + checkflood = 0; + } + + /* + * Handle flood protection here - if we exceed our flood limit on + * messages in this loop, we simply drop out of the loop prematurely. + * -- adrian + */ + for (;;) + { + if (IsDefunct(client_p)) + break; + + /* This flood protection works as follows: + * + * A client is given allow_read lines to send to the server. Every + * time a line is parsed, sent_parsed is increased. sent_parsed + * is decreased by 1 every time flood_recalc is called. + * + * Thus a client can 'burst' allow_read lines to the server, any + * excess lines will be parsed one per flood_recalc() call. + * + * Therefore a client will be penalised more if they keep flooding, + * as sent_parsed will always hover around the allow_read limit + * and no 'bursts' will be permitted. + */ + if (checkflood > 0) + { + if(lclient_p->sent_parsed >= lclient_p->allow_read) + break; + } + + /* allow opers 4 times the amount of messages as users. why 4? + * why not. :) --fl_ + */ + else if (lclient_p->sent_parsed >= (4 * lclient_p->allow_read) && + checkflood != -1) + break; + + dolen = extract_one_line(&lclient_p->buf_recvq, readBuf); + if (dolen == 0) + break; + + client_dopacket(client_p, readBuf, dolen); + lclient_p->sent_parsed++; + } + } +} + +/* flood_endgrace() + * + * marks the end of the clients grace period + */ +void +flood_endgrace(struct Client *client_p) +{ + SetFloodDone(client_p); + + /* Drop their flood limit back down */ + client_p->localClient->allow_read = MAX_FLOOD; + + /* sent_parsed could be way over MAX_FLOOD but under MAX_FLOOD_BURST, + * so reset it. + */ + client_p->localClient->sent_parsed = 0; +} + +/* + * flood_recalc + * + * recalculate the number of allowed flood lines. this should be called + * once a second on any given client. We then attempt to flush some data. + */ +void +flood_recalc(fde_t *fd, void *data) +{ + struct Client *client_p = data; + struct LocalUser *lclient_p = client_p->localClient; + + /* allow a bursting client their allocation per second, allow + * a client whos flooding an extra 2 per second + */ + if (IsFloodDone(client_p)) + lclient_p->sent_parsed -= 2; + else + lclient_p->sent_parsed = 0; + + if (lclient_p->sent_parsed < 0) + lclient_p->sent_parsed = 0; + + parse_client_queued(client_p); + + /* And now, try flushing .. */ + if (!IsDead(client_p)) + { + /* and finally, reset the flood check */ + comm_setflush(fd, 1000, flood_recalc, client_p); + } +} + +/* + * iorecv_default - append a packet to the recvq dbuf + */ +void * +iorecv_default(va_list args) +{ + struct Client *client_p = va_arg(args, struct Client *); + int length = va_arg(args, int); + char *buf = va_arg(args, char *); + + dbuf_put(&client_p->localClient->buf_recvq, buf, length); + return NULL; +} + +/* + * read_packet - Read a 'packet' of data from a connection and process it. + */ +void +read_packet(fde_t *fd, void *data) +{ + struct Client *client_p = data; + int length = 0; + + if (IsDefunct(client_p)) + return; + + /* + * Read some data. We *used to* do anti-flood protection here, but + * I personally think it makes the code too hairy to make sane. + * -- adrian + */ + do { +#ifdef HAVE_LIBCRYPTO + if (fd->ssl) + { + length = SSL_read(fd->ssl, readBuf, READBUF_SIZE); + + /* translate openssl error codes, sigh */ + if (length < 0) + switch (SSL_get_error(fd->ssl, length)) + { + case SSL_ERROR_WANT_WRITE: + fd->flags.pending_read = 1; + SetSendqBlocked(client_p); + comm_setselect(fd, COMM_SELECT_WRITE, (PF *) sendq_unblocked, + client_p, 0); + return; + case SSL_ERROR_WANT_READ: + errno = EWOULDBLOCK; + case SSL_ERROR_SYSCALL: + break; + case SSL_ERROR_SSL: + if (errno == EAGAIN) + break; + default: + length = errno = 0; + } + } + else +#endif + { + length = recv(fd->fd, readBuf, READBUF_SIZE, 0); + } + + if (length <= 0) + { + /* + * If true, then we can recover from this error. Just jump out of + * the loop and re-register a new io-request. + */ + if (length < 0 && ignoreErrno(errno)) + break; + + dead_link_on_read(client_p, length); + return; + } + + execute_callback(iorecv_cb, client_p, length, readBuf); + + if (client_p->localClient->lasttime < CurrentTime) + client_p->localClient->lasttime = CurrentTime; + if (client_p->localClient->lasttime > client_p->localClient->since) + client_p->localClient->since = CurrentTime; + ClearPingSent(client_p); + + /* Attempt to parse what we have */ + parse_client_queued(client_p); + + if (IsDefunct(client_p)) + return; + + /* Check to make sure we're not flooding */ + if (!(IsServer(client_p) || IsHandshake(client_p) || IsConnecting(client_p)) + && (dbuf_length(&client_p->localClient->buf_recvq) > + get_recvq(client_p))) + { + if (!(ConfigFileEntry.no_oper_flood && HasUMode(client_p, UMODE_OPER))) + { + exit_client(client_p, client_p, "Excess Flood"); + return; + } + } + } +#ifdef HAVE_LIBCRYPTO + while (length == sizeof(readBuf) || fd->ssl); +#else + while (length == sizeof(readBuf)); +#endif + + /* If we get here, we need to register for another COMM_SELECT_READ */ + comm_setselect(fd, COMM_SELECT_READ, read_packet, client_p, 0); +} + +/* + * client_dopacket - copy packet to client buf and parse it + * client_p - pointer to client structure for which the buffer data + * applies. + * buffer - pointr to the buffer containing the newly read data + * length - number of valid bytes of data in the buffer + * + * Note: + * It is implicitly assumed that dopacket is called only + * with client_p of "local" variation, which contains all the + * necessary fields (buffer etc..) + */ +static void +client_dopacket(struct Client *client_p, char *buffer, size_t length) +{ + /* + * Update messages received + */ + ++me.localClient->recv.messages; + ++client_p->localClient->recv.messages; + + /* + * Update bytes received + */ + client_p->localClient->recv.bytes += length; + me.localClient->recv.bytes += length; + + parse(client_p, buffer, buffer + length); +} diff --git a/src/parse.c b/src/parse.c new file mode 100644 index 0000000..f326d74 --- /dev/null +++ b/src/parse.c @@ -0,0 +1,815 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * parse.c: The message parser. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "client.h" +#include "parse.h" +#include "channel.h" +#include "hash.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "log.h" +#include "send.h" +#include "conf.h" +#include "memory.h" +#include "s_user.h" +#include "s_serv.h" + +/* + * (based on orabidoo's parser code) + * + * This has always just been a trie. Look at volume III of Knuth ACP + * + * + * ok, you start out with an array of pointers, each one corresponds + * to a letter at the current position in the command being examined. + * + * so roughly you have this for matching 'trie' or 'tie' + * + * 't' points -> [MessageTree *] 'r' -> [MessageTree *] -> 'i' + * -> [MessageTree *] -> [MessageTree *] -> 'e' and matches + * + * 'i' -> [MessageTree *] -> 'e' and matches + * + * BUGS (Limitations!) + * + * I designed this trie to parse ircd commands. Hence it currently + * casefolds. This is trivial to fix by increasing MAXPTRLEN. + * This trie also "folds" '{' etc. down. This means, the input to this + * trie must be alpha tokens only. This again, is a limitation that + * can be overcome by increasing MAXPTRLEN to include upper/lower case + * at the expense of more memory. At the extreme end, you could make + * MAXPTRLEN 128. + * + * This is also not a patricia trie. On short ircd tokens, this is + * not likely going to matter. + * + * Diane Bruce (Dianora), June 6 2003 + */ + +#define MAXPTRLEN 32 + /* Must be a power of 2, and + * larger than 26 [a-z]|[A-Z] + * its used to allocate the set + * of pointers at each node of the tree + * There are MAXPTRLEN pointers at each node. + * Obviously, there have to be more pointers + * Than ASCII letters. 32 is a nice number + * since there is then no need to shift + * 'A'/'a' to base 0 index, at the expense + * of a few never used pointers. For a small + * parser like this, this is a good compromise + * and does make it somewhat faster. + * + * - Dianora + */ + +struct MessageTree +{ + int links; /* Count of all pointers (including msg) at this node + * used as reference count for deletion of _this_ node. + */ + struct Message *msg; + struct MessageTree *pointers[MAXPTRLEN]; +}; + +static struct MessageTree msg_tree; + +/* + * NOTE: parse() should not be called recursively by other functions! + */ +static char *sender; +static char *para[MAXPARA + 2]; /* <prefix> + <params> + NULL */ +static char buffer[1024]; + +static int cancel_clients(struct Client *, struct Client *, char *); +static void remove_unknown(struct Client *, char *, char *); +static void handle_numeric(char[], struct Client *, struct Client *, int, char *[]); +static void handle_command(struct Message *, struct Client *, struct Client *, unsigned int, char *[]); + + +/* + * parse a buffer. + * + * NOTE: parse() should not be called recusively by any other functions! + */ +void +parse(struct Client *client_p, char *pbuffer, char *bufend) +{ + struct Client *from = client_p; + struct Message *msg_ptr = NULL; + char *ch = NULL; + char *s = NULL; + char *numeric = NULL; + unsigned int parc = 0; + unsigned int paramcount; + + if (IsDefunct(client_p)) + return; + + assert(client_p->localClient->fd.flags.open); + assert((bufend - pbuffer) < 512); + + for (ch = pbuffer; *ch == ' '; ++ch) /* skip spaces */ + /* null statement */ ; + + if (*ch == ':') + { + /* + * Copy the prefix to 'sender' assuming it terminates + * with SPACE (or NULL, which is an error, though). + */ + sender = ++ch; + + if ((s = strchr(ch, ' ')) != NULL) + { + *s = '\0'; + ch = ++s; + } + + if (*sender && IsServer(client_p)) + { + if ((from = find_person(client_p, sender)) == NULL) + from = hash_find_server(sender); + + /* Hmm! If the client corresponding to the + * prefix is not found--what is the correct + * action??? Now, I will ignore the message + * (old IRC just let it through as if the + * prefix just wasn't there...) --msa + */ + if (from == NULL) + { + ++ServerStats.is_unpf; + remove_unknown(client_p, sender, pbuffer); + return; + } + + if (from->from != client_p) + { + ++ServerStats.is_wrdi; + cancel_clients(client_p, from, pbuffer); + return; + } + } + + while (*ch == ' ') + ++ch; + } + + if (*ch == '\0') + { + ++ServerStats.is_empt; + return; + } + + /* Extract the command code from the packet. Point s to the end + * of the command code and calculate the length using pointer + * arithmetic. Note: only need length for numerics and *all* + * numerics must have parameters and thus a space after the command + * code. -avalon + */ + + /* EOB is 3 chars long but is not a numeric */ + if (*(ch + 3) == ' ' && /* ok, lets see if its a possible numeric.. */ + IsDigit(*ch) && IsDigit(*(ch + 1)) && IsDigit(*(ch + 2))) + { + numeric = ch; + paramcount = MAXPARA; + ++ServerStats.is_num; + s = ch + 3; /* I know this is ' ' from above if */ + *s++ = '\0'; /* blow away the ' ', and point s to next part */ + } + else + { + unsigned int ii = 0; + + if ((s = strchr(ch, ' ')) != NULL) + *s++ = '\0'; + + if ((msg_ptr = find_command(ch)) == NULL) + { + /* Note: Give error message *only* to recognized + * persons. It's a nightmare situation to have + * two programs sending "Unknown command"'s or + * equivalent to each other at full blast.... + * If it has got to person state, it at least + * seems to be well behaving. Perhaps this message + * should never be generated, though... --msa + * Hm, when is the buffer empty -- if a command + * code has been found ?? -Armin + */ + if (*pbuffer != '\0') + { + if (IsClient(from)) + sendto_one(from, form_str(ERR_UNKNOWNCOMMAND), + me.name, from->name, ch); + } + + ++ServerStats.is_unco; + return; + } + + assert(msg_ptr->cmd != NULL); + + paramcount = msg_ptr->args_max; + ii = bufend - ((s) ? s : ch); + msg_ptr->bytes += ii; + } + + /* + * Must the following loop really be so devious? On surface it + * splits the message to parameters from blank spaces. But, if + * paramcount has been reached, the rest of the message goes into + * this last parameter (about same effect as ":" has...) --msa + */ + + /* Note initially true: s==NULL || *(s-1) == '\0' !! */ + + para[parc] = from->name; + + if (s) + { + if (paramcount > MAXPARA) + paramcount = MAXPARA; + + while (1) + { + while (*s == ' ') + *s++ = '\0'; + + if (*s == '\0') + break; + + if (*s == ':') + { + /* The rest is a single parameter */ + para[++parc] = s + 1; + break; + } + + para[++parc] = s; + + if (parc >= paramcount) + break; + + while (*s && *s != ' ') + ++s; + } + } + + para[++parc] = NULL; + + if (msg_ptr != NULL) + handle_command(msg_ptr, client_p, from, parc, para); + else + handle_numeric(numeric, client_p, from, parc, para); +} + +/* handle_command() + * + * inputs - pointer to message block + * - pointer to client + * - pointer to client message is from + * - count of number of args + * - pointer to argv[] array + * output - -1 if error from server + * side effects - + */ +static void +handle_command(struct Message *mptr, struct Client *client_p, + struct Client *from, unsigned int i, char *hpara[]) +{ + MessageHandler handler = 0; + + if (IsServer(client_p)) + mptr->rcount++; + + mptr->count++; + + handler = mptr->handlers[client_p->handler]; + + /* check right amount of params is passed... --is */ + if (i < mptr->args_min) + { + if (!IsServer(client_p)) + { + sendto_one(client_p, form_str(ERR_NEEDMOREPARAMS), me.name, + EmptyString(hpara[0]) ? "*" : hpara[0], mptr->cmd); + } + else + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "Dropping server %s due to (invalid) command '%s' " + "with only %d arguments (expecting %d).", + client_p->name, mptr->cmd, i, mptr->args_min); + ilog(LOG_TYPE_IRCD, "Insufficient parameters (%d) for command '%s' from %s.", + i, mptr->cmd, client_p->name); + exit_client(client_p, client_p, + "Not enough arguments to server command."); + } + } + else + (*handler)(client_p, from, i, hpara); +} + +/* add_msg_element() + * + * inputs - pointer to MessageTree + * - pointer to Message to add for given command + * - pointer to current portion of command being added + * output - NONE + * side effects - recursively build the Message Tree ;-) + */ +/* + * How this works. + * + * The code first checks to see if its reached the end of the command + * If so, that struct MessageTree has a msg pointer updated and the links + * count incremented, since a msg pointer is a reference. + * Then the code descends recursively, building the trie. + * If a pointer index inside the struct MessageTree is NULL a new + * child struct MessageTree has to be allocated. + * The links (reference count) is incremented as they are created + * in the parent. + */ +static void +add_msg_element(struct MessageTree *mtree_p, struct Message *msg_p, + const char *cmd) +{ + struct MessageTree *ntree_p; + + if (*cmd == '\0') + { + mtree_p->msg = msg_p; + mtree_p->links++; /* Have msg pointer, so up ref count */ + } + else + { + /* *cmd & (MAXPTRLEN-1) + * convert the char pointed to at *cmd from ASCII to an integer + * between 0 and MAXPTRLEN. + * Thus 'A' -> 0x1 'B' -> 0x2 'c' -> 0x3 etc. + */ + + if ((ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN - 1)]) == NULL) + { + ntree_p = MyMalloc(sizeof(struct MessageTree)); + mtree_p->pointers[*cmd & (MAXPTRLEN - 1)] = ntree_p; + + mtree_p->links++; /* Have new pointer, so up ref count */ + } + + add_msg_element(ntree_p, msg_p, cmd + 1); + } +} + +/* del_msg_element() + * + * inputs - Pointer to MessageTree to delete from + * - pointer to command name to delete + * output - NONE + * side effects - recursively deletes a token from the Message Tree ;-) + */ +/* + * How this works. + * + * Well, first off, the code recursively descends into the trie + * until it finds the terminating letter of the command being removed. + * Once it has done that, it marks the msg pointer as NULL then + * reduces the reference count on that allocated struct MessageTree + * since a command counts as a reference. + * + * Then it pops up the recurse stack. As it comes back up the recurse + * The code checks to see if the child now has no pointers or msg + * i.e. the links count has gone to zero. If its no longer used, the + * child struct MessageTree can be deleted. The parent reference + * to this child is then removed and the parents link count goes down. + * Thus, we continue to go back up removing all unused MessageTree(s) + */ +static void +del_msg_element(struct MessageTree *mtree_p, const char *cmd) +{ + struct MessageTree *ntree_p; + + /* + * In case this is called for a nonexistent command + * check that there is a msg pointer here, else links-- goes -ve + * -db + */ + if ((*cmd == '\0') && (mtree_p->msg != NULL)) + { + mtree_p->msg = NULL; + mtree_p->links--; + } + else + { + if ((ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN - 1)]) != NULL) + { + del_msg_element(ntree_p, cmd + 1); + + if (ntree_p->links == 0) + { + mtree_p->pointers[*cmd & (MAXPTRLEN - 1)] = NULL; + mtree_p->links--; + MyFree(ntree_p); + } + } + } +} + +/* msg_tree_parse() + * + * inputs - Pointer to command to find + * - Pointer to MessageTree root + * output - Find given command returning Message * if found NULL if not + * side effects - none + */ +static struct Message * +msg_tree_parse(const char *cmd) +{ + struct MessageTree *mtree = &msg_tree; + assert(cmd && *cmd); + + while (IsAlpha(*cmd) && (mtree = mtree->pointers[*cmd & (MAXPTRLEN - 1)])) + if (*++cmd == '\0') + return mtree->msg; + + return NULL; +} + +/* mod_add_cmd() + * + * inputs - pointer to struct Message + * output - none + * side effects - load this one command name + * msg->count msg->bytes is modified in place, in + * modules address space. Might not want to do that... + */ +void +mod_add_cmd(struct Message *msg) +{ + assert(msg && msg->cmd); + + /* command already added? */ + if (msg_tree_parse(msg->cmd)) + return; + + add_msg_element(&msg_tree, msg, msg->cmd); + msg->count = msg->rcount = msg->bytes = 0; +} + +/* mod_del_cmd() + * + * inputs - pointer to struct Message + * output - none + * side effects - unload this one command name + */ +void +mod_del_cmd(struct Message *msg) +{ + assert(msg && msg->cmd); + + del_msg_element(&msg_tree, msg->cmd); +} + +/* find_command() + * + * inputs - command name + * output - pointer to struct Message + * side effects - none + */ +struct Message * +find_command(const char *cmd) +{ + return msg_tree_parse(cmd); +} + +static void +recurse_report_messages(struct Client *source_p, const struct MessageTree *mtree) +{ + unsigned int i; + + if (mtree->msg != NULL) + sendto_one(source_p, form_str(RPL_STATSCOMMANDS), + me.name, source_p->name, mtree->msg->cmd, + mtree->msg->count, mtree->msg->bytes, + mtree->msg->rcount); + + for (i = 0; i < MAXPTRLEN; ++i) + if (mtree->pointers[i] != NULL) + recurse_report_messages(source_p, mtree->pointers[i]); +} + +/* report_messages() + * + * inputs - pointer to client to report to + * output - NONE + * side effects - client is shown list of commands + */ +void +report_messages(struct Client *source_p) +{ + const struct MessageTree *mtree = &msg_tree; + unsigned int i; + + for (i = 0; i < MAXPTRLEN; ++i) + if (mtree->pointers[i] != NULL) + recurse_report_messages(source_p, mtree->pointers[i]); +} + +/* cancel_clients() + * + * inputs - + * output - + * side effects - + */ +static int +cancel_clients(struct Client *client_p, struct Client *source_p, char *cmd) +{ + /* kill all possible points that are causing confusion here, + * I'm not sure I've got this all right... + * - avalon + * + * knowing avalon, probably not. + */ + + /* with TS, fake prefixes are a common thing, during the + * connect burst when there's a nick collision, and they + * must be ignored rather than killed because one of the + * two is surviving.. so we don't bother sending them to + * all ops everytime, as this could send 'private' stuff + * from lagged clients. we do send the ones that cause + * servers to be dropped though, as well as the ones from + * non-TS servers -orabidoo + */ + /* Incorrect prefix for a server from some connection. If it is a + * client trying to be annoying, just QUIT them, if it is a server + * then the same deal. + */ + if (IsServer(source_p) || IsMe(source_p)) + { + sendto_realops_flags(UMODE_DEBUG, L_ADMIN, "Message for %s[%s] from %s", + source_p->name, source_p->from->name, + get_client_name(client_p, SHOW_IP)); + sendto_realops_flags(UMODE_DEBUG, L_OPER, "Message for %s[%s] from %s", + source_p->name, source_p->from->name, + get_client_name(client_p, MASK_IP)); + sendto_realops_flags(UMODE_DEBUG, L_ALL, + "Not dropping server %s (%s) for Fake Direction", + client_p->name, source_p->name); + return -1; + /* return exit_client(client_p, client_p, &me, "Fake Direction");*/ + } + + /* Ok, someone is trying to impose as a client and things are + * confused. If we got the wrong prefix from a server, send out a + * kill, else just exit the lame client. + */ + /* If the fake prefix is coming from a TS server, discard it + * silently -orabidoo + * + * all servers must be TS these days --is + */ + sendto_realops_flags(UMODE_DEBUG, L_ADMIN, + "Message for %s[%s@%s!%s] from %s (TS, ignored)", + source_p->name, source_p->username, source_p->host, + source_p->from->name, get_client_name(client_p, SHOW_IP)); + sendto_realops_flags(UMODE_DEBUG, L_OPER, + "Message for %s[%s@%s!%s] from %s (TS, ignored)", + source_p->name, source_p->username, source_p->host, + source_p->from->name, get_client_name(client_p, MASK_IP)); + + return 0; +} + +/* remove_unknown() + * + * inputs - + * output - + * side effects - + */ +static void +remove_unknown(struct Client *client_p, char *lsender, char *lbuffer) +{ + /* Do kill if it came from a server because it means there is a ghost + * user on the other server which needs to be removed. -avalon + * Tell opers about this. -Taner + */ + /* '[0-9]something' is an ID (KILL/SQUIT depending on its length) + * 'nodots' is a nickname (KILL) + * 'no.dot.at.start' is a server (SQUIT) + */ + if ((IsDigit(*lsender) && strlen(lsender) <= IRC_MAXSID) || + strchr(lsender, '.') != NULL) + { + sendto_realops_flags(UMODE_DEBUG, L_ADMIN, + "Unknown prefix (%s) from %s, Squitting %s", + lbuffer, get_client_name(client_p, SHOW_IP), lsender); + sendto_realops_flags(UMODE_DEBUG, L_OPER, + "Unknown prefix (%s) from %s, Squitting %s", + lbuffer, client_p->name, lsender); + sendto_one(client_p, ":%s SQUIT %s :(Unknown prefix (%s) from %s)", + me.name, lsender, lbuffer, client_p->name); + } + else + sendto_one(client_p, ":%s KILL %s :%s (Unknown Client)", + me.name, lsender, me.name); +} + +/* + * + * parc number of arguments ('sender' counted as one!) + * parv[0] pointer to 'sender' (may point to empty string) (not used) + * parv[1]..parv[parc-1] + * pointers to additional parameters, this is a NULL + * terminated list (parv[parc] == NULL). + * + * *WARNING* + * Numerics are mostly error reports. If there is something + * wrong with the message, just *DROP* it! Don't even think of + * sending back a neat error message -- big danger of creating + * a ping pong error message... + */ +static void +handle_numeric(char numeric[], struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + struct Client *target_p; + struct Channel *chptr; + char *t; /* current position within the buffer */ + int i, tl; /* current length of presently being built string in t */ + + if (parc < 2 || !IsServer(source_p)) + return; + + /* Remap low number numerics. */ + if (numeric[0] == '0') + numeric[0] = '1'; + + /* Prepare the parameter portion of the message into 'buffer'. + * (Because the buffer is twice as large as the message buffer + * for the socket, no overflow can occur here... ...on current + * assumptions--bets are off, if these are changed --msa) + */ + t = buffer; + for (i = 2; i < (parc - 1); i++) + { + tl = ircsprintf(t, " %s", parv[i]); + t += tl; + } + + ircsprintf(t, " :%s", parv[parc-1]); + + if (((target_p = find_person(client_p, parv[1])) != NULL) || + ((target_p = hash_find_server(parv[1])) != NULL)) + { + if (IsMe(target_p)) + { + int num; + + /* + * We shouldn't get numerics sent to us, + * any numerics we do get indicate a bug somewhere.. + */ + /* ugh. this is here because of nick collisions. when two servers + * relink, they burst each other their nicks, then perform collides. + * if there is a nick collision, BOTH servers will kill their own + * nicks, and BOTH will kill the other servers nick, which wont exist, + * because it will have been already killed by the local server. + * + * unfortunately, as we cant guarantee other servers will do the + * "right thing" on a nick collision, we have to keep both kills. + * ergo we need to ignore ERR_NOSUCHNICK. --fl_ + */ + /* quick comment. This _was_ tried. i.e. assume the other servers + * will do the "right thing" and kill a nick that is colliding. + * unfortunately, it did not work. --Dianora + */ + + /* Yes, a good compiler would have optimised this, but + * this is probably easier to read. -db + */ + num = atoi(numeric); + + if ((num != ERR_NOSUCHNICK)) + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "*** %s(via %s) sent a %s numeric to me: %s", + source_p->name, client_p->name, numeric, buffer); + return; + } + else if (target_p->from == client_p) + { + /* This message changed direction (nick collision?) + * ignore it. + */ + return; + } + + /* csircd will send out unknown umode flag for +a (admin), drop it here. */ + if ((atoi(numeric) == ERR_UMODEUNKNOWNFLAG) && MyClient(target_p)) + return; + + /* Fake it for server hiding, if its our client */ + if (ConfigServerHide.hide_servers && + MyClient(target_p) && !HasUMode(target_p, UMODE_OPER)) + sendto_one(target_p, ":%s %s %s%s", me.name, numeric, target_p->name, buffer); + else + sendto_one(target_p, ":%s %s %s%s", ID_or_name(source_p, target_p->from), + numeric, ID_or_name(target_p, target_p->from), buffer); + return; + } + else if ((chptr = hash_find_channel(parv[1])) != NULL) + sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s %s %s %s", + source_p->name, + numeric, chptr->chname, buffer); +} + +/* m_not_oper() + * inputs - + * output - + * side effects - just returns a nastyogram to given user + */ +void +m_not_oper(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); +} + +void +m_unregistered(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + sendto_one(source_p, form_str(ERR_NOTREGISTERED), me.name, + source_p->name[0] ? source_p->name : "*"); +} + +void +m_registered(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + sendto_one(source_p, form_str(ERR_ALREADYREGISTRED), + me.name, source_p->name); +} + +void +m_ignore(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + return; +} + +void +rfc1459_command_send_error(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + const char *in_para; + + in_para = (parc > 1 && *parv[1] != '\0') ? parv[1] : "<>"; + + ilog(LOG_TYPE_IRCD, "Received ERROR message from %s: %s", + source_p->name, in_para); + + if (client_p == source_p) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, "ERROR :from %s -- %s", + get_client_name(client_p, HIDE_IP), in_para); + sendto_realops_flags(UMODE_ALL, L_OPER, "ERROR :from %s -- %s", + get_client_name(client_p, MASK_IP), in_para); + } + else + { + sendto_realops_flags(UMODE_ALL, L_OPER, "ERROR :from %s via %s -- %s", + source_p->name, get_client_name(client_p, MASK_IP), in_para); + sendto_realops_flags(UMODE_ALL, L_ADMIN, "ERROR :from %s via %s -- %s", + source_p->name, get_client_name(client_p, HIDE_IP), in_para); + } + + if (MyClient(source_p)) + exit_client(source_p, source_p, "ERROR"); +} diff --git a/src/restart.c b/src/restart.c new file mode 100644 index 0000000..01966a6 --- /dev/null +++ b/src/restart.c @@ -0,0 +1,94 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * restart.c: Functions to allow the ircd to restart. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "restart.h" +#include "fdlist.h" +#include "ircd.h" +#include "irc_string.h" +#include "send.h" +#include "log.h" +#include "client.h" /* for UMODE_ALL */ +#include "memory.h" + +void +restart(const char *mesg) +{ + static int was_here = 0; /* redundant due to restarting flag below */ + + if (was_here++) + abort(); + + server_die(mesg, 1); +} + +void +server_die(const char *mesg, int rboot) +{ + char buffer[IRCD_BUFSIZE]; + dlink_node *ptr = NULL; + struct Client *target_p = NULL; + static int was_here = 0; + + if (rboot && was_here++) + abort(); + + if (EmptyString(mesg)) + snprintf(buffer, sizeof(buffer), "Server %s", + rboot ? "Restarting" : "Terminating"); + else + snprintf(buffer, sizeof(buffer), "Server %s: %s", + rboot ? "Restarting" : "Terminating", mesg); + + DLINK_FOREACH(ptr, local_client_list.head) + { + target_p = ptr->data; + + sendto_one(target_p, ":%s NOTICE %s :%s", + me.name, target_p->name, buffer); + } + + DLINK_FOREACH(ptr, serv_list.head) + { + target_p = ptr->data; + + sendto_one(target_p, ":%s ERROR :%s", me.name, buffer); + } + + ilog(LOG_TYPE_IRCD, "%s", buffer); + + send_queued_all(); + close_fds(NULL); + + unlink(pidFileName); + + if (rboot) + { + execv(SPATH, myargv); + exit(1); + } + else + exit(0); +} diff --git a/src/resv.c b/src/resv.c new file mode 100644 index 0000000..6f4ec14 --- /dev/null +++ b/src/resv.c @@ -0,0 +1,230 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * resv.c: Functions to reserve(jupe) a nick/channel. + * + * Copyright (C) 2001-2002 Hybrid 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 + * + * $Id$ + */ + +#include "stdinc.h" +#include "list.h" +#include "ircd.h" +#include "send.h" +#include "client.h" +#include "memory.h" +#include "numeric.h" +#include "resv.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd_defs.h" +#include "conf.h" + +dlink_list resv_channel_list = { NULL, NULL, 0 }; + + +/* create_channel_resv() + * + * inputs - name of channel to create resv for + * - reason for resv + * - flag, 1 for from ircd.conf 0 from elsehwere + * output - pointer to struct ResvChannel + * side effects - + */ +struct ConfItem * +create_channel_resv(char *name, char *reason, int in_conf) +{ + struct ConfItem *conf = NULL; + struct ResvChannel *resv_p = NULL; + + if (name == NULL || reason == NULL) + return NULL; + + if (hash_find_resv(name)) + return NULL; + + if (strlen(reason) > REASONLEN) + reason[REASONLEN] = '\0'; + + conf = make_conf_item(CRESV_TYPE); + resv_p = map_to_conf(conf); + + strlcpy(resv_p->name, name, sizeof(resv_p->name)); + DupString(conf->name, name); + DupString(resv_p->reason, reason); + resv_p->conf = in_conf; + + dlinkAdd(resv_p, &resv_p->node, &resv_channel_list); + hash_add_resv(resv_p); + + return conf; +} + +/* create_nick_resv() + * + * inputs - name of nick to create resv for + * - reason for resv + * - 1 if from ircd.conf, 0 if from elsewhere + * output - pointer to struct ResvNick + * side effects - + */ +struct ConfItem * +create_nick_resv(char *name, char *reason, int in_conf) +{ + struct ConfItem *conf = NULL; + struct MatchItem *resv_p = NULL; + + if (name == NULL || reason == NULL) + return NULL; + + if (find_matching_name_conf(NRESV_TYPE, name, NULL, NULL, 0)) + return NULL; + + if (strlen(reason) > REASONLEN) + reason[REASONLEN] = '\0'; + + conf = make_conf_item(NRESV_TYPE); + resv_p = map_to_conf(conf); + + DupString(conf->name, name); + DupString(resv_p->reason, reason); + resv_p->action = in_conf; + + return conf; +} + +/* clear_conf_resv() + * + * inputs - none + * output - none + * side effects - All resvs are cleared out + */ +void +clear_conf_resv(void) +{ + dlink_node *ptr = NULL, *next_ptr = NULL; + + DLINK_FOREACH_SAFE(ptr, next_ptr, resv_channel_list.head) + delete_channel_resv(ptr->data); +} + +/* delete_channel_resv() + * + * inputs - pointer to channel resv to delete + * output - none + * side effects - given struct ResvChannel * is removed + */ +int +delete_channel_resv(struct ResvChannel *resv_p) +{ + struct ConfItem *conf = NULL; + assert(resv_p != NULL); + + hash_del_resv(resv_p); + dlinkDelete(&resv_p->node, &resv_channel_list); + MyFree(resv_p->reason); + conf = unmap_conf_item(resv_p); + delete_conf_item(conf); + + return 1; +} + +/* match_find_resv() + * + * inputs - pointer to name + * output - pointer to a struct ResvChannel + * side effects - Finds a reserved channel whose name matches 'name', + * if can't find one returns NULL. + */ +struct ResvChannel * +match_find_resv(const char *name) +{ + dlink_node *ptr = NULL; + + if (EmptyString(name)) + return NULL; + + DLINK_FOREACH(ptr, resv_channel_list.head) + { + struct ResvChannel *chptr = ptr->data; + + if (match_chan(name, chptr->name)) + return chptr; + } + + return NULL; +} + +/* report_resv() + * + * inputs - pointer to client pointer to report to. + * output - NONE + * side effects - report all resvs to client. + */ +void +report_resv(struct Client *source_p) +{ + dlink_node *ptr; + struct ConfItem *conf; + struct ResvChannel *resv_cp; + struct MatchItem *resv_np; + + DLINK_FOREACH(ptr, resv_channel_list.head) + { + resv_cp = ptr->data; + sendto_one(source_p, form_str(RPL_STATSQLINE), + me.name, source_p->name, + resv_cp->conf ? 'Q' : 'q', + resv_cp->name, resv_cp->reason); + } + + DLINK_FOREACH(ptr, nresv_items.head) + { + conf = ptr->data; + resv_np = map_to_conf(conf); + + sendto_one(source_p, form_str(RPL_STATSQLINE), + me.name, source_p->name, + resv_np->action ? 'Q' : 'q', + conf->name, resv_np->reason); + } +} + +/* valid_wild_card_simple() + * + * inputs - data to check for sufficient non-wildcard characters + * outputs - 1 if valid, else 0 + * side effects - none + */ +int +valid_wild_card_simple(const char *data) +{ + const unsigned char *p = (const unsigned char *)data; + int nonwild = 0; + + while (*p != '\0') + { + if ((*p == '\\' && *++p) || (*p && !IsMWildChar(*p))) + if (++nonwild == ConfigFileEntry.min_nonwildcard_simple) + return 1; + if (*p != '\0') + ++p; + } + + return 0; +} diff --git a/src/rng_mt.c b/src/rng_mt.c new file mode 100644 index 0000000..dacc11f --- /dev/null +++ b/src/rng_mt.c @@ -0,0 +1,167 @@ +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + 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. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) + + $Id$ +*/ + +#include "stdinc.h" +#include "rng_mt.h" + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfU /* constant vector a */ +#define UPPER_MASK 0x80000000U /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffU /* least significant r bits */ + +static uint32_t mt[N]; /* the array for the state vector */ +static int mti = N + 1; /* mti==N+1 means mt[N] is not initialized */ + +/* initializes mt[N] with a seed */ +void +init_genrand(uint32_t s) +{ + mt[0] = s & 0xffffffffU; + + for (mti = 1; mti < N; mti++) + { + mt[mti] = (1812433253U * (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffU; + /* for >32 bit machines */ + } +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +/* slight change for C++, 2004/2/26 */ +void +init_by_array(uint32_t init_key[], int key_length) +{ + int i, j, k; + + init_genrand(19650218U); + + i = 1; j = 0; + k = (N > key_length ? N : key_length); + + for (; k; k--) + { + mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1664525U)) + + init_key[j] + j; /* non linear */ + mt[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */ + i++; j++; + + if (i >= N) + { + mt[0] = mt[N - 1]; + i = 1; + } + + if (j >= key_length) + j = 0; + } + + for (k = N - 1; k; k--) + { + mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1566083941U)) + - i; /* non linear */ + mt[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */ + i++; + + if (i >= N) + { + mt[0] = mt[N - 1]; + i = 1; + } + } + + mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ +} + +/* generates a random number on [0,0xffffffff]-interval */ +uint32_t +genrand_int32(void) +{ + uint32_t y; + static uint32_t mag01[2]={ 0x0U, MATRIX_A }; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) + { /* generate N words at one time */ + int kk; + + if (mti == N + 1) /* if init_genrand() has not been called, */ + init_genrand(5489U); /* a default initial seed is used */ + + for (kk = 0; kk < N - M; kk++) + { + y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); + mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1U]; + } + + for (; kk < N - 1; kk++) + { + y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); + mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1U]; + } + + y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK); + mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1U]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680U; + y ^= (y << 15) & 0xefc60000U; + y ^= (y >> 18); + + return y; +} diff --git a/src/rsa.c b/src/rsa.c new file mode 100644 index 0000000..8623ae0 --- /dev/null +++ b/src/rsa.c @@ -0,0 +1,120 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * rsa.c: Functions for use with RSA public key cryptography. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#ifdef HAVE_LIBCRYPTO +#include <openssl/pem.h> +#include <openssl/rand.h> +#include <openssl/rsa.h> +#include <openssl/bn.h> +#include <openssl/evp.h> +#include <openssl/err.h> +#include <openssl/opensslv.h> + +#include "memory.h" +#include "rsa.h" +#include "conf.h" +#include "log.h" + + +/* + * report_crypto_errors - Dump crypto error list to log + */ +void +report_crypto_errors(void) +{ + unsigned long e = 0; + unsigned long cnt = 0; + + while ((cnt < 100) && (e = ERR_get_error())) + { + ilog(LOG_TYPE_IRCD, "SSL error: %s", ERR_error_string(e, 0)); + cnt++; + } +} + +static void +binary_to_hex(unsigned char *bin, char *hex, int length) +{ + static const char trans[] = "0123456789ABCDEF"; + int i; + + for (i = 0; i < length; i++) + { + hex[i << 1] = trans[bin[i] >> 4]; + hex[(i << 1) + 1] = trans[bin[i] & 0xf]; + } + + hex[i << 1] = '\0'; +} + +int +get_randomness(unsigned char *buf, int length) +{ + /* Seed OpenSSL PRNG with EGD enthropy pool -kre */ + if (ConfigFileEntry.use_egd && + (ConfigFileEntry.egdpool_path != NULL)) + { + if (RAND_egd(ConfigFileEntry.egdpool_path) == -1) + return -1; + } + + if (RAND_status()) + return (RAND_bytes(buf, length)); + else /* XXX - abort? */ + return (RAND_pseudo_bytes(buf, length)); +} + +int +generate_challenge(char **r_challenge, char **r_response, RSA *rsa) +{ + unsigned char secret[32], *tmp; + unsigned long length; + int ret = -1; + + if (!rsa) + return -1; + + get_randomness(secret, 32); + *r_response = MyMalloc(65); + binary_to_hex(secret, *r_response, 32); + + length = RSA_size(rsa); + tmp = MyMalloc(length); + ret = RSA_public_encrypt(32, secret, tmp, rsa, RSA_PKCS1_PADDING); + + *r_challenge = MyMalloc((length << 1) + 1); + binary_to_hex( tmp, *r_challenge, length); + (*r_challenge)[length<<1] = 0; + MyFree(tmp); + + if (ret < 0) + { + report_crypto_errors(); + return -1; + } + + return 0; +} +#endif diff --git a/src/s_auth.c b/src/s_auth.c new file mode 100644 index 0000000..c14cb22 --- /dev/null +++ b/src/s_auth.c @@ -0,0 +1,598 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_auth.c: Functions for querying a users ident. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +/* + * Changes: + * July 6, 1999 - Rewrote most of the code here. When a client connects + * to the server and passes initial socket validation checks, it + * is owned by this module (auth) which returns it to the rest of the + * server when dns and auth queries are finished. Until the client is + * released, the server does not know it exists and does not process + * any messages from it. + * --Bleep Thomas Helvey <tomh@inxpress.net> + */ + +#include "stdinc.h" +#include "list.h" +#include "ircd_defs.h" +#include "fdlist.h" +#include "s_auth.h" +#include "conf.h" +#include "balloc.h" +#include "client.h" +#include "event.h" +#include "hook.h" +#include "irc_string.h" +#include "ircd.h" +#include "packet.h" +#include "irc_res.h" +#include "s_bsd.h" +#include "log.h" +#include "send.h" + + +static const char *HeaderMessages[] = { + ":%s NOTICE AUTH :*** Looking up your hostname...", + ":%s NOTICE AUTH :*** Found your hostname", + ":%s NOTICE AUTH :*** Couldn't look up your hostname", + ":%s NOTICE AUTH :*** Checking Ident", + ":%s NOTICE AUTH :*** Got Ident response", + ":%s NOTICE AUTH :*** No Ident response", + ":%s NOTICE AUTH :*** Your forward and reverse DNS do not match, ignoring hostname.", + ":%s NOTICE AUTH :*** Your hostname is too long, ignoring hostname" +}; + +enum { + REPORT_DO_DNS, + REPORT_FIN_DNS, + REPORT_FAIL_DNS, + REPORT_DO_ID, + REPORT_FIN_ID, + REPORT_FAIL_ID, + REPORT_IP_MISMATCH, + REPORT_HOST_TOOLONG +}; + +#define sendheader(c, i) sendto_one((c), HeaderMessages[(i)], me.name) + +static BlockHeap *auth_heap = NULL; +static dlink_list auth_doing_list = { NULL, NULL, 0 }; + +static EVH timeout_auth_queries_event; + +static PF read_auth_reply; +static CNCB auth_connect_callback; +static CBFUNC start_auth; + +struct Callback *auth_cb = NULL; + +/* init_auth() + * + * Initialise the auth code + */ +void +init_auth(void) +{ + auth_heap = BlockHeapCreate("auth", sizeof(struct AuthRequest), AUTH_HEAP_SIZE); + auth_cb = register_callback("start_auth", start_auth); + eventAddIsh("timeout_auth_queries_event", timeout_auth_queries_event, NULL, 1); +} + +/* + * make_auth_request - allocate a new auth request + */ +static struct AuthRequest * +make_auth_request(struct Client *client) +{ + struct AuthRequest *request = BlockHeapAlloc(auth_heap); + + client->localClient->auth = request; + request->client = client; + request->timeout = CurrentTime + CONNECTTIMEOUT; + + return request; +} + +/* + * release_auth_client - release auth client from auth system + * this adds the client into the local client lists so it can be read by + * the main io processing loop + */ +void +release_auth_client(struct AuthRequest *auth) +{ + struct Client *client = auth->client; + + if (IsDoingAuth(auth) || IsDNSPending(auth)) + return; + + client->localClient->auth = NULL; + dlinkDelete(&auth->node, &auth_doing_list); + BlockHeapFree(auth_heap, auth); + + /* + * When a client has auth'ed, we want to start reading what it sends + * us. This is what read_packet() does. + * -- adrian + */ + client->localClient->allow_read = MAX_FLOOD; + comm_setflush(&client->localClient->fd, 1000, flood_recalc, client); + + dlinkAdd(client, &client->node, &global_client_list); + + client->localClient->since = CurrentTime; + client->localClient->lasttime = CurrentTime; + client->localClient->firsttime = CurrentTime; + client->flags |= FLAGS_FINISHED_AUTH; + + read_packet(&client->localClient->fd, client); +} + +/* + * auth_dns_callback - called when resolver query finishes + * if the query resulted in a successful search, name will contain + * a non-NULL pointer, otherwise name will be NULL. + * set the client on it's way to a connection completion, regardless + * of success of failure + */ +static void +auth_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name) +{ + struct AuthRequest *auth = vptr; + + ClearDNSPending(auth); + + if (name != NULL) + { + const struct sockaddr_in *v4, *v4dns; +#ifdef IPV6 + const struct sockaddr_in6 *v6, *v6dns; +#endif + int good = 1; + +#ifdef IPV6 + if (auth->client->localClient->ip.ss.ss_family == AF_INET6) + { + v6 = (const struct sockaddr_in6 *)&auth->client->localClient->ip; + v6dns = (const struct sockaddr_in6 *)addr; + if (memcmp(&v6->sin6_addr, &v6dns->sin6_addr, sizeof(struct in6_addr)) != 0) + { + sendheader(auth->client, REPORT_IP_MISMATCH); + good = 0; + } + } + else +#endif + { + v4 = (const struct sockaddr_in *)&auth->client->localClient->ip; + v4dns = (const struct sockaddr_in *)addr; + if(v4->sin_addr.s_addr != v4dns->sin_addr.s_addr) + { + sendheader(auth->client, REPORT_IP_MISMATCH); + good = 0; + } + } + if (good && strlen(name) <= HOSTLEN) + { + strlcpy(auth->client->host, name, + sizeof(auth->client->host)); + sendheader(auth->client, REPORT_FIN_DNS); + } + else if (strlen(name) > HOSTLEN) + sendheader(auth->client, REPORT_HOST_TOOLONG); + } + else + sendheader(auth->client, REPORT_FAIL_DNS); + + release_auth_client(auth); +} + +/* + * authsenderr - handle auth send errors + */ +static void +auth_error(struct AuthRequest *auth) +{ + ++ServerStats.is_abad; + + fd_close(&auth->fd); + + ClearAuth(auth); + + sendheader(auth->client, REPORT_FAIL_ID); + + release_auth_client(auth); +} + +/* + * start_auth_query - Flag the client to show that an attempt to + * contact the ident server on + * the client's host. The connect and subsequently the socket are all put + * into 'non-blocking' mode. Should the connect or any later phase of the + * identifing process fail, it is aborted and the user is given a username + * of "unknown". + */ +static int +start_auth_query(struct AuthRequest *auth) +{ + struct irc_ssaddr localaddr; + socklen_t locallen = sizeof(struct irc_ssaddr); +#ifdef IPV6 + struct sockaddr_in6 *v6; +#else + struct sockaddr_in *v4; +#endif + + /* open a socket of the same type as the client socket */ + if (comm_open(&auth->fd, auth->client->localClient->ip.ss.ss_family, + SOCK_STREAM, 0, "ident") == -1) + { + report_error(L_ALL, "creating auth stream socket %s:%s", + get_client_name(auth->client, SHOW_IP), errno); + ilog(LOG_TYPE_IRCD, "Unable to create auth socket for %s", + get_client_name(auth->client, SHOW_IP)); + ++ServerStats.is_abad; + return 0; + } + + sendheader(auth->client, REPORT_DO_ID); + + /* + * get the local address of the client and bind to that to + * make the auth request. This used to be done only for + * ifdef VIRTUAL_HOST, but needs to be done for all clients + * since the ident request must originate from that same address-- + * and machines with multiple IP addresses are common now + */ + memset(&localaddr, 0, locallen); + getsockname(auth->client->localClient->fd.fd, (struct sockaddr*)&localaddr, + &locallen); + +#ifdef IPV6 + remove_ipv6_mapping(&localaddr); + v6 = (struct sockaddr_in6 *)&localaddr; + v6->sin6_port = htons(0); +#else + localaddr.ss_len = locallen; + v4 = (struct sockaddr_in *)&localaddr; + v4->sin_port = htons(0); +#endif + localaddr.ss_port = htons(0); + + comm_connect_tcp(&auth->fd, auth->client->sockhost, 113, + (struct sockaddr *)&localaddr, localaddr.ss_len, auth_connect_callback, + auth, auth->client->localClient->ip.ss.ss_family, + GlobalSetOptions.ident_timeout); + return 1; /* We suceed here for now */ +} + +/* + * GetValidIdent - parse ident query reply from identd server + * + * Inputs - pointer to ident buf + * Output - NULL if no valid ident found, otherwise pointer to name + * Side effects - + */ +/* + * A few questions have been asked about this mess, obviously + * it should have been commented better the first time. + * The original idea was to remove all references to libc from ircd-hybrid. + * Instead of having to write a replacement for sscanf(), I did a + * rather gruseome parser here so we could remove this function call. + * Note, that I had also removed a few floating point printfs as well (though + * now we are still stuck with a few...) + * Remember, we have a replacement ircd sprintf, we have bleeps fputs lib + * it would have been nice to remove some unneeded code. + * Oh well. If we don't remove libc stuff totally, then it would be + * far cleaner to use sscanf() + * + * - Dianora + */ +static char * +GetValidIdent(char *buf) +{ + int remp = 0; + int locp = 0; + char* colon1Ptr; + char* colon2Ptr; + char* colon3Ptr; + char* commaPtr; + char* remotePortString; + + /* All this to get rid of a sscanf() fun. */ + remotePortString = buf; + + if ((colon1Ptr = strchr(remotePortString,':')) == NULL) + return 0; + *colon1Ptr = '\0'; + colon1Ptr++; + + if ((colon2Ptr = strchr(colon1Ptr,':')) == NULL) + return 0; + *colon2Ptr = '\0'; + colon2Ptr++; + + if ((commaPtr = strchr(remotePortString, ',')) == NULL) + return 0; + *commaPtr = '\0'; + commaPtr++; + + if ((remp = atoi(remotePortString)) == 0) + return 0; + + if ((locp = atoi(commaPtr)) == 0) + return 0; + + /* look for USERID bordered by first pair of colons */ + if (strstr(colon1Ptr, "USERID") == NULL) + return 0; + + if ((colon3Ptr = strchr(colon2Ptr,':')) == NULL) + return 0; + *colon3Ptr = '\0'; + colon3Ptr++; + return (colon3Ptr); +} + +/* + * start_auth + * + * inputs - pointer to client to auth + * output - NONE + * side effects - starts auth (identd) and dns queries for a client + */ +static void * +start_auth(va_list args) +{ + struct Client *client = va_arg(args, struct Client *); + struct AuthRequest *auth = NULL; + + assert(client != NULL); + + auth = make_auth_request(client); + dlinkAdd(auth, &auth->node, &auth_doing_list); + + sendheader(client, REPORT_DO_DNS); + + SetDNSPending(auth); + + if (ConfigFileEntry.disable_auth == 0) + { + SetDoingAuth(auth); + start_auth_query(auth); + } + + gethost_byaddr(auth_dns_callback, auth, &client->localClient->ip); + + return NULL; +} + +/* + * timeout_auth_queries - timeout resolver and identd requests + * allow clients through if requests failed + */ +static void +timeout_auth_queries_event(void *notused) +{ + dlink_node *ptr = NULL, *next_ptr = NULL; + + DLINK_FOREACH_SAFE(ptr, next_ptr, auth_doing_list.head) + { + struct AuthRequest *auth = ptr->data; + + if (auth->timeout > CurrentTime) + continue; + + if (IsDoingAuth(auth)) + { + ++ServerStats.is_abad; + fd_close(&auth->fd); + ClearAuth(auth); + sendheader(auth->client, REPORT_FAIL_ID); + } + + if (IsDNSPending(auth)) + { + delete_resolver_queries(auth); + ClearDNSPending(auth); + sendheader(auth->client, REPORT_FAIL_DNS); + } + + ilog(LOG_TYPE_IRCD, "DNS/AUTH timeout %s", + get_client_name(auth->client, SHOW_IP)); + release_auth_client(auth); + } +} + +/* + * auth_connect_callback() - deal with the result of comm_connect_tcp() + * + * If the connection failed, we simply close the auth fd and report + * a failure. If the connection suceeded send the ident server a query + * giving "theirport , ourport". The write is only attempted *once* so + * it is deemed to be a fail if the entire write doesn't write all the + * data given. This shouldnt be a problem since the socket should have + * a write buffer far greater than this message to store it in should + * problems arise. -avalon + */ +static void +auth_connect_callback(fde_t *fd, int error, void *data) +{ + struct AuthRequest *auth = data; + struct irc_ssaddr us; + struct irc_ssaddr them; + char authbuf[32]; + socklen_t ulen = sizeof(struct irc_ssaddr); + socklen_t tlen = sizeof(struct irc_ssaddr); + uint16_t uport, tport; +#ifdef IPV6 + struct sockaddr_in6 *v6; +#else + struct sockaddr_in *v4; +#endif + + if (error != COMM_OK) + { + auth_error(auth); + return; + } + + if (getsockname(auth->client->localClient->fd.fd, (struct sockaddr *)&us, + &ulen) || + getpeername(auth->client->localClient->fd.fd, (struct sockaddr *)&them, + &tlen)) + { + ilog(LOG_TYPE_IRCD, "auth get{sock,peer}name error for %s", + get_client_name(auth->client, SHOW_IP)); + auth_error(auth); + return; + } + +#ifdef IPV6 + v6 = (struct sockaddr_in6 *)&us; + uport = ntohs(v6->sin6_port); + v6 = (struct sockaddr_in6 *)&them; + tport = ntohs(v6->sin6_port); + remove_ipv6_mapping(&us); + remove_ipv6_mapping(&them); +#else + v4 = (struct sockaddr_in *)&us; + uport = ntohs(v4->sin_port); + v4 = (struct sockaddr_in *)&them; + tport = ntohs(v4->sin_port); + us.ss_len = ulen; + them.ss_len = tlen; +#endif + + snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n", tport, uport); + + if (send(fd->fd, authbuf, strlen(authbuf), 0) == -1) + { + auth_error(auth); + return; + } + + read_auth_reply(&auth->fd, auth); +} + +/* + * read_auth_reply - read the reply (if any) from the ident server + * we connected to. + * We only give it one shot, if the reply isn't good the first time + * fail the authentication entirely. --Bleep + */ +#define AUTH_BUFSIZ 128 + +static void +read_auth_reply(fde_t *fd, void *data) +{ + struct AuthRequest *auth = data; + char *s = NULL; + char *t = NULL; + int len; + int count; + char buf[AUTH_BUFSIZ + 1]; /* buffer to read auth reply into */ + + /* Why? + * Well, recv() on many POSIX systems is a per-packet operation, + * and we do not necessarily want this, because on lowspec machines, + * the ident response may come back fragmented, thus resulting in an + * invalid ident response, even if the ident response was really OK. + * + * So PLEASE do not change this code to recv without being aware of the + * consequences. + * + * --nenolod + */ + len = read(fd->fd, buf, AUTH_BUFSIZ); + + if (len < 0) + { + if (ignoreErrno(errno)) + comm_setselect(fd, COMM_SELECT_READ, read_auth_reply, auth, 0); + else + auth_error(auth); + return; + } + + if (len > 0) + { + buf[len] = '\0'; + + if ((s = GetValidIdent(buf))) + { + t = auth->client->username; + + while (*s == '~' || *s == '^') + s++; + + for (count = USERLEN; *s && count; s++) + { + if (*s == '@') + break; + if (!IsSpace(*s) && *s != ':' && *s != '[') + { + *t++ = *s; + count--; + } + } + + *t = '\0'; + } + } + + fd_close(fd); + + ClearAuth(auth); + + if (s == NULL) + { + sendheader(auth->client, REPORT_FAIL_ID); + ++ServerStats.is_abad; + } + else + { + sendheader(auth->client, REPORT_FIN_ID); + ++ServerStats.is_asuc; + SetGotId(auth->client); + } + + release_auth_client(auth); +} + +/* + * delete_auth() + */ +void +delete_auth(struct AuthRequest *auth) +{ + if (IsDNSPending(auth)) + delete_resolver_queries(auth); + + if (IsDoingAuth(auth)) + fd_close(&auth->fd); + + dlinkDelete(&auth->node, &auth_doing_list); + BlockHeapFree(auth_heap, auth); +} diff --git a/src/s_bsd.c b/src/s_bsd.c new file mode 100644 index 0000000..316d3f4 --- /dev/null +++ b/src/s_bsd.c @@ -0,0 +1,757 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_bsd.c: Network functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/tcp.h> +#include "list.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "client.h" +#include "dbuf.h" +#include "event.h" +#include "irc_string.h" +#include "ircd.h" +#include "listener.h" +#include "numeric.h" +#include "packet.h" +#include "irc_res.h" +#include "restart.h" +#include "s_auth.h" +#include "conf.h" +#include "log.h" +#include "s_serv.h" +#include "send.h" +#include "memory.h" +#include "s_user.h" +#include "hook.h" + +static const char *comm_err_str[] = { "Comm OK", "Error during bind()", + "Error during DNS lookup", "connect timeout", "Error during connect()", + "Comm Error" }; + +struct Callback *setup_socket_cb = NULL; + +static void comm_connect_callback(fde_t *, int); +static PF comm_connect_timeout; +static void comm_connect_dns_callback(void *, const struct irc_ssaddr *, const char *); +static PF comm_connect_tryconnect; + + +/* check_can_use_v6() + * Check if the system can open AF_INET6 sockets + */ +void +check_can_use_v6(void) +{ +#ifdef IPV6 + int v6; + + if ((v6 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) + ServerInfo.can_use_v6 = 0; + else + { + ServerInfo.can_use_v6 = 1; + close(v6); + } +#else + ServerInfo.can_use_v6 = 0; +#endif +} + +/* get_sockerr - get the error value from the socket or the current errno + * + * Get the *real* error from the socket (well try to anyway..). + * This may only work when SO_DEBUG is enabled but its worth the + * gamble anyway. + */ +int +get_sockerr(int fd) +{ + int errtmp = errno; +#ifdef SO_ERROR + int err = 0; + socklen_t len = sizeof(err); + + if (-1 < fd && !getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len)) + { + if (err) + errtmp = err; + } + errno = errtmp; +#endif + return errtmp; +} + +/* + * report_error - report an error from an errno. + * Record error to log and also send a copy to all *LOCAL* opers online. + * + * text is a *format* string for outputing error. It must + * contain only two '%s', the first will be replaced + * by the sockhost from the client_p, and the latter will + * be taken from sys_errlist[errno]. + * + * client_p if not NULL, is the *LOCAL* client associated with + * the error. + * + * Cannot use perror() within daemon. stderr is closed in + * ircd and cannot be used. And, worse yet, it might have + * been reassigned to a normal connection... + * + * Actually stderr is still there IFF ircd was run with -s --Rodder + */ + +void +report_error(int level, const char* text, const char* who, int error) +{ + who = (who) ? who : ""; + + sendto_realops_flags(UMODE_DEBUG, level, text, who, strerror(error)); + ilog(LOG_TYPE_IRCD, text, who, strerror(error)); +} + +/* + * setup_socket() + * + * Set the socket non-blocking, and other wonderful bits. + */ +static void * +setup_socket(va_list args) +{ + int fd = va_arg(args, int); + int opt = 1; + + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)); + +#ifdef IPTOS_LOWDELAY + opt = IPTOS_LOWDELAY; + setsockopt(fd, IPPROTO_IP, IP_TOS, &opt, sizeof(opt)); +#endif + + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + + return NULL; +} + +/* + * init_comm() + * + * Initializes comm subsystem. + */ +void +init_comm(void) +{ + setup_socket_cb = register_callback("setup_socket", setup_socket); + init_netio(); +} + +/* + * close_connection + * Close the physical connection. This function must make + * MyConnect(client_p) == FALSE, and set client_p->from == NULL. + */ +void +close_connection(struct Client *client_p) +{ + struct AccessItem *aconf; + struct ClassItem *aclass; + dlink_node *ptr = NULL; + + assert(client_p); + + if (!IsDead(client_p)) + { + /* attempt to flush any pending dbufs. Evil, but .. -- adrian */ + /* there is still a chance that we might send data to this socket + * even if it is marked as blocked (COMM_SELECT_READ handler is called + * before COMM_SELECT_WRITE). Let's try, nothing to lose.. -adx + */ + ClearSendqBlocked(client_p); + send_queued_write(client_p); + } + + if (IsClient(client_p)) + { + ++ServerStats.is_cl; + ServerStats.is_cbs += client_p->localClient->send.bytes; + ServerStats.is_cbr += client_p->localClient->recv.bytes; + ServerStats.is_cti += CurrentTime - client_p->localClient->firsttime; + } + else if (IsServer(client_p)) + { + ++ServerStats.is_sv; + ServerStats.is_sbs += client_p->localClient->send.bytes; + ServerStats.is_sbr += client_p->localClient->recv.bytes; + ServerStats.is_sti += CurrentTime - client_p->localClient->firsttime; + + DLINK_FOREACH(ptr, server_items.head) + { + struct ConfItem *conf = ptr->data; + + if (irccmp(conf->name, client_p->name)) + continue; + + /* + * Reset next-connect cycle of all connect{} blocks that match + * this servername. + */ + aconf = map_to_conf(conf); + aclass = map_to_conf(aconf->class_ptr); + aconf->hold = CurrentTime + aclass->con_freq; + } + } + else + ++ServerStats.is_ni; + +#ifdef HAVE_LIBCRYPTO + if (client_p->localClient->fd.ssl) + { + SSL_set_shutdown(client_p->localClient->fd.ssl, SSL_RECEIVED_SHUTDOWN); + + if (!SSL_shutdown(client_p->localClient->fd.ssl)) + SSL_shutdown(client_p->localClient->fd.ssl); + } +#endif + if (client_p->localClient->fd.flags.open) + fd_close(&client_p->localClient->fd); + + dbuf_clear(&client_p->localClient->buf_sendq); + dbuf_clear(&client_p->localClient->buf_recvq); + + MyFree(client_p->localClient->passwd); + detach_conf(client_p, CONF_TYPE); + client_p->from = NULL; /* ...this should catch them! >:) --msa */ +} + +#ifdef HAVE_LIBCRYPTO +/* + * ssl_handshake - let OpenSSL initialize the protocol. Register for + * read/write events if necessary. + */ +static void +ssl_handshake(int fd, struct Client *client_p) +{ + int ret = SSL_accept(client_p->localClient->fd.ssl); + + if (ret <= 0) + switch (SSL_get_error(client_p->localClient->fd.ssl, ret)) + { + case SSL_ERROR_WANT_WRITE: + comm_setselect(&client_p->localClient->fd, COMM_SELECT_WRITE, + (PF *) ssl_handshake, client_p, 0); + return; + + case SSL_ERROR_WANT_READ: + comm_setselect(&client_p->localClient->fd, COMM_SELECT_READ, + (PF *) ssl_handshake, client_p, 0); + return; + + default: + exit_client(client_p, client_p, "Error during SSL handshake"); + return; + } + + execute_callback(auth_cb, client_p); +} +#endif + +/* + * add_connection - creates a client which has just connected to us on + * the given fd. The sockhost field is initialized with the ip# of the host. + * An unique id is calculated now, in case it is needed for auth. + * The client is sent to the auth module for verification, and not put in + * any client list yet. + */ +void +add_connection(struct Listener *listener, struct irc_ssaddr *irn, int fd) +{ + struct Client *new_client = make_client(NULL); + + fd_open(&new_client->localClient->fd, fd, 1, + (listener->flags & LISTENER_SSL) ? + "Incoming SSL connection" : "Incoming connection"); + + /* + * copy address to 'sockhost' as a string, copy it to host too + * so we have something valid to put into error messages... + */ + memcpy(&new_client->localClient->ip, irn, sizeof(struct irc_ssaddr)); + + getnameinfo((struct sockaddr *)&new_client->localClient->ip, + new_client->localClient->ip.ss_len, new_client->sockhost, + sizeof(new_client->sockhost), NULL, 0, NI_NUMERICHOST); + new_client->localClient->aftype = new_client->localClient->ip.ss.ss_family; + + if (new_client->sockhost[0] == ':' && new_client->sockhost[1] == ':') + { + strlcpy(new_client->host, "0", sizeof(new_client->host)); + strlcpy(new_client->host+1, new_client->sockhost, sizeof(new_client->host)-1); + memmove(new_client->sockhost+1, new_client->sockhost, sizeof(new_client->sockhost)-1); + new_client->sockhost[0] = '0'; + } + else + strlcpy(new_client->host, new_client->sockhost, sizeof(new_client->host)); + + new_client->localClient->listener = listener; + ++listener->ref_count; + +#ifdef HAVE_LIBCRYPTO + if (listener->flags & LISTENER_SSL) + { + if ((new_client->localClient->fd.ssl = SSL_new(ServerInfo.server_ctx)) == NULL) + { + ilog(LOG_TYPE_IRCD, "SSL_new() ERROR! -- %s", + ERR_error_string(ERR_get_error(), NULL)); + + SetDead(new_client); + exit_client(new_client, new_client, "SSL_new failed"); + return; + } + + SSL_set_fd(new_client->localClient->fd.ssl, fd); + ssl_handshake(0, new_client); + } + else +#endif + execute_callback(auth_cb, new_client); +} + +/* + * stolen from squid - its a neat (but overused! :) routine which we + * can use to see whether we can ignore this errno or not. It is + * generally useful for non-blocking network IO related errnos. + * -- adrian + */ +int +ignoreErrno(int ierrno) +{ + switch (ierrno) + { + case EINPROGRESS: + case EWOULDBLOCK: +#if EAGAIN != EWOULDBLOCK + case EAGAIN: +#endif + case EALREADY: + case EINTR: +#ifdef ERESTART + case ERESTART: +#endif + return 1; + default: + return 0; + } +} + +/* + * comm_settimeout() - set the socket timeout + * + * Set the timeout for the fd + */ +void +comm_settimeout(fde_t *fd, time_t timeout, PF *callback, void *cbdata) +{ + assert(fd->flags.open); + + fd->timeout = CurrentTime + (timeout / 1000); + fd->timeout_handler = callback; + fd->timeout_data = cbdata; +} + +/* + * comm_setflush() - set a flush function + * + * A flush function is simply a function called if found during + * comm_timeouts(). Its basically a second timeout, except in this case + * I'm too lazy to implement multiple timeout functions! :-) + * its kinda nice to have it separate, since this is designed for + * flush functions, and when comm_close() is implemented correctly + * with close functions, we _actually_ don't call comm_close() here .. + * -- originally Adrian's notes + * comm_close() is replaced with fd_close() in fdlist.c + */ +void +comm_setflush(fde_t *fd, time_t timeout, PF *callback, void *cbdata) +{ + assert(fd->flags.open); + + fd->flush_timeout = CurrentTime + (timeout / 1000); + fd->flush_handler = callback; + fd->flush_data = cbdata; +} + +/* + * comm_checktimeouts() - check the socket timeouts + * + * All this routine does is call the given callback/cbdata, without closing + * down the file descriptor. When close handlers have been implemented, + * this will happen. + */ +void +comm_checktimeouts(void *notused) +{ + int i; + fde_t *F; + PF *hdl; + void *data; + + for (i = 0; i < FD_HASH_SIZE; i++) + for (F = fd_hash[i]; F != NULL; F = fd_next_in_loop) + { + assert(F->flags.open); + fd_next_in_loop = F->hnext; + + /* check flush functions */ + if (F->flush_handler && F->flush_timeout > 0 && + F->flush_timeout < CurrentTime) + { + hdl = F->flush_handler; + data = F->flush_data; + comm_setflush(F, 0, NULL, NULL); + hdl(F, data); + } + + /* check timeouts */ + if (F->timeout_handler && F->timeout > 0 && + F->timeout < CurrentTime) + { + /* Call timeout handler */ + hdl = F->timeout_handler; + data = F->timeout_data; + comm_settimeout(F, 0, NULL, NULL); + hdl(F, data); + } + } +} + +/* + * void comm_connect_tcp(int fd, const char *host, unsigned short port, + * struct sockaddr *clocal, int socklen, + * CNCB *callback, void *data, int aftype, int timeout) + * Input: An fd to connect with, a host and port to connect to, + * a local sockaddr to connect from + length(or NULL to use the + * default), a callback, the data to pass into the callback, the + * address family. + * Output: None. + * Side-effects: A non-blocking connection to the host is started, and + * if necessary, set up for selection. The callback given + * may be called now, or it may be called later. + */ +void +comm_connect_tcp(fde_t *fd, const char *host, unsigned short port, + struct sockaddr *clocal, int socklen, CNCB *callback, + void *data, int aftype, int timeout) +{ + struct addrinfo hints, *res; + char portname[PORTNAMELEN + 1]; + + assert(callback); + fd->connect.callback = callback; + fd->connect.data = data; + + fd->connect.hostaddr.ss.ss_family = aftype; + fd->connect.hostaddr.ss_port = htons(port); + + /* Note that we're using a passed sockaddr here. This is because + * generally you'll be bind()ing to a sockaddr grabbed from + * getsockname(), so this makes things easier. + * XXX If NULL is passed as local, we should later on bind() to the + * virtual host IP, for completeness. + * -- adrian + */ + if ((clocal != NULL) && (bind(fd->fd, clocal, socklen) < 0)) + { + /* Failure, call the callback with COMM_ERR_BIND */ + comm_connect_callback(fd, COMM_ERR_BIND); + /* ... and quit */ + return; + } + + /* Next, if we have been given an IP, get the addr and skip the + * DNS check (and head direct to comm_connect_tryconnect(). + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + + snprintf(portname, sizeof(portname), "%d", port); + + if (getaddrinfo(host, portname, &hints, &res)) + { + /* Send the DNS request, for the next level */ + if (aftype == AF_INET6) + gethost_byname_type(comm_connect_dns_callback, fd, host, T_AAAA); + else + gethost_byname_type(comm_connect_dns_callback, fd, host, T_A); + } + else + { + /* We have a valid IP, so we just call tryconnect */ + /* Make sure we actually set the timeout here .. */ + assert(res != NULL); + memcpy(&fd->connect.hostaddr, res->ai_addr, res->ai_addrlen); + fd->connect.hostaddr.ss_len = res->ai_addrlen; + fd->connect.hostaddr.ss.ss_family = res->ai_family; + freeaddrinfo(res); + comm_settimeout(fd, timeout*1000, comm_connect_timeout, NULL); + comm_connect_tryconnect(fd, NULL); + } +} + +/* + * comm_connect_callback() - call the callback, and continue with life + */ +static void +comm_connect_callback(fde_t *fd, int status) +{ + CNCB *hdl; + + /* This check is gross..but probably necessary */ + if (fd->connect.callback == NULL) + return; + + /* Clear the connect flag + handler */ + hdl = fd->connect.callback; + fd->connect.callback = NULL; + + /* Clear the timeout handler */ + comm_settimeout(fd, 0, NULL, NULL); + + /* Call the handler */ + hdl(fd, status, fd->connect.data); +} + +/* + * comm_connect_timeout() - this gets called when the socket connection + * times out. This *only* can be called once connect() is initially + * called .. + */ +static void +comm_connect_timeout(fde_t *fd, void *notused) +{ + /* error! */ + comm_connect_callback(fd, COMM_ERR_TIMEOUT); +} + +/* + * comm_connect_dns_callback() - called at the completion of the DNS request + * + * The DNS request has completed, so if we've got an error, return it, + * otherwise we initiate the connect() + */ +static void +comm_connect_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name) +{ + fde_t *F = vptr; + + if (name == NULL) + { + comm_connect_callback(F, COMM_ERR_DNS); + return; + } + + /* No error, set a 10 second timeout */ + comm_settimeout(F, 30*1000, comm_connect_timeout, NULL); + + /* Copy over the DNS reply info so we can use it in the connect() */ + /* + * Note we don't fudge the refcount here, because we aren't keeping + * the DNS record around, and the DNS cache is gone anyway.. + * -- adrian + */ + memcpy(&F->connect.hostaddr, addr, addr->ss_len); + /* The cast is hacky, but safe - port offset is same on v4 and v6 */ + ((struct sockaddr_in *) &F->connect.hostaddr)->sin_port = + F->connect.hostaddr.ss_port; + F->connect.hostaddr.ss_len = addr->ss_len; + + /* Now, call the tryconnect() routine to try a connect() */ + comm_connect_tryconnect(F, NULL); +} + +/* static void comm_connect_tryconnect(int fd, void *notused) + * Input: The fd, the handler data(unused). + * Output: None. + * Side-effects: Try and connect with pending connect data for the FD. If + * we succeed or get a fatal error, call the callback. + * Otherwise, it is still blocking or something, so register + * to select for a write event on this FD. + */ +static void +comm_connect_tryconnect(fde_t *fd, void *notused) +{ + int retval; + + /* This check is needed or re-entrant s_bsd_* like sigio break it. */ + if (fd->connect.callback == NULL) + return; + + /* Try the connect() */ + retval = connect(fd->fd, (struct sockaddr *) &fd->connect.hostaddr, + fd->connect.hostaddr.ss_len); + + /* Error? */ + if (retval < 0) + { + /* + * If we get EISCONN, then we've already connect()ed the socket, + * which is a good thing. + * -- adrian + */ + if (errno == EISCONN) + comm_connect_callback(fd, COMM_OK); + else if (ignoreErrno(errno)) + /* Ignore error? Reschedule */ + comm_setselect(fd, COMM_SELECT_WRITE, comm_connect_tryconnect, + NULL, 0); + else + /* Error? Fail with COMM_ERR_CONNECT */ + comm_connect_callback(fd, COMM_ERR_CONNECT); + return; + } + + /* If we get here, we've suceeded, so call with COMM_OK */ + comm_connect_callback(fd, COMM_OK); +} + +/* + * comm_errorstr() - return an error string for the given error condition + */ +const char * +comm_errstr(int error) +{ + if (error < 0 || error >= COMM_ERR_MAX) + return "Invalid error number!"; + return comm_err_str[error]; +} + +/* + * comm_open() - open a socket + * + * This is a highly highly cut down version of squid's comm_open() which + * for the most part emulates socket(), *EXCEPT* it fails if we're about + * to run out of file descriptors. + */ +int +comm_open(fde_t *F, int family, int sock_type, int proto, const char *note) +{ + int fd; + + /* First, make sure we aren't going to run out of file descriptors */ + if (number_fd >= hard_fdlimit) + { + errno = ENFILE; + return -1; + } + + /* + * Next, we try to open the socket. We *should* drop the reserved FD + * limit if/when we get an error, but we can deal with that later. + * XXX !!! -- adrian + */ + fd = socket(family, sock_type, proto); + if (fd < 0) + return -1; /* errno will be passed through, yay.. */ + + execute_callback(setup_socket_cb, fd); + + /* update things in our fd tracking */ + fd_open(F, fd, 1, note); + return 0; +} + +/* + * comm_accept() - accept an incoming connection + * + * This is a simple wrapper for accept() which enforces FD limits like + * comm_open() does. Returned fd must be either closed or tagged with + * fd_open (this function no longer does it). + */ +int +comm_accept(struct Listener *lptr, struct irc_ssaddr *pn) +{ + int newfd; + socklen_t addrlen = sizeof(struct irc_ssaddr); + + if (number_fd >= hard_fdlimit) + { + errno = ENFILE; + return -1; + } + + /* + * Next, do the accept(). if we get an error, we should drop the + * reserved fd limit, but we can deal with that when comm_open() + * also does it. XXX -- adrian + */ + newfd = accept(lptr->fd.fd, (struct sockaddr *)pn, &addrlen); + if (newfd < 0) + return -1; + +#ifdef IPV6 + remove_ipv6_mapping(pn); +#else + pn->ss_len = addrlen; +#endif + + execute_callback(setup_socket_cb, newfd); + + /* .. and return */ + return newfd; +} + +/* + * remove_ipv6_mapping() - Removes IPv4-In-IPv6 mapping from an address + * OSes with IPv6 mapping listening on both + * AF_INET and AF_INET6 map AF_INET connections inside AF_INET6 structures + * + */ +#ifdef IPV6 +void +remove_ipv6_mapping(struct irc_ssaddr *addr) +{ + if (addr->ss.ss_family == AF_INET6) + { + if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)addr)->sin6_addr)) + { + struct sockaddr_in6 v6; + struct sockaddr_in *v4 = (struct sockaddr_in *)addr; + + memcpy(&v6, addr, sizeof(v6)); + memset(v4, 0, sizeof(struct sockaddr_in)); + memcpy(&v4->sin_addr, &v6.sin6_addr.s6_addr[12], sizeof(v4->sin_addr)); + + addr->ss.ss_family = AF_INET; + addr->ss_len = sizeof(struct sockaddr_in); + } + else + addr->ss_len = sizeof(struct sockaddr_in6); + } + else + addr->ss_len = sizeof(struct sockaddr_in); +} +#endif diff --git a/src/s_bsd_devpoll.c b/src/s_bsd_devpoll.c new file mode 100644 index 0000000..49d4eee --- /dev/null +++ b/src/s_bsd_devpoll.c @@ -0,0 +1,186 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_bsd_devpoll.c: /dev/poll compatible network routines. + * + * Originally by Adrian Chadd <adrian@creative.net.au> + * Copyright (C) 2002 Hybrid 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 + * + * $Id$ + */ + +#include "stdinc.h" +#if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_DEVPOLL +#include <sys/ioctl.h> +/* HPUX uses devpoll.h and not sys/devpoll.h */ +#ifdef HAVE_DEVPOLL_H +# include <devpoll.h> +#else +# ifdef HAVE_SYS_DEVPOLL_H +# include <sys/devpoll.h> +# else +# error "No devpoll.h found! Try ./configuring and letting the script choose for you." +# endif +#endif +#include "fdlist.h" +#include "ircd.h" +#include "s_bsd.h" +#include "log.h" + +static fde_t dpfd; + +/* + * init_netio + * + * This is a needed exported function which will be called to initialise + * the network loop code. + */ +void +init_netio(void) +{ + int fd; + + if ((fd = open("/dev/poll", O_RDWR)) < 0) + { + ilog(LOG_TYPE_IRCD, "init_netio: Couldn't open /dev/poll - %d: %s", + errno, strerror(errno)); + exit(115); /* Whee! */ + } + + fd_open(&dpfd, fd, 0, "/dev/poll file descriptor"); +} + +/* + * Write an update to the devpoll filter. + * See, we end up having to do a seperate (?) remove before we do an + * add of a new polltype, so we have to have this function seperate from + * the others. + */ +static void +devpoll_write_update(int fd, int events) +{ + struct pollfd pfd; + + /* Build the pollfd entry */ + pfd.revents = 0; + pfd.fd = fd; + pfd.events = events; + + /* Write the thing to our poll fd */ + if (write(dpfd.fd, &pfd, sizeof(pfd)) != sizeof(pfd)) + ilog(LOG_TYPE_IRCD, "devpoll_write_update: dpfd write failed %d: %s", + errno, strerror(errno)); +} + +/* + * comm_setselect + * + * This is a needed exported function which will be called to register + * and deregister interest in a pending IO state for a given FD. + */ +void +comm_setselect(fde_t *F, unsigned int type, PF *handler, + void *client_data, time_t timeout) +{ + int new_events; + + if ((type & COMM_SELECT_READ)) + { + F->read_handler = handler; + F->read_data = client_data; + } + + if ((type & COMM_SELECT_WRITE)) + { + F->write_handler = handler; + F->write_data = client_data; + } + + new_events = (F->read_handler ? POLLIN : 0) | + (F->write_handler ? POLLOUT : 0); + + if (timeout != 0) + F->timeout = CurrentTime + (timeout / 1000); + + if (new_events != F->evcache) + { + devpoll_write_update(F->fd, POLLREMOVE); + if ((F->evcache = new_events)) + devpoll_write_update(F->fd, new_events); + } +} + +/* + * comm_select + * + * Called to do the new-style IO, courtesy of squid (like most of this + * new IO code). This routine handles the stuff we've hidden in + * comm_setselect and fd_table[] and calls callbacks for IO ready + * events. + */ +void +comm_select(void) +{ + int num, i; + struct pollfd pollfds[128]; + struct dvpoll dopoll; + PF *hdl; + fde_t *F; + + dopoll.dp_timeout = SELECT_DELAY; + dopoll.dp_nfds = 128; + dopoll.dp_fds = &pollfds[0]; + num = ioctl(dpfd.fd, DP_POLL, &dopoll); + + set_time(); + + if (num < 0) + { +#ifdef HAVE_USLEEP + usleep(50000); /* avoid 99% CPU in comm_select */ +#endif + return; + } + + for (i = 0; i < num; i++) + { + F = lookup_fd(dopoll.dp_fds[i].fd); + if (F == NULL || !F->flags.open) + continue; + + if ((dopoll.dp_fds[i].revents & POLLIN)) + if ((hdl = F->read_handler) != NULL) + { + F->read_handler = NULL; + hdl(F, F->read_data); + if (!F->flags.open) + continue; + } + + if ((dopoll.dp_fds[i].revents & POLLOUT)) + if ((hdl = F->write_handler) != NULL) + { + F->write_handler = NULL; + hdl(F, F->write_data); + if (!F->flags.open) + continue; + } + + comm_setselect(F, 0, NULL, NULL, 0); + } +} +#endif diff --git a/src/s_bsd_epoll.c b/src/s_bsd_epoll.c new file mode 100644 index 0000000..8e8de83 --- /dev/null +++ b/src/s_bsd_epoll.c @@ -0,0 +1,221 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_bsd_epoll.c: Linux epoll() compatible network routines. + * + * Copyright (C) 2002-2005 Hybrid Development Team + * Based also on work of Adrian Chadd, Aaron Sethman and others. + * + * 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$ + */ + +#include "stdinc.h" +#if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_EPOLL +#include "fdlist.h" +#include "ircd.h" +#include "memory.h" +#include "s_bsd.h" +#include "log.h" +#include <sys/epoll.h> +#include <sys/syscall.h> + +static fde_t efd; + +/* Thanks to ircu for the following ifdefs. */ + +/* The GNU C library may have a valid header but stub implementations + * of the epoll system calls. If so, provide our own. */ +#if defined(__stub_epoll_create) || defined(__stub___epoll_create) || defined(EPOLL_NEED_BODY) + +/* Oh, did we mention that some glibc releases do not even define the + * syscall numbers? */ +#if !defined(__NR_epoll_create) +#if defined(__ia64__) +#define __NR_epoll_create 1243 +#define __NR_epoll_ctl 1244 +#define __NR_epoll_wait 1245 +#elif defined(__x86_64__) +#define __NR_epoll_create 214 +#define __NR_epoll_ctl 233 +#define __NR_epoll_wait 232 +#elif defined(__sparc64__) || defined(__sparc__) +#define __NR_epoll_create 193 +#define __NR_epoll_ctl 194 +#define __NR_epoll_wait 195 +#elif defined(__s390__) || defined(__m68k__) +#define __NR_epoll_create 249 +#define __NR_epoll_ctl 250 +#define __NR_epoll_wait 251 +#elif defined(__ppc64__) || defined(__ppc__) +#define __NR_epoll_create 236 +#define __NR_epoll_ctl 237 +#define __NR_epoll_wait 238 +#elif defined(__parisc__) || defined(__arm26__) || defined(__arm__) +#define __NR_epoll_create 224 +#define __NR_epoll_ctl 225 +#define __NR_epoll_wait 226 +#elif defined(__alpha__) +#define __NR_epoll_create 407 +#define __NR_epoll_ctl 408 +#define __NR_epoll_wait 409 +#elif defined(__sh64__) +#define __NR_epoll_create 282 +#define __NR_epoll_ctl 283 +#define __NR_epoll_wait 284 +#elif defined(__i386__) || defined(__sh__) || defined(__m32r__) || defined(__h8300__) || defined(__frv__) +#define __NR_epoll_create 254 +#define __NR_epoll_ctl 255 +#define __NR_epoll_wait 256 +#else /* cpu types */ +#error No system call numbers defined for epoll family. +#endif /* cpu types */ +#endif /* !defined(__NR_epoll_create) */ + +_syscall1(int, epoll_create, int, size) +_syscall4(int, epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event *, event) +_syscall4(int, epoll_wait, int, epfd, struct epoll_event *, pevents, int, maxevents, int, timeout) + +#endif /* epoll_create defined as stub */ + +/* + * init_netio + * + * This is a needed exported function which will be called to initialise + * the network loop code. + */ +void +init_netio(void) +{ + int fd; + + if ((fd = epoll_create(hard_fdlimit)) < 0) + { + ilog(LOG_TYPE_IRCD, "init_netio: Couldn't open epoll fd - %d: %s", + errno, strerror(errno)); + exit(115); /* Whee! */ + } + + fd_open(&efd, fd, 0, "epoll file descriptor"); +} + +/* + * comm_setselect + * + * This is a needed exported function which will be called to register + * and deregister interest in a pending IO state for a given FD. + */ +void +comm_setselect(fde_t *F, unsigned int type, PF *handler, + void *client_data, time_t timeout) +{ + int new_events, op; + struct epoll_event ep_event = { 0, { 0 } }; + + if ((type & COMM_SELECT_READ)) + { + F->read_handler = handler; + F->read_data = client_data; + } + + if ((type & COMM_SELECT_WRITE)) + { + F->write_handler = handler; + F->write_data = client_data; + } + + new_events = (F->read_handler ? EPOLLIN : 0) | + (F->write_handler ? EPOLLOUT : 0); + + if (timeout != 0) + F->timeout = CurrentTime + (timeout / 1000); + + if (new_events != F->evcache) + { + if (new_events == 0) + op = EPOLL_CTL_DEL; + else if (F->evcache == 0) + op = EPOLL_CTL_ADD; + else + op = EPOLL_CTL_MOD; + + ep_event.events = F->evcache = new_events; + ep_event.data.fd = F->fd; + + if (epoll_ctl(efd.fd, op, F->fd, &ep_event) != 0) + { + ilog(LOG_TYPE_IRCD, "comm_setselect: epoll_ctl() failed: %s", strerror(errno)); + abort(); + } + } +} + +/* + * comm_select() + * + * Called to do the new-style IO, courtesy of of squid (like most of this + * new IO code). This routine handles the stuff we've hidden in + * comm_setselect and fd_table[] and calls callbacks for IO ready + * events. + */ +void +comm_select(void) +{ + struct epoll_event ep_fdlist[128]; + int num, i; + PF *hdl; + fde_t *F; + + num = epoll_wait(efd.fd, ep_fdlist, 128, SELECT_DELAY); + + set_time(); + + if (num < 0) + { +#ifdef HAVE_USLEEP + usleep(50000); /* avoid 99% CPU in comm_select */ +#endif + return; + } + + for (i = 0; i < num; i++) + { + F = lookup_fd(ep_fdlist[i].data.fd); + if (F == NULL || !F->flags.open) + continue; + + if ((ep_fdlist[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR))) + if ((hdl = F->read_handler) != NULL) + { + F->read_handler = NULL; + hdl(F, F->read_data); + if (!F->flags.open) + continue; + } + + if ((ep_fdlist[i].events & (EPOLLOUT | EPOLLHUP | EPOLLERR))) + if ((hdl = F->write_handler) != NULL) + { + F->write_handler = NULL; + hdl(F, F->write_data); + if (!F->flags.open) + continue; + } + + comm_setselect(F, 0, NULL, NULL, 0); + } +} +#endif diff --git a/src/s_bsd_kqueue.c b/src/s_bsd_kqueue.c new file mode 100644 index 0000000..6571878 --- /dev/null +++ b/src/s_bsd_kqueue.c @@ -0,0 +1,199 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_bsd_kqueue.c: FreeBSD kqueue compatible network routines. + * + * Originally by Adrian Chadd <adrian@creative.net.au> + * Copyright (C) 2005 Hybrid 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 + * + * $Id$ + */ + +#include "stdinc.h" +#if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_KQUEUE +#include <sys/event.h> +#include "fdlist.h" +#include "ircd.h" +#include "memory.h" +#include "s_bsd.h" +#include "log.h" + +#define KE_LENGTH 128 + +/* jlemon goofed up and didn't add EV_SET until fbsd 4.3 */ + +#ifndef EV_SET +#define EV_SET(kevp, a, b, c, d, e, f) do { \ + (kevp)->ident = (a); \ + (kevp)->filter = (b); \ + (kevp)->flags = (c); \ + (kevp)->fflags = (d); \ + (kevp)->data = (e); \ + (kevp)->udata = (f); \ +} while(0) +#endif + +static fde_t kqfd; +static struct kevent kq_fdlist[KE_LENGTH]; /* kevent buffer */ +static int kqoff; /* offset into the buffer */ +void init_netio(void); + +/* + * init_netio + * + * This is a needed exported function which will be called to initialise + * the network loop code. + */ +void +init_netio(void) +{ + int fd; + + if ((fd = kqueue()) < 0) + { + ilog(LOG_TYPE_IRCD, "init_netio: Couldn't open kqueue fd!"); + exit(115); /* Whee! */ + } + + fd_open(&kqfd, fd, 0, "kqueue() file descriptor"); +} + +/* + * Write a single update to the kqueue list. + */ +static void +kq_update_events(int fd, int filter, int what) +{ + static struct timespec zero_timespec = {0, 0}; + struct kevent *kep = kq_fdlist + kqoff; + + EV_SET(kep, (uintptr_t) fd, (short) filter, what, 0, 0, NULL); + + if (++kqoff == KE_LENGTH) + { + kevent(kqfd.fd, kq_fdlist, kqoff, NULL, 0, &zero_timespec); + kqoff = 0; + } +} + +/* + * comm_setselect + * + * This is a needed exported function which will be called to register + * and deregister interest in a pending IO state for a given FD. + */ +void +comm_setselect(fde_t *F, unsigned int type, PF *handler, + void *client_data, time_t timeout) +{ + int new_events, diff; + + if ((type & COMM_SELECT_READ)) + { + F->read_handler = handler; + F->read_data = client_data; + } + + if ((type & COMM_SELECT_WRITE)) + { + F->write_handler = handler; + F->write_data = client_data; + } + + new_events = (F->read_handler ? COMM_SELECT_READ : 0) | + (F->write_handler ? COMM_SELECT_WRITE : 0); + + if (timeout != 0) + F->timeout = CurrentTime + (timeout / 1000); + + diff = new_events ^ F->evcache; + + if ((diff & COMM_SELECT_READ)) + kq_update_events(F->fd, EVFILT_READ, + (new_events & COMM_SELECT_READ) ? EV_ADD : EV_DELETE); + if ((diff & COMM_SELECT_WRITE)) + kq_update_events(F->fd, EVFILT_WRITE, + (new_events & COMM_SELECT_WRITE) ? EV_ADD : EV_DELETE); + + F->evcache = new_events; +} + +/* + * comm_select + * + * Called to do the new-style IO, courtesy of squid (like most of this + * new IO code). This routine handles the stuff we've hidden in + * comm_setselect and fd_table[] and calls callbacks for IO ready + * events. + */ +void +comm_select(void) +{ + int num, i; + static struct kevent ke[KE_LENGTH]; + struct timespec poll_time; + PF *hdl; + fde_t *F; + + /* + * remember we are doing NANOseconds here, not micro/milli. God knows + * why jlemon used a timespec, but hey, he wrote the interface, not I + * -- Adrian + */ + poll_time.tv_sec = 0; + poll_time.tv_nsec = SELECT_DELAY * 1000000; + num = kevent(kqfd.fd, kq_fdlist, kqoff, ke, KE_LENGTH, &poll_time); + kqoff = 0; + + set_time(); + + if (num < 0) + { +#ifdef HAVE_USLEEP + usleep(50000); /* avoid 99% CPU in comm_select */ +#endif + return; + } + + for (i = 0; i < num; i++) + { + F = lookup_fd(ke[i].ident); + if (F == NULL || !F->flags.open || (ke[i].flags & EV_ERROR)) + continue; + + if (ke[i].filter == EVFILT_READ) + if ((hdl = F->read_handler) != NULL) + { + F->read_handler = NULL; + hdl(F, F->read_data); + if (!F->flags.open) + continue; + } + + if (ke[i].filter == EVFILT_WRITE) + if ((hdl = F->write_handler) != NULL) + { + F->write_handler = NULL; + hdl(F, F->write_data); + if (!F->flags.open) + continue; + } + + comm_setselect(F, 0, NULL, NULL, 0); + } +} +#endif diff --git a/src/s_bsd_poll.c b/src/s_bsd_poll.c new file mode 100644 index 0000000..2692da5 --- /dev/null +++ b/src/s_bsd_poll.c @@ -0,0 +1,224 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_bsd_poll.c: POSIX poll() compatible network routines. + * + * Originally by Adrian Chadd <adrian@creative.net.au> + * Copyright (C) 2002 Hybrid 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 + * + * $Id$ + */ + +#include "stdinc.h" +#if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_POLL +#include <sys/poll.h> +#include "fdlist.h" +#include "list.h" +#include "hook.h" +#include "ircd.h" +#include "s_bsd.h" +#include "log.h" + +/* I hate linux -- adrian */ +#ifndef POLLRDNORM +#define POLLRDNORM POLLIN +#endif +#ifndef POLLWRNORM +#define POLLWRNORM POLLOUT +#endif + +static struct pollfd *pollfds; +static int pollmax = -1; /* highest FD number */ +static dlink_node *hookptr; + +/* + * changing_fdlimit + * + * Resize pollfds array if necessary. + */ +static void * +changing_fdlimit(va_list args) +{ + int old_fdlimit = hard_fdlimit; + + pass_callback(hookptr, va_arg(args, int)); + + if (hard_fdlimit != old_fdlimit) + pollfds = MyRealloc(pollfds, sizeof(struct pollfd) * hard_fdlimit); + + return NULL; +} + +/* + * init_netio + * + * This is a needed exported function which will be called to initialise + * the network loop code. + */ +void +init_netio(void) +{ + int fd; + + pollfds = MyMalloc(sizeof(struct pollfd) * hard_fdlimit); + + for (fd = 0; fd < hard_fdlimit; fd++) + pollfds[fd].fd = -1; + + hookptr = install_hook(fdlimit_cb, changing_fdlimit); +} + +/* + * find a spare slot in the fd list. We can optimise this out later! + * -- adrian + */ +static inline int +poll_findslot(void) +{ + int i; + + for (i = 0; i < hard_fdlimit; i++) + if (pollfds[i].fd == -1) + { + /* MATCH!!#$*&$ */ + return i; + } + + assert(1 == 0); + /* NOTREACHED */ + return -1; +} + +/* + * comm_setselect + * + * This is a needed exported function which will be called to register + * and deregister interest in a pending IO state for a given FD. + */ +void +comm_setselect(fde_t *F, unsigned int type, PF *handler, + void *client_data, time_t timeout) +{ + int new_events; + + if ((type & COMM_SELECT_READ)) + { + F->read_handler = handler; + F->read_data = client_data; + } + + if ((type & COMM_SELECT_WRITE)) + { + F->write_handler = handler; + F->write_data = client_data; + } + + new_events = (F->read_handler ? POLLRDNORM : 0) | + (F->write_handler ? POLLWRNORM : 0); + + if (timeout != 0) + F->timeout = CurrentTime + (timeout / 1000); + + if (new_events != F->evcache) + { + if (new_events == 0) + { + pollfds[F->comm_index].fd = -1; + pollfds[F->comm_index].revents = 0; + + if (pollmax == F->comm_index) + while (pollmax >= 0 && pollfds[pollmax].fd == -1) + pollmax--; + } + else + { + if (F->evcache == 0) + { + F->comm_index = poll_findslot(); + if (F->comm_index > pollmax) + pollmax = F->comm_index; + + pollfds[F->comm_index].fd = F->fd; + } + pollfds[F->comm_index].events = new_events; + pollfds[F->comm_index].revents = 0; + } + + F->evcache = new_events; + } +} + +/* + * comm_select + * + * Called to do the new-style IO, courtesy of of squid (like most of this + * new IO code). This routine handles the stuff we've hidden in + * comm_setselect and fd_table[] and calls callbacks for IO ready + * events. + */ +void +comm_select(void) +{ + int num, ci, revents; + PF *hdl; + fde_t *F; + + /* XXX kill that +1 later ! -- adrian */ + num = poll(pollfds, pollmax + 1, SELECT_DELAY); + + set_time(); + + if (num < 0) + { +#ifdef HAVE_USLEEP + usleep(50000); /* avoid 99% CPU in comm_select */ +#endif + return; + } + + for (ci = 0; ci <= pollmax && num > 0; ci++) + { + if ((revents = pollfds[ci].revents) == 0 || pollfds[ci].fd == -1) + continue; + num--; + + F = lookup_fd(pollfds[ci].fd); + if (F == NULL || !F->flags.open) + continue; + + if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) + if ((hdl = F->read_handler) != NULL) + { + F->read_handler = NULL; + hdl(F, F->read_data); + if (!F->flags.open) + continue; + } + + if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) + if ((hdl = F->write_handler) != NULL) + { + F->write_handler = NULL; + hdl(F, F->write_data); + if (!F->flags.open) + continue; + } + + comm_setselect(F, 0, NULL, NULL, 0); + } +} +#endif diff --git a/src/s_bsd_select.c b/src/s_bsd_select.c new file mode 100644 index 0000000..c0b327c --- /dev/null +++ b/src/s_bsd_select.c @@ -0,0 +1,204 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_bsd_select.c: select() compatible network routines. + * + * Originally by Adrian Chadd <adrian@creative.net.au> + * Copyright (C) 2002 Hybrid 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 + * + * $Id$ + */ + +#include "stdinc.h" +#if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_SELECT +#include "list.h" +#include "fdlist.h" +#include "hook.h" +#include "ircd.h" +#include "s_bsd.h" +#include "log.h" + +/* + * Note that this is only a single list - multiple lists is kinda pointless + * under select because the list size is a function of the highest FD :-) + * -- adrian + */ + +static fd_set select_readfds, tmpreadfds; +static fd_set select_writefds, tmpwritefds; +static int highest_fd = -1; +static dlink_node *hookptr; + +/* + * changing_fdlimit + * + * Make sure hard_fdlimit doesn't go too big. + */ +static void * +changing_fdlimit(va_list args) +{ + int fdmax = va_arg(args, int); + + if (fdmax > FD_SETSIZE) + fdmax = FD_SETSIZE; + + return pass_callback(hookptr, fdmax); +} + +/* + * init_netio + * + * This is a needed exported function which will be called to initialise + * the network loop code. + */ +void +init_netio(void) +{ + FD_ZERO(&select_readfds); + FD_ZERO(&select_writefds); + + hookptr = install_hook(fdlimit_cb, changing_fdlimit); +} + +/* + * comm_setselect + * + * This is a needed exported function which will be called to register + * and deregister interest in a pending IO state for a given FD. + */ +void +comm_setselect(fde_t *F, unsigned int type, PF *handler, + void *client_data, time_t timeout) +{ + int new_events; + + if ((type & COMM_SELECT_READ)) + { + F->read_handler = handler; + F->read_data = client_data; + } + + if ((type & COMM_SELECT_WRITE)) + { + F->write_handler = handler; + F->write_data = client_data; + } + + new_events = (F->read_handler ? COMM_SELECT_READ : 0) | + (F->write_handler ? COMM_SELECT_WRITE : 0); + + if (timeout != 0) + F->timeout = CurrentTime + (timeout / 1000); + + if (new_events != F->evcache) + { + if ((new_events & COMM_SELECT_READ)) + FD_SET(F->fd, &select_readfds); + else + { + FD_CLR(F->fd, &select_readfds); + FD_CLR(F->fd, &tmpreadfds); + } + + if ((new_events & COMM_SELECT_WRITE)) + FD_SET(F->fd, &select_writefds); + else + { + FD_CLR(F->fd, &select_writefds); + FD_CLR(F->fd, &tmpwritefds); + } + + if (new_events == 0) + { + if (highest_fd == F->fd) + while (highest_fd >= 0 && (FD_ISSET(highest_fd, &select_readfds) || + FD_ISSET(highest_fd, &select_writefds))) + highest_fd--; + } + else if (F->evcache == 0) + if (F->fd > highest_fd) + highest_fd = F->fd; + + F->evcache = new_events; + } +} + +/* + * comm_select + * + * Called to do the new-style IO, courtesy of squid (like most of this + * new IO code). This routine handles the stuff we've hidden in + * comm_setselect and fd_table[] and calls callbacks for IO ready + * events. + */ +void +comm_select(void) +{ + struct timeval to; + int num, fd; + fde_t *F; + PF *hdl; + + /* Copy over the read/write sets so we don't have to rebuild em */ + memcpy(&tmpreadfds, &select_readfds, sizeof(fd_set)); + memcpy(&tmpwritefds, &select_writefds, sizeof(fd_set)); + + to.tv_sec = 0; + to.tv_usec = SELECT_DELAY * 1000; + num = select(highest_fd + 1, &tmpreadfds, &tmpwritefds, NULL, &to); + + set_time(); + + if (num < 0) + { +#ifdef HAVE_USLEEP + usleep(50000); +#endif + return; + } + + for (fd = 0; fd <= highest_fd && num > 0; fd++) + if (FD_ISSET(fd, &tmpreadfds) || FD_ISSET(fd, &tmpwritefds)) + { + num--; + + F = lookup_fd(fd); + if (F == NULL || !F->flags.open) + continue; + + if (FD_ISSET(fd, &tmpreadfds)) + if ((hdl = F->read_handler) != NULL) + { + F->read_handler = NULL; + hdl(F, F->read_data); + if (!F->flags.open) + continue; + } + + if (FD_ISSET(fd, &tmpwritefds)) + if ((hdl = F->write_handler) != NULL) + { + F->write_handler = NULL; + hdl(F, F->write_data); + if (!F->flags.open) + continue; + } + + comm_setselect(F, 0, NULL, NULL, 0); + } +} +#endif diff --git a/src/s_bsd_sigio.c b/src/s_bsd_sigio.c new file mode 100644 index 0000000..6480393 --- /dev/null +++ b/src/s_bsd_sigio.c @@ -0,0 +1,318 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_bsd_sigio.c: Linux Realtime SIGIO compatible network routines. + * + * Originally by Aaron Sethman <androsyn@ratbox.org> + * based upon: s_bsd_poll.c by Adrian Chadd <adrian@creative.net.au> + * Copyright (C) 2001-2002 Hybrid 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 + * + * $Id$ + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 /* Needed for F_SETSIG */ +#endif + +#include "stdinc.h" +#if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_RTSIGIO +#include <sys/poll.h> +#include "list.h" +#include "fdlist.h" +#include "hook.h" +#include "ircd.h" +#include "s_bsd.h" +#include "log.h" + +#define SIGIO_SIGNAL SIGRTMIN + +static pid_t my_pid; +static sigset_t our_sigset; +static struct pollfd *pollfds; +static int pollmax = -1; /* highest FD number */ +static dlink_node *fdlim_hook, *setupfd_hook; + +/* + * static void mask_our_signal(int s) + * + * Input: None + * Output: None + * Side Effects: Block our signal + */ +static void +mask_our_signal() +{ + sigemptyset(&our_sigset); + sigaddset(&our_sigset, SIGIO_SIGNAL); + sigaddset(&our_sigset, SIGIO); + sigprocmask(SIG_BLOCK, &our_sigset, NULL); +} + +/* + * void setup_sigio_fd(int fd) + * + * Input: File descriptor + * Output: None + * Side Effect: Sets the FD up for SIGIO + */ +static void * +setup_sigio_fd(va_list args) +{ + int fd = va_arg(args, int); + + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_ASYNC); + fcntl(fd, F_SETSIG, SIGIO_SIGNAL); + fcntl(fd, F_SETOWN, my_pid); + + return pass_callback(setupfd_hook, fd); +} + +/* + * changing_fdlimit + * + * Resize pollfds array if necessary. + */ +static void * +changing_fdlimit(va_list args) +{ + int old_fdlimit = hard_fdlimit; + + pass_callback(fdlim_hook, va_arg(args, int)); + + if (hard_fdlimit != old_fdlimit) + pollfds = MyRealloc(pollfds, sizeof(struct pollfd) * hard_fdlimit); + + return NULL; +} + +/* + * void init_netio(void) + * + * Input: None + * Output: None + * Side Effects: This is a needed exported function which will + * be called to initialise the network loop code. + */ +void +init_netio(void) +{ + int fd; + + pollfds = MyMalloc(sizeof(struct pollfd) * hard_fdlimit); + + for (fd = 0; fd < hard_fdlimit; fd++) + pollfds[fd].fd = -1; + + setupfd_hook = install_hook(setup_socket_cb, setup_sigio_fd); + fdlim_hook = install_hook(fdlimit_cb, changing_fdlimit); + + my_pid = getpid(); + mask_our_signal(SIGIO_SIGNAL); +} + +/* + * find a spare slot in the fd list. We can optimise this out later! + * -- adrian + */ +static inline int +poll_findslot(void) +{ + int i; + + for (i = 0; i < hard_fdlimit; i++) + { + if (pollfds[i].fd == -1) + { + /* MATCH!!#$*&$ */ + return i; + } + } + + assert(1 == 0); + /* NOTREACHED */ + return -1; +} + +/* + * comm_setselect + * + * This is a needed exported function which will be called to register + * and deregister interest in a pending IO state for a given FD. + */ +void +comm_setselect(fde_t *F, unsigned int type, PF *handler, + void *client_data, time_t timeout) +{ + int new_events; + + if ((type & COMM_SELECT_READ)) + { + F->read_handler = handler; + F->read_data = client_data; + } + + if ((type & COMM_SELECT_WRITE)) + { + F->write_handler = handler; + F->write_data = client_data; + } + + new_events = (F->read_handler ? POLLRDNORM : 0) | + (F->write_handler ? POLLWRNORM : 0); + + if (timeout != 0) + F->timeout = CurrentTime + (timeout / 1000); + + if (new_events != F->evcache) + { + if (new_events == 0) + { + pollfds[F->comm_index].fd = -1; + pollfds[F->comm_index].revents = 0; + + if (pollmax == F->comm_index) + while (pollmax >= 0 && pollfds[pollmax].fd == -1) + pollmax--; + } + else + { + if (F->evcache == 0) + { + F->comm_index = poll_findslot(); + if (F->comm_index > pollmax) + pollmax = F->comm_index; + + pollfds[F->comm_index].fd = F->fd; + } + pollfds[F->comm_index].events = new_events; + pollfds[F->comm_index].revents = 0; + } + + F->evcache = new_events; + } +} + +/* + * comm_select + * + * Called to do the new-style IO, courtesy of squid (like most of this + * new IO code). This routine handles the stuff we've hidden in + * comm_setselect and fd_table[] and calls callbacks for IO ready + * events. + */ +void +comm_select(void) +{ + static time_t last_rtsigqo_warning = 0; + struct timespec timeout; + struct siginfo si; + int i, revents, num; + fde_t *F; + PF *hdl; + + timeout.tv_sec = 0; + timeout.tv_nsec = 1000000 * SELECT_DELAY; + i = sigtimedwait(&our_sigset, &si, &timeout); + + set_time(); + + if (i != SIGIO) + { + if (i > 0) + { + F = lookup_fd(si.si_fd); + if (F == NULL || !F->flags.open) + return; + + if (si.si_band & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) + if ((hdl = F->read_handler) != NULL) + { + F->read_handler = NULL; + hdl(F, F->read_data); + if (!F->flags.open) + return; + } + + if (si.si_band & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) + if ((hdl = F->write_handler) != NULL) + { + F->write_handler = NULL; + hdl(F, F->write_data); + if (!F->flags.open) + return; + } + + comm_setselect(F, 0, NULL, NULL, 0); + } + + return; + } + + /* RT signal queue overflowed.. */ + + if (CurrentTime - last_rtsigqo_warning >= 30) + { + ilog(LOG_TYPE_IRCD, "Kernel RT Signal queue overflowed. " + "Is /proc/sys/kernel/rtsig-max too small?"); + last_rtsigqo_warning = CurrentTime; + } + + signal(SIGIO_SIGNAL, SIG_IGN); + signal(SIGIO_SIGNAL, SIG_DFL); + + /* ..try polling instead */ + + while ((num = poll(pollfds, pollmax + 1, 0)) < 0 && ignoreErrno(errno)) + ; + + /* update current time again, eww.. */ + set_time(); + + for (i = 0; i <= pollmax && num > 0; i++) + { + if ((revents = pollfds[i].revents) == 0 || pollfds[i].fd == -1) + continue; + num--; + + F = lookup_fd(pollfds[i].fd); + if (F == NULL || !F->flags.open) + continue; + + if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) + if ((hdl = F->read_handler) != NULL) + { + F->read_handler = NULL; + hdl(F, F->read_data); + if (!F->flags.open) + continue; + } + + if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) + if ((hdl = F->write_handler) != NULL) + { + F->write_handler = NULL; + hdl(F, F->write_data); + if (!F->flags.open) + continue; + } + + comm_setselect(F, 0, NULL, NULL, 0); + } + + mask_our_signal(SIGIO_SIGNAL); +} +#endif diff --git a/src/s_gline.c b/src/s_gline.c new file mode 100644 index 0000000..aff7a05 --- /dev/null +++ b/src/s_gline.c @@ -0,0 +1,114 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_gline.c: GLine global ban functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "client.h" +#include "irc_string.h" +#include "ircd.h" +#include "hostmask.h" +#include "conf.h" +#include "s_misc.h" +#include "send.h" +#include "s_serv.h" +#include "s_gline.h" +#include "event.h" +#include "memory.h" + +dlink_list pending_glines[GLINE_PENDING_ADD_TYPE + 1] = { { NULL, NULL, 0 }, + { NULL, NULL, 0 } }; + +static void expire_pending_glines(struct gline_pending *); + + +struct AccessItem * +find_is_glined(const char *host, const char *user) +{ + struct irc_ssaddr iphost, *piphost; + struct AccessItem *aconf; + int t; + + if ((t = parse_netmask(host, &iphost, &t)) != HM_HOST) + { +#ifdef IPV6 + if (t == HM_IPV6) + t = AF_INET6; + else +#endif + t = AF_INET; + piphost = &iphost; + } + else + { + t = 0; + piphost = NULL; + } + + aconf = find_conf_by_address(host, piphost, CONF_GLINE, t, user, NULL, 0); + return aconf; +} + +/* cleanup_glines() + * + * inputs - NONE + * output - NONE + * side effects - expire gline lists + * This is an event started off in ircd.c + */ +void +cleanup_glines(void *unused) +{ + expire_pending_glines(unused); +} + +/* expire_pending_glines() + * + * inputs - NONE + * output - NONE + * side effects - + * + * Go through the pending gline list, expire any that haven't had + * enough "votes" in the time period allowed + */ +static void +expire_pending_glines(struct gline_pending *in) +{ + dlink_node *ptr = NULL, *next_ptr = NULL; + unsigned int idx = 0; + + for (; idx < GLINE_PENDING_ADD_TYPE + 1; ++idx) + { + DLINK_FOREACH_SAFE(ptr, next_ptr, pending_glines[idx].head) + { + struct gline_pending *glp_ptr = ptr->data; + + if ((glp_ptr->last_gline_time + ConfigFileEntry.gline_request_time) <= CurrentTime || + glp_ptr == in) + { + dlinkDelete(&glp_ptr->node, &pending_glines[idx]); + MyFree(glp_ptr); + } + } + } +} diff --git a/src/s_misc.c b/src/s_misc.c new file mode 100644 index 0000000..1b6166b --- /dev/null +++ b/src/s_misc.c @@ -0,0 +1,131 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_misc.c: Yet another miscellaneous functions file. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "s_misc.h" +#include "client.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "irc_res.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "conf.h" +#include "s_serv.h" +#include "send.h" +#include "memory.h" + + +static const char *months[] = +{ + "January", "February", "March", "April", + "May", "June", "July", "August", + "September", "October", "November","December" +}; + +static const char *weekdays[] = +{ + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" +}; + +char * +date(time_t lclock) +{ + static char buf[80], plus; + struct tm *lt, *gm; + struct tm gmbuf; + int minswest; + + if (!lclock) + lclock = CurrentTime; + gm = gmtime(&lclock); + memcpy(&gmbuf, gm, sizeof(gmbuf)); + gm = &gmbuf; + lt = localtime(&lclock); + + /* + * There is unfortunately no clean portable way to extract time zone + * offset information, so do ugly things. + */ + minswest = (gm->tm_hour - lt->tm_hour) * 60 + (gm->tm_min - lt->tm_min); + + if (lt->tm_yday != gm->tm_yday) + { + if ((lt->tm_yday > gm->tm_yday && lt->tm_year == gm->tm_year) || + (lt->tm_yday < gm->tm_yday && lt->tm_year != gm->tm_year)) + minswest -= 24 * 60; + else + minswest += 24 * 60; + } + + plus = (minswest > 0) ? '-' : '+'; + if (minswest < 0) + minswest = -minswest; + + snprintf(buf, sizeof(buf), "%s %s %d %d -- %02u:%02u:%02u %c%02u:%02u", + weekdays[lt->tm_wday], months[lt->tm_mon],lt->tm_mday, + lt->tm_year + 1900, lt->tm_hour, lt->tm_min, lt->tm_sec, + plus, minswest/60, minswest%60); + return buf; +} + +const char * +smalldate(time_t lclock) +{ + static char buf[MAX_DATE_STRING]; + struct tm *lt, *gm; + struct tm gmbuf; + + if (!lclock) + lclock = CurrentTime; + + gm = gmtime(&lclock); + memcpy(&gmbuf, gm, sizeof(gmbuf)); + gm = &gmbuf; + lt = localtime(&lclock); + + snprintf(buf, sizeof(buf), "%d/%d/%d %02d.%02d", + lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, + lt->tm_hour, lt->tm_min); + + return buf; +} + +#ifdef HAVE_LIBCRYPTO +char * +ssl_get_cipher(const SSL *ssl) +{ + static char buffer[IRCD_BUFSIZE / 4]; + int bits = 0; + + SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl), &bits); + + snprintf(buffer, sizeof(buffer), "%s %s-%d", SSL_get_version(ssl), + SSL_get_cipher(ssl), bits); + + return buffer; +} +#endif diff --git a/src/s_serv.c b/src/s_serv.c new file mode 100644 index 0000000..4d7dcd6 --- /dev/null +++ b/src/s_serv.c @@ -0,0 +1,1503 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_serv.c: Server related functions. + * + * Copyright (C) 2005 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#ifdef HAVE_LIBCRYPTO +#include <openssl/rsa.h> +#include "rsa.h" +#endif +#include "list.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "dbuf.h" +#include "event.h" +#include "fdlist.h" +#include "hash.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "ircd_defs.h" +#include "s_bsd.h" +#include "numeric.h" +#include "packet.h" +#include "irc_res.h" +#include "conf.h" +#include "s_serv.h" +#include "log.h" +#include "s_misc.h" +#include "s_user.h" +#include "send.h" +#include "memory.h" +#include "channel.h" /* chcap_usage_counts stuff...*/ +#include "parse.h" + +#define MIN_CONN_FREQ 300 + +static dlink_list cap_list = { NULL, NULL, 0 }; +static void server_burst(struct Client *); +static void burst_all(struct Client *); +static void send_tb(struct Client *client_p, struct Channel *chptr); + +static CNCB serv_connect_callback; + +static void burst_members(struct Client *, struct Channel *); + +/* + * write_links_file + * + * inputs - void pointer which is not used + * output - NONE + * side effects - called from an event, write out list of linked servers + * but in no particular order. + */ +void +write_links_file(void* notused) +{ + MessageFileLine *next_mptr = NULL; + MessageFileLine *mptr = NULL; + MessageFileLine *currentMessageLine = NULL; + MessageFileLine *newMessageLine = NULL; + MessageFile *MessageFileptr = &ConfigFileEntry.linksfile; + FILE *file; + char buff[512]; + dlink_node *ptr; + + if ((file = fopen(MessageFileptr->fileName, "w")) == NULL) + return; + + for (mptr = MessageFileptr->contentsOfFile; mptr; mptr = next_mptr) + { + next_mptr = mptr->next; + MyFree(mptr); + } + + MessageFileptr->contentsOfFile = NULL; + + DLINK_FOREACH(ptr, global_serv_list.head) + { + const struct Client *target_p = ptr->data; + + /* skip ourselves, we send ourselves in /links */ + if (IsMe(target_p)) + continue; + + /* skip hidden servers */ + if (IsHidden(target_p)) + continue; + + newMessageLine = MyMalloc(sizeof(MessageFileLine)); + + /* + * Attempt to format the file in such a way it follows the usual links output + * ie "servername uplink :hops info" + * Mostly for aesthetic reasons - makes it look pretty in mIRC ;) + * - madmax + */ + snprintf(newMessageLine->line, sizeof(newMessageLine->line), "%s %s :1 %s", + target_p->name, me.name, target_p->info); + + if (MessageFileptr->contentsOfFile) + { + if (currentMessageLine) + currentMessageLine->next = newMessageLine; + currentMessageLine = newMessageLine; + } + else + { + MessageFileptr->contentsOfFile = newMessageLine; + currentMessageLine = newMessageLine; + } + + snprintf(buff, sizeof(buff), "%s %s :1 %s\n", + target_p->name, me.name, target_p->info); + fputs(buff, file); + } + + fclose(file); +} + +/* hunt_server() + * Do the basic thing in delivering the message (command) + * across the relays to the specific server (server) for + * actions. + * + * Note: The command is a format string and *MUST* be + * of prefixed style (e.g. ":%s COMMAND %s ..."). + * Command can have only max 8 parameters. + * + * server parv[server] is the parameter identifying the + * target server. + * + * *WARNING* + * parv[server] is replaced with the pointer to the + * real servername from the matched client (I'm lazy + * now --msa). + * + * returns: (see #defines) + */ +int +hunt_server(struct Client *client_p, struct Client *source_p, const char *command, + int server, int parc, char *parv[]) +{ + struct Client *target_p = NULL; + struct Client *target_tmp = NULL; + dlink_node *ptr; + int wilds; + + /* Assume it's me, if no server */ + if (parc <= server || EmptyString(parv[server])) + return HUNTED_ISME; + + if (!strcmp(parv[server], me.id) || match(parv[server], me.name)) + return HUNTED_ISME; + + /* These are to pickup matches that would cause the following + * message to go in the wrong direction while doing quick fast + * non-matching lookups. + */ + if (MyClient(source_p)) + target_p = hash_find_client(parv[server]); + else + target_p = find_person(client_p, parv[server]); + + if (target_p) + if (target_p->from == source_p->from && !MyConnect(target_p)) + target_p = NULL; + + if (target_p == NULL && (target_p = hash_find_server(parv[server]))) + if (target_p->from == source_p->from && !MyConnect(target_p)) + target_p = NULL; + + collapse(parv[server]); + wilds = has_wildcards(parv[server]); + + /* Again, if there are no wild cards involved in the server + * name, use the hash lookup + */ + if (target_p == NULL) + { + if (!wilds) + { + if (!(target_p = hash_find_server(parv[server]))) + { + sendto_one(source_p, form_str(ERR_NOSUCHSERVER), + me.name, source_p->name, parv[server]); + return(HUNTED_NOSUCH); + } + } + else + { + DLINK_FOREACH(ptr, global_client_list.head) + { + target_tmp = ptr->data; + + if (match(parv[server], target_tmp->name)) + { + if (target_tmp->from == source_p->from && !MyConnect(target_tmp)) + continue; + target_p = ptr->data; + + if (IsRegistered(target_p) && (target_p != client_p)) + break; + } + } + } + } + + if (target_p != NULL) + { + if(!IsRegistered(target_p)) + { + sendto_one(source_p, form_str(ERR_NOSUCHSERVER), + me.name, source_p->name, parv[server]); + return HUNTED_NOSUCH; + } + + if (IsMe(target_p) || MyClient(target_p)) + return HUNTED_ISME; + + if (!match(target_p->name, parv[server])) + parv[server] = target_p->name; + + /* This is a little kludgy but should work... */ + if (IsClient(source_p) && + ((MyConnect(target_p) && IsCapable(target_p, CAP_TS6)) || + (!MyConnect(target_p) && IsCapable(target_p->from, CAP_TS6)))) + parv[0] = ID(source_p); + + sendto_one(target_p, command, parv[0], + parv[1], parv[2], parv[3], parv[4], + parv[5], parv[6], parv[7], parv[8]); + return(HUNTED_PASS); + } + + sendto_one(source_p, form_str(ERR_NOSUCHSERVER), + me.name, source_p->name, parv[server]); + return(HUNTED_NOSUCH); +} + +/* try_connections() + * + * inputs - void pointer which is not used + * output - NONE + * side effects - + * scan through configuration and try new connections. + * Returns the calendar time when the next call to this + * function should be made latest. (No harm done if this + * is called earlier or later...) + */ +void +try_connections(void *unused) +{ + dlink_node *ptr; + struct ConfItem *conf; + struct AccessItem *aconf; + struct ClassItem *cltmp; + int confrq; + + /* TODO: change this to set active flag to 0 when added to event! --Habeeb */ + if (GlobalSetOptions.autoconn == 0) + return; + + DLINK_FOREACH(ptr, server_items.head) + { + conf = ptr->data; + aconf = map_to_conf(conf); + + /* Also when already connecting! (update holdtimes) --SRB + */ + if (!(aconf->status & CONF_SERVER) || !aconf->port || + !(IsConfAllowAutoConn(aconf))) + continue; + + cltmp = map_to_conf(aconf->class_ptr); + + /* Skip this entry if the use of it is still on hold until + * future. Otherwise handle this entry (and set it on hold + * until next time). Will reset only hold times, if already + * made one successfull connection... [this algorithm is + * a bit fuzzy... -- msa >;) ] + */ + if (aconf->hold > CurrentTime) + continue; + + if (cltmp == NULL) + confrq = DEFAULT_CONNECTFREQUENCY; + else + { + confrq = cltmp->con_freq; + if (confrq < MIN_CONN_FREQ) + confrq = MIN_CONN_FREQ; + } + + aconf->hold = CurrentTime + confrq; + + /* Found a CONNECT config with port specified, scan clients + * and see if this server is already connected? + */ + if (hash_find_server(conf->name) != NULL) + continue; + + if (cltmp->curr_user_count < cltmp->max_total) + { + /* Go to the end of the list, if not already last */ + if (ptr->next != NULL) + { + dlinkDelete(ptr, &server_items); + dlinkAddTail(conf, &conf->node, &server_items); + } + + if (find_servconn_in_progress(conf->name)) + return; + + /* We used to only print this if serv_connect() actually + * succeeded, but since comm_tcp_connect() can call the callback + * immediately if there is an error, we were getting error messages + * in the wrong order. SO, we just print out the activated line, + * and let serv_connect() / serv_connect_callback() print an + * error afterwards if it fails. + * -- adrian + */ + if (ConfigServerHide.hide_server_ips) + sendto_realops_flags(UMODE_ALL, L_ALL, "Connection to %s activated.", + conf->name); + else + sendto_realops_flags(UMODE_ALL, L_ALL, "Connection to %s[%s] activated.", + conf->name, aconf->host); + + serv_connect(aconf, NULL); + /* We connect only one at time... */ + return; + } + } +} + +int +valid_servname(const char *name) +{ + unsigned int length = 0; + unsigned int dots = 0; + const char *p = name; + + for (; *p; ++p) + { + if (!IsServChar(*p)) + return 0; + + ++length; + + if (*p == '.') + ++dots; + } + + return dots != 0 && length <= HOSTLEN; +} + +int +check_server(const char *name, struct Client *client_p) +{ + dlink_node *ptr; + struct ConfItem *conf = NULL; + struct ConfItem *server_conf = NULL; + struct AccessItem *server_aconf = NULL; + struct AccessItem *aconf = NULL; + int error = -1; + + assert(client_p != NULL); + + /* loop through looking for all possible connect items that might work */ + DLINK_FOREACH(ptr, server_items.head) + { + conf = ptr->data; + aconf = map_to_conf(conf); + + if (!match(name, conf->name)) + continue; + + error = -3; + + /* XXX: Fix me for IPv6 */ + /* XXX sockhost is the IPv4 ip as a string */ + if (match(aconf->host, client_p->host) || + match(aconf->host, client_p->sockhost)) + { + error = -2; + + if (!match_conf_password(client_p->localClient->passwd, aconf)) + return -2; + + server_conf = conf; + } + } + + if (server_conf == NULL) + return(error); + + attach_conf(client_p, server_conf); + + server_aconf = map_to_conf(server_conf); + + if (aconf != NULL) + { + struct sockaddr_in *v4; +#ifdef IPV6 + struct sockaddr_in6 *v6; +#endif + switch (aconf->aftype) + { +#ifdef IPV6 + case AF_INET6: + v6 = (struct sockaddr_in6 *)&aconf->addr; + + if (IN6_IS_ADDR_UNSPECIFIED(&v6->sin6_addr)) + memcpy(&aconf->addr, &client_p->localClient->ip, sizeof(struct irc_ssaddr)); + break; +#endif + case AF_INET: + v4 = (struct sockaddr_in *)&aconf->addr; + + if (v4->sin_addr.s_addr == INADDR_NONE) + memcpy(&aconf->addr, &client_p->localClient->ip, sizeof(struct irc_ssaddr)); + break; + } + } + + return(0); +} + +/* add_capability() + * + * inputs - string name of CAPAB + * - int flag of capability + * output - NONE + * side effects - Adds given capability name and bit mask to + * current supported capabilities. This allows + * modules to dynamically add or subtract their capability. + */ +void +add_capability(const char *capab_name, int cap_flag, int add_to_default) +{ + struct Capability *cap = MyMalloc(sizeof(*cap)); + + DupString(cap->name, capab_name); + cap->cap = cap_flag; + dlinkAdd(cap, &cap->node, &cap_list); + + if (add_to_default) + default_server_capabs |= cap_flag; +} + +/* delete_capability() + * + * inputs - string name of CAPAB + * output - NONE + * side effects - delete given capability from ones known. + */ +int +delete_capability(const char *capab_name) +{ + dlink_node *ptr; + dlink_node *next_ptr; + struct Capability *cap; + + DLINK_FOREACH_SAFE(ptr, next_ptr, cap_list.head) + { + cap = ptr->data; + + if (cap->cap != 0) + { + if (irccmp(cap->name, capab_name) == 0) + { + default_server_capabs &= ~(cap->cap); + dlinkDelete(ptr, &cap_list); + MyFree(cap->name); + cap->name = NULL; + MyFree(cap); + } + } + } + + return 0; +} + +/* + * find_capability() + * + * inputs - string name of capab to find + * output - 0 if not found CAPAB otherwise + * side effects - none + */ +int +find_capability(const char *capab) +{ + const dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, cap_list.head) + { + const struct Capability *cap = ptr->data; + + if (cap->cap && !irccmp(cap->name, capab)) + return cap->cap; + } + + return 0; +} + +/* send_capabilities() + * + * inputs - Client pointer to send to + * - Pointer to AccessItem (for crypt) + * - int flag of capabilities that this server can send + * output - NONE + * side effects - send the CAPAB line to a server -orabidoo + * + */ +void +send_capabilities(struct Client *client_p, struct AccessItem *aconf, + int cap_can_send) +{ + struct Capability *cap=NULL; + char msgbuf[IRCD_BUFSIZE]; + char *t; + int tl; + dlink_node *ptr; + + t = msgbuf; + + DLINK_FOREACH(ptr, cap_list.head) + { + cap = ptr->data; + + if (cap->cap & (cap_can_send|default_server_capabs)) + { + tl = ircsprintf(t, "%s ", cap->name); + t += tl; + } + } + + *(t - 1) = '\0'; + sendto_one(client_p, "CAPAB :%s", msgbuf); +} + +/* sendnick_TS() + * + * inputs - client (server) to send nick towards + * - client to send nick for + * output - NONE + * side effects - NICK message is sent towards given client_p + */ +void +sendnick_TS(struct Client *client_p, struct Client *target_p) +{ + static char ubuf[12]; + + if (!IsClient(target_p)) + return; + + send_umode(NULL, target_p, 0, SEND_UMODES, ubuf); + + if (ubuf[0] == '\0') + { + ubuf[0] = '+'; + ubuf[1] = '\0'; + } + + if (IsCapable(client_p, CAP_SVS)) + { + if (HasID(target_p) && IsCapable(client_p, CAP_TS6)) + sendto_one(client_p, ":%s UID %s %d %lu %s %s %s %s %s %s :%s", + target_p->servptr->id, + target_p->name, target_p->hopcount + 1, + (unsigned long) target_p->tsinfo, + ubuf, target_p->username, target_p->host, + (MyClient(target_p) && IsIPSpoof(target_p)) ? + "0" : target_p->sockhost, target_p->id, + target_p->svid, target_p->info); + else + sendto_one(client_p, "NICK %s %d %lu %s %s %s %s %s :%s", + target_p->name, target_p->hopcount + 1, + (unsigned long) target_p->tsinfo, + ubuf, target_p->username, target_p->host, + target_p->servptr->name, target_p->svid, + target_p->info); + } + else + { + if (HasID(target_p) && IsCapable(client_p, CAP_TS6)) + sendto_one(client_p, ":%s UID %s %d %lu %s %s %s %s %s :%s", + target_p->servptr->id, + target_p->name, target_p->hopcount + 1, + (unsigned long) target_p->tsinfo, + ubuf, target_p->username, target_p->host, + (MyClient(target_p) && IsIPSpoof(target_p)) ? + "0" : target_p->sockhost, target_p->id, target_p->info); + else + sendto_one(client_p, "NICK %s %d %lu %s %s %s %s :%s", + target_p->name, target_p->hopcount + 1, + (unsigned long) target_p->tsinfo, + ubuf, target_p->username, target_p->host, + target_p->servptr->name, target_p->info); + } + + if (target_p->away[0]) + sendto_one(client_p, ":%s AWAY :%s", ID_or_name(target_p, client_p), + target_p->away); + +} + +/* + * show_capabilities - show current server capabilities + * + * inputs - pointer to a struct Client + * output - pointer to static string + * side effects - build up string representing capabilities of server listed + */ +const char * +show_capabilities(struct Client *target_p) +{ + static char msgbuf[IRCD_BUFSIZE]; + char *t = msgbuf; + dlink_node *ptr; + + t += ircsprintf(msgbuf, "TS "); + + DLINK_FOREACH(ptr, cap_list.head) + { + const struct Capability *cap = ptr->data; + + if (IsCapable(target_p, cap->cap)) + t += ircsprintf(t, "%s ", cap->name); + } + + *(t - 1) = '\0'; + return msgbuf; +} + +/* make_server() + * + * inputs - pointer to client struct + * output - pointer to struct Server + * side effects - add's an Server information block to a client + * if it was not previously allocated. + */ +struct Server * +make_server(struct Client *client_p) +{ + if (client_p->serv == NULL) + client_p->serv = MyMalloc(sizeof(struct Server)); + + return client_p->serv; +} + +/* server_estab() + * + * inputs - pointer to a struct Client + * output - + * side effects - + */ +void +server_estab(struct Client *client_p) +{ + struct Client *target_p; + struct ConfItem *conf; + struct AccessItem *aconf=NULL; + char *host; + const char *inpath; + static char inpath_ip[HOSTLEN * 2 + USERLEN + 6]; + dlink_node *ptr; +#ifdef HAVE_LIBCRYPTO + const COMP_METHOD *compression = NULL, *expansion = NULL; +#endif + + assert(client_p != NULL); + + strlcpy(inpath_ip, get_client_name(client_p, SHOW_IP), sizeof(inpath_ip)); + + inpath = get_client_name(client_p, MASK_IP); /* "refresh" inpath with host */ + host = client_p->name; + + if ((conf = find_conf_name(&client_p->localClient->confs, host, SERVER_TYPE)) + == NULL) + { + /* This shouldn't happen, better tell the ops... -A1kmm */ + sendto_realops_flags(UMODE_ALL, L_ALL, "Warning: Lost connect{} block " + "for server %s(this shouldn't happen)!", host); + exit_client(client_p, &me, "Lost connect{} block!"); + return; + } + + MyFree(client_p->localClient->passwd); + client_p->localClient->passwd = NULL; + + /* Its got identd, since its a server */ + SetGotId(client_p); + + /* If there is something in the serv_list, it might be this + * connecting server.. + */ + if (!ServerInfo.hub && serv_list.head) + { + if (client_p != serv_list.head->data || serv_list.head->next) + { + ++ServerStats.is_ref; + sendto_one(client_p, "ERROR :I'm a leaf not a hub"); + exit_client(client_p, &me, "I'm a leaf"); + return; + } + } + + aconf = map_to_conf(conf); + + if (IsUnknown(client_p)) + { + /* jdc -- 1. Use EmptyString(), not [0] index reference. + * 2. Check aconf->spasswd, not aconf->passwd. + */ + if (!EmptyString(aconf->spasswd)) + sendto_one(client_p, "PASS %s TS %d %s", + aconf->spasswd, TS_CURRENT, me.id); + + /* Pass my info to the new server + * + * Pass on ZIP if supported + * Pass on TB if supported. + * - Dianora + */ + + send_capabilities(client_p, aconf, 0); + + sendto_one(client_p, "SERVER %s 1 :%s%s", + me.name, ConfigServerHide.hidden ? "(H) " : "", me.info); + } + + sendto_one(client_p, "SVINFO %d %d 0 :%lu", TS_CURRENT, TS_MIN, + (unsigned long)CurrentTime); + + /* assumption here is if they passed the correct TS version, they also passed an SID */ + if (IsCapable(client_p, CAP_TS6)) + hash_add_id(client_p); + + /* XXX Does this ever happen? I don't think so -db */ + detach_conf(client_p, OPER_TYPE); + + /* *WARNING* + ** In the following code in place of plain server's + ** name we send what is returned by get_client_name + ** which may add the "sockhost" after the name. It's + ** *very* *important* that there is a SPACE between + ** the name and sockhost (if present). The receiving + ** server will start the information field from this + ** first blank and thus puts the sockhost into info. + ** ...a bit tricky, but you have been warned, besides + ** code is more neat this way... --msa + */ + client_p->servptr = &me; + + if (IsClosing(client_p)) + return; + + SetServer(client_p); + + /* Update the capability combination usage counts. -A1kmm */ + set_chcap_usage_counts(client_p); + + /* Some day, all these lists will be consolidated *sigh* */ + dlinkAdd(client_p, &client_p->lnode, &me.serv->server_list); + + assert(dlinkFind(&unknown_list, client_p)); + + dlink_move_node(&client_p->localClient->lclient_node, + &unknown_list, &serv_list); + + Count.myserver++; + + dlinkAdd(client_p, make_dlink_node(), &global_serv_list); + hash_add_client(client_p); + + /* doesnt duplicate client_p->serv if allocated this struct already */ + make_server(client_p); + + /* fixing eob timings.. -gnp */ + client_p->localClient->firsttime = CurrentTime; + + if (find_matching_name_conf(SERVICE_TYPE, client_p->name, NULL, NULL, 0)) + AddFlag(client_p, FLAGS_SERVICE); + + /* Show the real host/IP to admins */ +#ifdef HAVE_LIBCRYPTO + if (client_p->localClient->fd.ssl) + { + compression = SSL_get_current_compression(client_p->localClient->fd.ssl); + expansion = SSL_get_current_expansion(client_p->localClient->fd.ssl); + + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Link with %s established: [SSL: %s, Compression/Expansion method: %s/%s] (Capabilities: %s)", + inpath_ip, ssl_get_cipher(client_p->localClient->fd.ssl), + compression ? SSL_COMP_get_name(compression) : "NONE", + expansion ? SSL_COMP_get_name(expansion) : "NONE", + show_capabilities(client_p)); + /* Now show the masked hostname/IP to opers */ + sendto_realops_flags(UMODE_ALL, L_OPER, + "Link with %s established: [SSL: %s, Compression/Expansion method: %s/%s] (Capabilities: %s)", + inpath, ssl_get_cipher(client_p->localClient->fd.ssl), + compression ? SSL_COMP_get_name(compression) : "NONE", + expansion ? SSL_COMP_get_name(expansion) : "NONE", + show_capabilities(client_p)); + ilog(LOG_TYPE_IRCD, "Link with %s established: [SSL: %s, Compression/Expansion method: %s/%s] (Capabilities: %s)", + inpath_ip, ssl_get_cipher(client_p->localClient->fd.ssl), + compression ? SSL_COMP_get_name(compression) : "NONE", + expansion ? SSL_COMP_get_name(expansion) : "NONE", + show_capabilities(client_p)); + } + else +#endif + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Link with %s established: (Capabilities: %s)", + inpath_ip,show_capabilities(client_p)); + /* Now show the masked hostname/IP to opers */ + sendto_realops_flags(UMODE_ALL, L_OPER, + "Link with %s established: (Capabilities: %s)", + inpath,show_capabilities(client_p)); + ilog(LOG_TYPE_IRCD, "Link with %s established: (Capabilities: %s)", + inpath_ip, show_capabilities(client_p)); + } + + fd_note(&client_p->localClient->fd, "Server: %s", client_p->name); + + /* Old sendto_serv_but_one() call removed because we now + ** need to send different names to different servers + ** (domain name matching) Send new server to other servers. + */ + DLINK_FOREACH(ptr, serv_list.head) + { + target_p = ptr->data; + + if (target_p == client_p) + continue; + + if (IsCapable(target_p, CAP_TS6) && HasID(client_p)) + sendto_one(target_p, ":%s SID %s 2 %s :%s%s", + me.id, client_p->name, client_p->id, + IsHidden(client_p) ? "(H) " : "", + client_p->info); + else + sendto_one(target_p,":%s SERVER %s 2 :%s%s", + me.name, client_p->name, + IsHidden(client_p) ? "(H) " : "", + client_p->info); + } + + /* Pass on my client information to the new server + ** + ** First, pass only servers (idea is that if the link gets + ** cancelled beacause the server was already there, + ** there are no NICK's to be cancelled...). Of course, + ** if cancellation occurs, all this info is sent anyway, + ** and I guess the link dies when a read is attempted...? --msa + ** + ** Note: Link cancellation to occur at this point means + ** that at least two servers from my fragment are building + ** up connection this other fragment at the same time, it's + ** a race condition, not the normal way of operation... + ** + ** ALSO NOTE: using the get_client_name for server names-- + ** see previous *WARNING*!!! (Also, original inpath + ** is destroyed...) + */ + + DLINK_FOREACH_PREV(ptr, global_serv_list.tail) + { + target_p = ptr->data; + + /* target_p->from == target_p for target_p == client_p */ + if (IsMe(target_p) || target_p->from == client_p) + continue; + + if (IsCapable(client_p, CAP_TS6)) + { + if (HasID(target_p)) + sendto_one(client_p, ":%s SID %s %d %s :%s%s", + ID(target_p->servptr), target_p->name, target_p->hopcount+1, + target_p->id, IsHidden(target_p) ? "(H) " : "", + target_p->info); + else /* introducing non-ts6 server */ + sendto_one(client_p, ":%s SERVER %s %d :%s%s", + ID(target_p->servptr), target_p->name, target_p->hopcount+1, + IsHidden(target_p) ? "(H) " : "", target_p->info); + } + else + sendto_one(client_p, ":%s SERVER %s %d :%s%s", + target_p->servptr->name, target_p->name, target_p->hopcount+1, + IsHidden(target_p) ? "(H) " : "", target_p->info); + } + + server_burst(client_p); +} + +/* server_burst() + * + * inputs - struct Client pointer server + * - + * output - none + * side effects - send a server burst + * bugs - still too long + */ +static void +server_burst(struct Client *client_p) +{ + /* Send it in the shortened format with the TS, if + ** it's a TS server; walk the list of channels, sending + ** all the nicks that haven't been sent yet for each + ** channel, then send the channel itself -- it's less + ** obvious than sending all nicks first, but on the + ** receiving side memory will be allocated more nicely + ** saving a few seconds in the handling of a split + ** -orabidoo + */ + + burst_all(client_p); + + /* EOB stuff is now in burst_all */ + /* Always send a PING after connect burst is done */ + sendto_one(client_p, "PING :%s", ID_or_name(&me, client_p)); +} + +/* burst_all() + * + * inputs - pointer to server to send burst to + * output - NONE + * side effects - complete burst of channels/nicks is sent to client_p + */ +static void +burst_all(struct Client *client_p) +{ + dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, global_channel_list.head) + { + struct Channel *chptr = ptr->data; + + if (dlink_list_length(&chptr->members) != 0) + { + burst_members(client_p, chptr); + send_channel_modes(client_p, chptr); + + if (IsCapable(client_p, CAP_TBURST)) + send_tb(client_p, chptr); + } + } + + /* also send out those that are not on any channel + */ + DLINK_FOREACH(ptr, global_client_list.head) + { + struct Client *target_p = ptr->data; + + if (!HasFlag(target_p, FLAGS_BURSTED) && target_p->from != client_p) + sendnick_TS(client_p, target_p); + + DelFlag(target_p, FLAGS_BURSTED); + } + + /* We send the time we started the burst, and let the remote host determine an EOB time, + ** as otherwise we end up sending a EOB of 0 Sending here means it gets sent last -- fl + */ + /* Its simpler to just send EOB and use the time its been connected.. --fl_ */ + if (IsCapable(client_p, CAP_EOB)) + sendto_one(client_p, ":%s EOB", ID_or_name(&me, client_p)); +} + +/* + * send_tb + * + * inputs - pointer to Client + * - pointer to channel + * output - NONE + * side effects - Called on a server burst when + * server is CAP_TBURST capable + */ +static void +send_tb(struct Client *client_p, struct Channel *chptr) +{ + /* + * We may also send an empty topic here, but only if topic_time isn't 0, + * i.e. if we had a topic that got unset. This is required for syncing + * topics properly. + * + * Imagine the following scenario: Our downlink introduces a channel + * to us with a TS that is equal to ours, but the channel topic on + * their side got unset while the servers were in splitmode, which means + * their 'topic' is newer. They simply wanted to unset it, so we have to + * deal with it in a more sophisticated fashion instead of just resetting + * it to their old topic they had before. Read m_tburst.c:ms_tburst + * for further information -Michael + */ + if (chptr->topic_time != 0) + sendto_one(client_p, ":%s TBURST %lu %s %lu %s :%s", + ID_or_name(&me, client_p), + (unsigned long)chptr->channelts, chptr->chname, + (unsigned long)chptr->topic_time, + chptr->topic_info, + chptr->topic); +} + +/* burst_members() + * + * inputs - pointer to server to send members to + * - dlink_list pointer to membership list to send + * output - NONE + * side effects - + */ +static void +burst_members(struct Client *client_p, struct Channel *chptr) +{ + struct Client *target_p; + struct Membership *ms; + dlink_node *ptr; + + DLINK_FOREACH(ptr, chptr->members.head) + { + ms = ptr->data; + target_p = ms->client_p; + + if (!HasFlag(target_p, FLAGS_BURSTED)) + { + AddFlag(target_p, FLAGS_BURSTED); + + if (target_p->from != client_p) + sendnick_TS(client_p, target_p); + } + } +} + +/* New server connection code + * Based upon the stuff floating about in s_bsd.c + * -- adrian + */ + +/* serv_connect() - initiate a server connection + * + * inputs - pointer to conf + * - pointer to client doing the connect + * output - + * side effects - + * + * This code initiates a connection to a server. It first checks to make + * sure the given server exists. If this is the case, it creates a socket, + * creates a client, saves the socket information in the client, and + * initiates a connection to the server through comm_connect_tcp(). The + * completion of this goes through serv_completed_connection(). + * + * We return 1 if the connection is attempted, since we don't know whether + * it suceeded or not, and 0 if it fails in here somewhere. + */ +int +serv_connect(struct AccessItem *aconf, struct Client *by) +{ + struct ConfItem *conf; + struct Client *client_p; + char buf[HOSTIPLEN + 1]; + + /* conversion structs */ + struct sockaddr_in *v4; + /* Make sure aconf is useful */ + assert(aconf != NULL); + + /* XXX should be passing struct ConfItem in the first place */ + conf = unmap_conf_item(aconf); + + /* log */ + getnameinfo((struct sockaddr *)&aconf->addr, aconf->addr.ss_len, + buf, sizeof(buf), NULL, 0, NI_NUMERICHOST); + ilog(LOG_TYPE_IRCD, "Connect to %s[%s] @%s", conf->name, aconf->host, + buf); + + /* Still processing a DNS lookup? -> exit */ + if (aconf->dns_pending) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "Error connecting to %s: DNS lookup for connect{} in progress.", + conf->name); + return (0); + } + + if (aconf->dns_failed) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "Error connecting to %s: DNS lookup for connect{} failed.", + conf->name); + return (0); + } + + /* Make sure this server isn't already connected + * Note: aconf should ALWAYS be a valid C: line + */ + if ((client_p = hash_find_server(conf->name)) != NULL) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Server %s already present from %s", + conf->name, get_client_name(client_p, SHOW_IP)); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Server %s already present from %s", + conf->name, get_client_name(client_p, MASK_IP)); + if (by && IsClient(by) && !MyClient(by)) + sendto_one(by, ":%s NOTICE %s :Server %s already present from %s", + me.name, by->name, conf->name, + get_client_name(client_p, MASK_IP)); + return (0); + } + + /* Create a local client */ + client_p = make_client(NULL); + + /* Copy in the server, hostname, fd */ + strlcpy(client_p->name, conf->name, sizeof(client_p->name)); + strlcpy(client_p->host, aconf->host, sizeof(client_p->host)); + + /* We already converted the ip once, so lets use it - stu */ + strlcpy(client_p->sockhost, buf, sizeof(client_p->sockhost)); + + /* create a socket for the server connection */ + if (comm_open(&client_p->localClient->fd, aconf->addr.ss.ss_family, + SOCK_STREAM, 0, NULL) < 0) + { + /* Eek, failure to create the socket */ + report_error(L_ALL, + "opening stream socket to %s: %s", conf->name, errno); + SetDead(client_p); + exit_client(client_p, &me, "Connection failed"); + return (0); + } + + /* servernames are always guaranteed under HOSTLEN chars */ + fd_note(&client_p->localClient->fd, "Server: %s", conf->name); + + /* Attach config entries to client here rather than in + * serv_connect_callback(). This to avoid null pointer references. + */ + if (!attach_connect_block(client_p, conf->name, aconf->host)) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "Host %s is not enabled for connecting:no C/N-line", + conf->name); + if (by && IsClient(by) && !MyClient(by)) + sendto_one(by, ":%s NOTICE %s :Connect to host %s failed.", + me.name, by->name, client_p->name); + SetDead(client_p); + exit_client(client_p, client_p, "Connection failed"); + return (0); + } + + /* at this point we have a connection in progress and C/N lines + * attached to the client, the socket info should be saved in the + * client and it should either be resolved or have a valid address. + * + * The socket has been connected or connect is in progress. + */ + make_server(client_p); + + if (by && IsClient(by)) + strlcpy(client_p->serv->by, by->name, sizeof(client_p->serv->by)); + else + strlcpy(client_p->serv->by, "AutoConn.", sizeof(client_p->serv->by)); + + SetConnecting(client_p); + dlinkAdd(client_p, &client_p->node, &global_client_list); + /* from def_fam */ + client_p->localClient->aftype = aconf->aftype; + + /* Now, initiate the connection */ + /* XXX assume that a non 0 type means a specific bind address + * for this connect. + */ + switch (aconf->aftype) + { + case AF_INET: + v4 = (struct sockaddr_in*)&aconf->bind; + if (v4->sin_addr.s_addr != 0) + { + struct irc_ssaddr ipn; + memset(&ipn, 0, sizeof(struct irc_ssaddr)); + ipn.ss.ss_family = AF_INET; + ipn.ss_port = 0; + memcpy(&ipn, &aconf->bind, sizeof(struct irc_ssaddr)); + comm_connect_tcp(&client_p->localClient->fd, aconf->host, aconf->port, + (struct sockaddr *)&ipn, ipn.ss_len, + serv_connect_callback, client_p, aconf->aftype, + CONNECTTIMEOUT); + } + else if (ServerInfo.specific_ipv4_vhost) + { + struct irc_ssaddr ipn; + memset(&ipn, 0, sizeof(struct irc_ssaddr)); + ipn.ss.ss_family = AF_INET; + ipn.ss_port = 0; + memcpy(&ipn, &ServerInfo.ip, sizeof(struct irc_ssaddr)); + comm_connect_tcp(&client_p->localClient->fd, aconf->host, aconf->port, + (struct sockaddr *)&ipn, ipn.ss_len, + serv_connect_callback, client_p, aconf->aftype, + CONNECTTIMEOUT); + } + else + comm_connect_tcp(&client_p->localClient->fd, aconf->host, aconf->port, + NULL, 0, serv_connect_callback, client_p, aconf->aftype, + CONNECTTIMEOUT); + break; +#ifdef IPV6 + case AF_INET6: + { + struct irc_ssaddr ipn; + struct sockaddr_in6 *v6; + struct sockaddr_in6 *v6conf; + + memset(&ipn, 0, sizeof(struct irc_ssaddr)); + v6conf = (struct sockaddr_in6 *)&aconf->bind; + v6 = (struct sockaddr_in6 *)&ipn; + + if (memcmp(&v6conf->sin6_addr, &v6->sin6_addr, + sizeof(struct in6_addr)) != 0) + { + memcpy(&ipn, &aconf->bind, sizeof(struct irc_ssaddr)); + ipn.ss.ss_family = AF_INET6; + ipn.ss_port = 0; + comm_connect_tcp(&client_p->localClient->fd, + aconf->host, aconf->port, + (struct sockaddr *)&ipn, ipn.ss_len, + serv_connect_callback, client_p, + aconf->aftype, CONNECTTIMEOUT); + } + else if (ServerInfo.specific_ipv6_vhost) + { + memcpy(&ipn, &ServerInfo.ip6, sizeof(struct irc_ssaddr)); + ipn.ss.ss_family = AF_INET6; + ipn.ss_port = 0; + comm_connect_tcp(&client_p->localClient->fd, + aconf->host, aconf->port, + (struct sockaddr *)&ipn, ipn.ss_len, + serv_connect_callback, client_p, + aconf->aftype, CONNECTTIMEOUT); + } + else + comm_connect_tcp(&client_p->localClient->fd, + aconf->host, aconf->port, + NULL, 0, serv_connect_callback, client_p, + aconf->aftype, CONNECTTIMEOUT); + } +#endif + } + return (1); +} + +#ifdef HAVE_LIBCRYPTO +static void +finish_ssl_server_handshake(struct Client *client_p) +{ + struct ConfItem *conf=NULL; + struct AccessItem *aconf=NULL; + + conf = find_conf_name(&client_p->localClient->confs, + client_p->name, SERVER_TYPE); + if (conf == NULL) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Lost connect{} block for %s", get_client_name(client_p, HIDE_IP)); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Lost connect{} block for %s", get_client_name(client_p, MASK_IP)); + + exit_client(client_p, &me, "Lost connect{} block"); + return; + } + + aconf = map_to_conf(conf); + + /* jdc -- Check and send spasswd, not passwd. */ + if (!EmptyString(aconf->spasswd)) + sendto_one(client_p, "PASS %s TS %d %s", + aconf->spasswd, TS_CURRENT, me.id); + + send_capabilities(client_p, aconf, 0); + + sendto_one(client_p, "SERVER %s 1 :%s%s", + me.name, ConfigServerHide.hidden ? "(H) " : "", + me.info); + + /* If we've been marked dead because a send failed, just exit + * here now and save everyone the trouble of us ever existing. + */ + if (IsDead(client_p)) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "%s[%s] went dead during handshake", + client_p->name, + client_p->host); + sendto_realops_flags(UMODE_ALL, L_OPER, + "%s went dead during handshake", client_p->name); + return; + } + + /* don't move to serv_list yet -- we haven't sent a burst! */ + /* If we get here, we're ok, so lets start reading some data */ + comm_setselect(&client_p->localClient->fd, COMM_SELECT_READ, read_packet, client_p, 0); +} + +static void +ssl_server_handshake(fde_t *fd, struct Client *client_p) +{ + int ret; + int err; + + ret = SSL_connect(client_p->localClient->fd.ssl); + + if (ret <= 0) + { + switch ((err = SSL_get_error(client_p->localClient->fd.ssl, ret))) + { + case SSL_ERROR_WANT_WRITE: + comm_setselect(&client_p->localClient->fd, COMM_SELECT_WRITE, + (PF *)ssl_server_handshake, client_p, 0); + return; + case SSL_ERROR_WANT_READ: + comm_setselect(&client_p->localClient->fd, COMM_SELECT_READ, + (PF *)ssl_server_handshake, client_p, 0); + return; + default: + { + const char *sslerr = ERR_error_string(ERR_get_error(), NULL); + sendto_realops_flags(UMODE_ALL, L_ALL, + "Error connecting to %s: %s", client_p->name, + sslerr ? sslerr : "unknown SSL error"); + exit_client(client_p, client_p, "Error during SSL handshake"); + return; + } + } + } + + finish_ssl_server_handshake(client_p); +} + +static void +ssl_connect_init(struct Client *client_p, struct AccessItem *aconf, fde_t *fd) +{ + if ((client_p->localClient->fd.ssl = SSL_new(ServerInfo.client_ctx)) == NULL) + { + ilog(LOG_TYPE_IRCD, "SSL_new() ERROR! -- %s", + ERR_error_string(ERR_get_error(), NULL)); + SetDead(client_p); + exit_client(client_p, client_p, "SSL_new failed"); + return; + } + + SSL_set_fd(fd->ssl, fd->fd); + + if (!EmptyString(aconf->cipher_list)) + SSL_set_cipher_list(client_p->localClient->fd.ssl, aconf->cipher_list); + + ssl_server_handshake(NULL, client_p); +} +#endif + +/* serv_connect_callback() - complete a server connection. + * + * This routine is called after the server connection attempt has + * completed. If unsucessful, an error is sent to ops and the client + * is closed. If sucessful, it goes through the initialisation/check + * procedures, the capabilities are sent, and the socket is then + * marked for reading. + */ +static void +serv_connect_callback(fde_t *fd, int status, void *data) +{ + struct Client *client_p = data; + struct ConfItem *conf=NULL; + struct AccessItem *aconf=NULL; + + /* First, make sure its a real client! */ + assert(client_p != NULL); + assert(&client_p->localClient->fd == fd); + + /* Next, for backward purposes, record the ip of the server */ + memcpy(&client_p->localClient->ip, &fd->connect.hostaddr, + sizeof(struct irc_ssaddr)); + /* Check the status */ + if (status != COMM_OK) + { + /* We have an error, so report it and quit + * Admins get to see any IP, mere opers don't *sigh* + */ + if (ConfigServerHide.hide_server_ips) + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Error connecting to %s: %s", + client_p->name, comm_errstr(status)); + else + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Error connecting to %s[%s]: %s", client_p->name, + client_p->host, comm_errstr(status)); + + sendto_realops_flags(UMODE_ALL, L_OPER, + "Error connecting to %s: %s", + client_p->name, comm_errstr(status)); + + /* If a fd goes bad, call dead_link() the socket is no + * longer valid for reading or writing. + */ + dead_link_on_write(client_p, 0); + return; + } + + /* COMM_OK, so continue the connection procedure */ + /* Get the C/N lines */ + conf = find_conf_name(&client_p->localClient->confs, + client_p->name, SERVER_TYPE); + if (conf == NULL) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "Lost connect{} block for %s", get_client_name(client_p, HIDE_IP)); + sendto_realops_flags(UMODE_ALL, L_OPER, + "Lost connect{} block for %s", get_client_name(client_p, MASK_IP)); + + exit_client(client_p, &me, "Lost connect{} block"); + return; + } + + aconf = map_to_conf(conf); + /* Next, send the initial handshake */ + SetHandshake(client_p); + +#ifdef HAVE_LIBCRYPTO + if (IsConfSSL(aconf)) + { + ssl_connect_init(client_p, aconf, fd); + return; + } +#endif + + /* jdc -- Check and send spasswd, not passwd. */ + if (!EmptyString(aconf->spasswd)) + sendto_one(client_p, "PASS %s TS %d %s", + aconf->spasswd, TS_CURRENT, me.id); + + send_capabilities(client_p, aconf, 0); + + sendto_one(client_p, "SERVER %s 1 :%s%s", + me.name, ConfigServerHide.hidden ? "(H) " : "", + me.info); + + /* If we've been marked dead because a send failed, just exit + * here now and save everyone the trouble of us ever existing. + */ + if (IsDead(client_p)) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, + "%s[%s] went dead during handshake", + client_p->name, + client_p->host); + sendto_realops_flags(UMODE_ALL, L_OPER, + "%s went dead during handshake", client_p->name); + return; + } + + /* don't move to serv_list yet -- we haven't sent a burst! */ + /* If we get here, we're ok, so lets start reading some data */ + comm_setselect(fd, COMM_SELECT_READ, read_packet, client_p, 0); +} + +struct Client * +find_servconn_in_progress(const char *name) +{ + dlink_node *ptr; + struct Client *cptr; + + DLINK_FOREACH(ptr, unknown_list.head) + { + cptr = ptr->data; + + if (cptr && cptr->name[0]) + if (match(name, cptr->name)) + return cptr; + } + + return NULL; +} diff --git a/src/s_user.c b/src/s_user.c new file mode 100644 index 0000000..1973bfa --- /dev/null +++ b/src/s_user.c @@ -0,0 +1,1484 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * s_user.c: User related functions. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "s_user.h" +#include "s_misc.h" +#include "channel.h" +#include "channel_mode.h" +#include "client.h" +#include "fdlist.h" +#include "hash.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "s_bsd.h" +#include "ircd.h" +#include "listener.h" +#include "motd.h" +#include "numeric.h" +#include "conf.h" +#include "log.h" +#include "s_serv.h" +#include "send.h" +#include "supported.h" +#include "whowas.h" +#include "memory.h" +#include "packet.h" +#include "rng_mt.h" +#include "userhost.h" +#include "hook.h" +#include "s_misc.h" +#include "parse.h" +#include "watch.h" + + +struct Callback *entering_umode_cb = NULL; +struct Callback *umode_cb = NULL; + +static char umode_buffer[IRCD_BUFSIZE]; + +static void user_welcome(struct Client *); +static void report_and_set_user_flags(struct Client *, const struct AccessItem *); +static int check_xline(struct Client *); +static void introduce_client(struct Client *); +static const char *uid_get(void); + +/* Used for building up the isupport string, + * used with init_isupport, add_isupport, delete_isupport + */ + +struct Isupport +{ + dlink_node node; + char *name; + char *options; + int number; +}; + +static dlink_list support_list = { NULL, NULL, 0 }; +MessageFile *isupportFile; + +/* memory is cheap. map 0-255 to equivalent mode */ +unsigned int user_modes[256] = +{ + /* 0x00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x0F */ + /* 0x10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1F */ + /* 0x20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x2F */ + /* 0x30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x3F */ + 0, /* @ */ + 0, /* A */ + 0, /* B */ + UMODE_CCONN_FULL, /* C */ + UMODE_DEAF, /* D */ + 0, /* E */ + 0, /* F */ + UMODE_SOFTCALLERID, /* G */ + UMODE_HIDDEN, /* H */ + 0, /* I */ + 0, /* J */ + 0, /* K */ + 0, /* L */ + 0, /* M */ + 0, /* N */ + 0, /* O */ + 0, /* P */ + 0, /* Q */ + UMODE_REGONLY, /* R */ + 0, /* S */ + 0, /* T */ + 0, /* U */ + 0, /* V */ + 0, /* W */ + 0, /* X */ + 0, /* Y */ + 0, /* Z 0x5A */ + 0, 0, 0, 0, 0, /* 0x5F */ + 0, /* 0x60 */ + UMODE_ADMIN, /* a */ + UMODE_BOTS, /* b */ + UMODE_CCONN, /* c */ + UMODE_DEBUG, /* d */ + 0, /* e */ + UMODE_FULL, /* f */ + UMODE_CALLERID, /* g */ + 0, /* h */ + UMODE_INVISIBLE, /* i */ + UMODE_REJ, /* j */ + UMODE_SKILL, /* k */ + UMODE_LOCOPS, /* l */ + 0, /* m */ + UMODE_NCHANGE, /* n */ + UMODE_OPER, /* o */ + 0, /* p */ + 0, /* q */ + UMODE_REGISTERED, /* r */ + UMODE_SERVNOTICE, /* s */ + 0, /* t */ + UMODE_UNAUTH, /* u */ + 0, /* v */ + UMODE_WALLOP, /* w */ + UMODE_EXTERNAL, /* x */ + UMODE_SPY, /* y */ + UMODE_OPERWALL, /* z 0x7A */ + 0,0,0,0,0, /* 0x7B - 0x7F */ + + /* 0x80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x8F */ + /* 0x90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x9F */ + /* 0xA0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xAF */ + /* 0xB0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xBF */ + /* 0xC0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xCF */ + /* 0xD0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xDF */ + /* 0xE0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xEF */ + /* 0xF0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 0xFF */ +}; + +void +assemble_umode_buffer(void) +{ + unsigned int idx = 0; + char *umode_buffer_ptr = umode_buffer; + + for (; idx < (sizeof(user_modes) / sizeof(user_modes[0])); ++idx) + if (user_modes[idx]) + *umode_buffer_ptr++ = idx; + + *umode_buffer_ptr = '\0'; +} + +/* show_lusers() + * + * inputs - pointer to client + * output - NONE + * side effects - display to client user counts etc. + */ +void +show_lusers(struct Client *source_p) +{ + const char *from, *to; + + if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p)) + { + from = me.id; + to = source_p->id; + } + else + { + from = me.name; + to = source_p->name; + } + + if (!ConfigServerHide.hide_servers || HasUMode(source_p, UMODE_OPER)) + sendto_one(source_p, form_str(RPL_LUSERCLIENT), + from, to, (Count.total-Count.invisi), + Count.invisi, dlink_list_length(&global_serv_list)); + else + sendto_one(source_p, form_str(RPL_LUSERCLIENT), from, to, + (Count.total-Count.invisi), Count.invisi, 1); + + if (Count.oper > 0) + sendto_one(source_p, form_str(RPL_LUSEROP), + from, to, Count.oper); + + if (dlink_list_length(&unknown_list) > 0) + sendto_one(source_p, form_str(RPL_LUSERUNKNOWN), + from, to, dlink_list_length(&unknown_list)); + + if (dlink_list_length(&global_channel_list) > 0) + sendto_one(source_p, form_str(RPL_LUSERCHANNELS), + from, to, dlink_list_length(&global_channel_list)); + + if (!ConfigServerHide.hide_servers || HasUMode(source_p, UMODE_OPER)) + { + sendto_one(source_p, form_str(RPL_LUSERME), + from, to, Count.local, Count.myserver); + sendto_one(source_p, form_str(RPL_LOCALUSERS), + from, to, Count.local, Count.max_loc, + Count.local, Count.max_loc); + } + else + { + sendto_one(source_p, form_str(RPL_LUSERME), + from, to, Count.total, 0); + sendto_one(source_p, form_str(RPL_LOCALUSERS), + from, to, Count.total, Count.max_tot, + Count.total, Count.max_tot); + } + + sendto_one(source_p, form_str(RPL_GLOBALUSERS), + from, to, Count.total, Count.max_tot, + Count.total, Count.max_tot); + + if (!ConfigServerHide.hide_servers || HasUMode(source_p, UMODE_OPER)) + sendto_one(source_p, form_str(RPL_STATSCONN), from, to, + Count.max_loc_con, Count.max_loc_cli, Count.totalrestartcount); + + if (Count.local > Count.max_loc_cli) + Count.max_loc_cli = Count.local; + + if ((Count.local + Count.myserver) > Count.max_loc_con) + Count.max_loc_con = Count.local + Count.myserver; +} + +/* show_isupport() + * + * inputs - pointer to client + * output - NONE + * side effects - display to client what we support (for them) + */ +void +show_isupport(struct Client *source_p) +{ + send_message_file(source_p, isupportFile); +} + +/* +** register_local_user +** This function is called when both NICK and USER messages +** have been accepted for the client, in whatever order. Only +** after this, is the USER message propagated. +** +** NICK's must be propagated at once when received, although +** it would be better to delay them too until full info is +** available. Doing it is not so simple though, would have +** to implement the following: +** +** (actually it has been implemented already for a while) -orabidoo +** +** 1) user telnets in and gives only "NICK foobar" and waits +** 2) another user far away logs in normally with the nick +** "foobar" (quite legal, as this server didn't propagate +** it). +** 3) now this server gets nick "foobar" from outside, but +** has alread the same defined locally. Current server +** would just issue "KILL foobar" to clean out dups. But, +** this is not fair. It should actually request another +** nick from local user or kill him/her... +*/ +void +register_local_user(struct Client *source_p) +{ + const char *id = NULL; + const struct AccessItem *aconf = NULL; + dlink_node *ptr = NULL; + + assert(source_p != NULL); + assert(source_p == source_p->from); + assert(MyConnect(source_p)); + assert(!source_p->localClient->registration); + + ClearCap(source_p, CAP_TS6); + + if (ConfigFileEntry.ping_cookie) + { + if (!IsPingSent(source_p) && source_p->localClient->random_ping == 0) + { + do + source_p->localClient->random_ping = genrand_int32(); + while (!source_p->localClient->random_ping); + + sendto_one(source_p, "PING :%u", + source_p->localClient->random_ping); + SetPingSent(source_p); + return; + } + + if (!HasPingCookie(source_p)) + return; + } + + source_p->localClient->last_privmsg = CurrentTime; + /* Straight up the maximum rate of flooding... */ + source_p->localClient->allow_read = MAX_FLOOD_BURST; + + if (!execute_callback(client_check_cb, source_p, source_p->username)) + return; + + if (valid_hostname(source_p->host) == 0) + { + sendto_one(source_p, ":%s NOTICE %s :*** Notice -- You have an illegal " + "character in your hostname", me.name, source_p->name); + strlcpy(source_p->host, source_p->sockhost, + sizeof(source_p->host)); + } + + ptr = source_p->localClient->confs.head; + aconf = map_to_conf(ptr->data); + + if (!IsGotId(source_p)) + { + char username[USERLEN + 1]; + const char *p = username; + unsigned int i = 0; + + if (IsNeedIdentd(aconf)) + { + ++ServerStats.is_ref; + sendto_one(source_p, ":%s NOTICE %s :*** Notice -- You need to install " + "identd to use this server", me.name, source_p->name); + exit_client(source_p, &me, "Install identd"); + return; + } + + strlcpy(username, source_p->username, sizeof(username)); + + if (!IsNoTilde(aconf)) + source_p->username[i++] = '~'; + + for (; *p && i < USERLEN; ++p) + if (*p != '[') + source_p->username[i++] = *p; + + source_p->username[i] = '\0'; + } + + /* password check */ + if (!EmptyString(aconf->passwd)) + { + const char *pass = source_p->localClient->passwd; + + if (!match_conf_password(pass, aconf)) + { + ++ServerStats.is_ref; + sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), + me.name, source_p->name); + exit_client(source_p, &me, "Bad Password"); + return; + } + } + + /* don't free source_p->localClient->passwd here - it can be required + * by masked /stats I if there are auth{} blocks with need_password = no; + * --adx + */ + + /* report if user has &^>= etc. and set flags as needed in source_p */ + report_and_set_user_flags(source_p, aconf); + + if (IsDead(source_p)) + return; + + /* Limit clients - + * We want to be able to have servers and F-line clients + * connect, so save room for "buffer" connections. + * Smaller servers may want to decrease this, and it should + * probably be just a percentage of the MAXCLIENTS... + * -Taner + */ + /* Except "F:" clients */ + if ((Count.local >= ServerInfo.max_clients + MAX_BUFFER) || + (Count.local >= ServerInfo.max_clients && !IsExemptLimits(source_p))) + { + sendto_realops_flags(UMODE_FULL, L_ALL, + "Too many clients, rejecting %s[%s].", + source_p->name, source_p->host); + ++ServerStats.is_ref; + exit_client(source_p, &me, "Sorry, server is full - try later"); + return; + } + + /* valid user name check */ + if (valid_username(source_p->username) == 0) + { + char tmpstr2[IRCD_BUFSIZE]; + + sendto_realops_flags(UMODE_REJ, L_ALL, "Invalid username: %s (%s@%s)", + source_p->name, source_p->username, source_p->host); + ++ServerStats.is_ref; + snprintf(tmpstr2, sizeof(tmpstr2), "Invalid username [%s]", + source_p->username); + exit_client(source_p, &me, tmpstr2); + return; + } + + if (check_xline(source_p)) + return; + + while (hash_find_id((id = uid_get())) != NULL) + ; + + strlcpy(source_p->id, id, sizeof(source_p->id)); + hash_add_id(source_p); + + sendto_realops_flags(UMODE_CCONN, L_ALL, + "Client connecting: %s (%s@%s) [%s] {%s} [%s] <%s>", + source_p->name, source_p->username, source_p->host, + ConfigFileEntry.hide_spoof_ips && IsIPSpoof(source_p) ? + "255.255.255.255" : source_p->sockhost, + get_client_class(source_p), + source_p->info, source_p->id); + + sendto_realops_flags(UMODE_CCONN_FULL, L_ALL, + "CLICONN %s %s %s %s %s %s %s 0 %s", + source_p->name, source_p->username, source_p->host, + ConfigFileEntry.hide_spoof_ips && IsIPSpoof(source_p) ? + "255.255.255.255" : source_p->sockhost, + get_client_class(source_p), + ConfigFileEntry.hide_spoof_ips && IsIPSpoof(source_p) ? + "<hidden>" : source_p->localClient->client_host, + ConfigFileEntry.hide_spoof_ips && IsIPSpoof(source_p) ? + "<hidden>" : source_p->localClient->client_server, + source_p->info); + + + if (ConfigFileEntry.invisible_on_connect) + { + AddUMode(source_p, UMODE_INVISIBLE); + ++Count.invisi; + } + + if ((++Count.local) > Count.max_loc) + { + Count.max_loc = Count.local; + + if (!(Count.max_loc % 10)) + sendto_realops_flags(UMODE_ALL, L_ALL, "New Max Local Clients: %d", + Count.max_loc); + } + + /* Increment our total user count here */ + if (++Count.total > Count.max_tot) + Count.max_tot = Count.total; + ++Count.totalrestartcount; + + assert(source_p->servptr == &me); + SetClient(source_p); + dlinkAdd(source_p, &source_p->lnode, &source_p->servptr->serv->client_list); + + source_p->localClient->allow_read = MAX_FLOOD_BURST; + + assert(dlinkFind(&unknown_list, source_p)); + + dlink_move_node(&source_p->localClient->lclient_node, + &unknown_list, &local_client_list); + + user_welcome(source_p); + add_user_host(source_p->username, source_p->host, 0); + SetUserHost(source_p); + + introduce_client(source_p); +} + +/* register_remote_user() + * + * inputs - source_p remote or directly connected client + * - username to register as + * - host name to register as + * - server name + * - realname (gecos) + * output - NONE + * side effects - This function is called when a remote client + * is introduced by a server. + */ +void +register_remote_user(struct Client *source_p, + const char *username, const char *host, const char *server, + const char *realname) +{ + struct Client *target_p = NULL; + + assert(source_p != NULL); + assert(source_p->username != username); + + strlcpy(source_p->host, host, sizeof(source_p->host)); + strlcpy(source_p->username, username, sizeof(source_p->username)); + + /* + * coming from another server, take the servers word for it + */ + source_p->servptr = hash_find_server(server); + + /* Super GhostDetect: + * If we can't find the server the user is supposed to be on, + * then simply blow the user away. -Taner + */ + if (source_p->servptr == NULL) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "No server %s for user %s[%s@%s] from %s", + server, source_p->name, source_p->username, + source_p->host, source_p->from->name); + kill_client(source_p->from, source_p, "%s (Server doesn't exist)", me.name); + + AddFlag(source_p, FLAGS_KILLED); + exit_client(source_p, &me, "Ghosted Client"); + return; + } + + if ((target_p = source_p->servptr) && target_p->from != source_p->from) + { + sendto_realops_flags(UMODE_DEBUG, L_ALL, + "Bad User [%s] :%s USER %s@%s %s, != %s[%s]", + source_p->from->name, source_p->name, source_p->username, + source_p->host, source_p->servptr->name, + target_p->name, target_p->from->name); + kill_client(source_p->from, source_p, + "%s (NICK from wrong direction (%s != %s))", + me.name, source_p->servptr->name, target_p->from->name); + AddFlag(source_p, FLAGS_KILLED); + exit_client(source_p, &me, "USER server wrong direction"); + return; + } + + /* + * If the nick has been introduced by a services server, + * make it a service as well. + */ + if (HasFlag(source_p->servptr, FLAGS_SERVICE)) + AddFlag(source_p, FLAGS_SERVICE); + + /* Increment our total user count here */ + if (++Count.total > Count.max_tot) + Count.max_tot = Count.total; + + SetClient(source_p); + dlinkAdd(source_p, &source_p->lnode, &source_p->servptr->serv->client_list); + add_user_host(source_p->username, source_p->host, 1); + SetUserHost(source_p); + + introduce_client(source_p); +} + +/* introduce_client() + * + * inputs - source_p + * output - NONE + * side effects - This common function introduces a client to the rest + * of the net, either from a local client connect or + * from a remote connect. + */ +static void +introduce_client(struct Client *source_p) +{ + dlink_node *server_node = NULL; + static char ubuf[12]; + + if (MyClient(source_p)) + send_umode(source_p, source_p, 0, SEND_UMODES, ubuf); + else + send_umode(NULL, source_p, 0, SEND_UMODES, ubuf); + + watch_check_hash(source_p, RPL_LOGON); + + if (*ubuf == '\0') + { + ubuf[0] = '+'; + ubuf[1] = '\0'; + } + + DLINK_FOREACH(server_node, serv_list.head) + { + struct Client *server = server_node->data; + + if (server == source_p->from) + continue; + + if (IsCapable(server, CAP_SVS)) + { + if (IsCapable(server, CAP_TS6) && HasID(source_p)) + sendto_one(server, ":%s UID %s %d %lu %s %s %s %s %s %s :%s", + source_p->servptr->id, + source_p->name, source_p->hopcount+1, + (unsigned long)source_p->tsinfo, + ubuf, source_p->username, source_p->host, + (MyClient(source_p) && IsIPSpoof(source_p)) ? + "0" : source_p->sockhost, source_p->id, + source_p->svid, + source_p->info); + else + sendto_one(server, "NICK %s %d %lu %s %s %s %s %s :%s", + source_p->name, source_p->hopcount+1, + (unsigned long)source_p->tsinfo, + ubuf, source_p->username, source_p->host, + source_p->servptr->name, source_p->svid, + source_p->info); + + } + else + { + if (IsCapable(server, CAP_TS6) && HasID(source_p)) + sendto_one(server, ":%s UID %s %d %lu %s %s %s %s %s :%s", + source_p->servptr->id, + source_p->name, source_p->hopcount+1, + (unsigned long)source_p->tsinfo, + ubuf, source_p->username, source_p->host, + (MyClient(source_p) && IsIPSpoof(source_p)) ? + "0" : source_p->sockhost, source_p->id, source_p->info); + else + sendto_one(server, "NICK %s %d %lu %s %s %s %s :%s", + source_p->name, source_p->hopcount+1, + (unsigned long)source_p->tsinfo, + ubuf, source_p->username, source_p->host, + source_p->servptr->name, source_p->info); + } + } +} + +/* valid_hostname() + * + * Inputs - pointer to hostname + * Output - 1 if valid, 0 if not + * Side effects - check hostname for validity + * + * NOTE: this doesn't allow a hostname to begin with a dot and + * will not allow more dots than chars. + */ +int +valid_hostname(const char *hostname) +{ + const char *p = hostname; + + assert(p != NULL); + + if (*p == '.' || *p == ':') + return 0; + + for (; *p; ++p) + if (!IsHostChar(*p)) + return 0; + + return 1; +} + +/* valid_username() + * + * Inputs - pointer to user + * Output - 1 if valid, 0 if not + * Side effects - check username for validity + * + * Absolutely always reject any '*' '!' '?' '@' in an user name + * reject any odd control characters names. + * Allow '.' in username to allow for "first.last" + * style of username + */ +int +valid_username(const char *username) +{ + int dots = 0; + const char *p = username; + + assert(p != NULL); + + if (*p == '~') + ++p; + + /* reject usernames that don't start with an alphanum + * i.e. reject jokers who have '-@somehost' or '.@somehost' + * or "-hi-@somehost", "h-----@somehost" would still be accepted. + */ + if (!IsAlNum(*p)) + return 0; + + while (*++p) + { + if ((*p == '.') && ConfigFileEntry.dots_in_ident) + { + if (++dots > ConfigFileEntry.dots_in_ident) + return 0; + if (!IsUserChar(*(p + 1))) + return 0; + } + else if (!IsUserChar(*p)) + return 0; + } + + return 1; +} + +/* clean_nick_name() + * + * input - nickname + * - whether it's a local nick (1) or remote (0) + * output - none + * side effects - walks through the nickname, returning 0 if erroneous + */ +int +valid_nickname(const char *nickname, const int local) +{ + const char *p = nickname; + assert(nickname && *nickname); + + /* nicks can't start with a digit or - or be 0 length */ + /* This closer duplicates behaviour of hybrid-6 */ + if (*p == '-' || (IsDigit(*p) && local) || *p == '\0') + return 0; + + for (; *p; ++p) + if (!IsNickChar(*p)) + return 0; + + return p - nickname <= NICKLEN; +} + +/* report_and_set_user_flags() + * + * inputs - pointer to source_p + * - pointer to aconf for this user + * output - NONE + * side effects - Report to user any special flags + * they are getting, and set them. + */ +static void +report_and_set_user_flags(struct Client *source_p, const struct AccessItem *aconf) +{ + /* If this user is being spoofed, tell them so */ + if (IsConfDoSpoofIp(aconf)) + { + sendto_one(source_p, + ":%s NOTICE %s :*** Spoofing your IP. congrats.", + me.name, source_p->name); + } + + /* If this user is in the exception class, Set it "E lined" */ + if (IsConfExemptKline(aconf)) + { + SetExemptKline(source_p); + sendto_one(source_p, + ":%s NOTICE %s :*** You are exempt from K/D/G lines. congrats.", + me.name, source_p->name); + } + + /* The else here is to make sure that G line exempt users + * do not get noticed twice. + */ + else if (IsConfExemptGline(aconf)) + { + SetExemptGline(source_p); + sendto_one(source_p, ":%s NOTICE %s :*** You are exempt from G lines.", + me.name, source_p->name); + } + + if (IsConfExemptResv(aconf)) + { + SetExemptResv(source_p); + sendto_one(source_p, ":%s NOTICE %s :*** You are exempt from resvs.", + me.name, source_p->name); + } + + /* If this user is exempt from user limits set it "F lined" */ + if (IsConfExemptLimits(aconf)) + { + SetExemptLimits(source_p); + sendto_one(source_p, + ":%s NOTICE %s :*** You are exempt from user limits. congrats.", + me.name,source_p->name); + } + + if (IsConfCanFlood(aconf)) + { + SetCanFlood(source_p); + sendto_one(source_p, ":%s NOTICE %s :*** You are exempt from flood " + "protection, aren't you fearsome.", + me.name, source_p->name); + } +} + +/* change_simple_umode() + * + * this callback can be hooked to allow special handling of + * certain usermodes + */ +static void * +change_simple_umode(va_list args) +{ + struct Client *client_p; + struct Client *source_p; + int what; + unsigned int flag; + + client_p = va_arg(args, struct Client *); + source_p = va_arg(args, struct Client *); + what = va_arg(args, int); + flag = va_arg(args, unsigned int); + + if (what == MODE_ADD) + AddUMode(source_p, flag); + else + DelUMode(source_p, flag); + + return NULL; +} + +/* set_user_mode() + * + * added 15/10/91 By Darren Reed. + * parv[0] - sender + * parv[1] - username to change mode for + * parv[2] - modes to change + */ +void +set_user_mode(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) +{ + unsigned int flag, setflags; + char **p, *m, buf[IRCD_BUFSIZE]; + struct Client *target_p; + int what = MODE_ADD, badflag = 0, i; + + assert(!(parc < 2)); + + if ((target_p = find_person(client_p, parv[1])) == NULL) + { + if (MyConnect(source_p)) + sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), + me.name, source_p->name, parv[1]); + return; + } + + if (IsServer(source_p)) + { + sendto_realops_flags(UMODE_ALL, L_ADMIN, "*** Mode for User %s from %s", + parv[1], source_p->name); + return; + } + + if (source_p != target_p) + { + sendto_one(source_p, form_str(ERR_USERSDONTMATCH), + me.name, source_p->name); + return; + } + + if (parc < 3) + { + m = buf; + *m++ = '+'; + + for (i = 0; i < 128; i++) + if (HasUMode(source_p, user_modes[i])) + *m++ = (char)i; + *m = '\0'; + + sendto_one(source_p, form_str(RPL_UMODEIS), + me.name, source_p->name, buf); + return; + } + + execute_callback(entering_umode_cb, client_p, source_p); + + /* find flags already set for user */ + setflags = source_p->umodes; + + /* parse mode change string(s) */ + for (p = &parv[2]; p && *p; p++) + { + for (m = *p; *m; m++) + { + switch (*m) + { + case '+': + what = MODE_ADD; + break; + case '-': + what = MODE_DEL; + break; + case 'o': + if (what == MODE_ADD) + { + if (IsServer(client_p) && !HasUMode(source_p, UMODE_OPER)) + { + ++Count.oper; + SetOper(source_p); + } + } + else + { + /* Only decrement the oper counts if an oper to begin with + * found by Pat Szuta, Perly , perly@xnet.com + */ + if (!HasUMode(source_p, UMODE_OPER)) + break; + + ClearOper(source_p); + Count.oper--; + + if (MyConnect(source_p)) + { + dlink_node *dm; + + detach_conf(source_p, OPER_TYPE); + ClrOFlag(source_p); + DelUMode(source_p, ConfigFileEntry.oper_only_umodes); + + if ((dm = dlinkFindDelete(&oper_list, source_p)) != NULL) + free_dlink_node(dm); + } + } + + break; + + /* we may not get these, + * but they shouldnt be in default + */ + case 'r': + case ' ' : + case '\n': + case '\r': + case '\t': + break; + + default: + if ((flag = user_modes[(unsigned char)*m])) + { + if (MyConnect(source_p) && !HasUMode(source_p, UMODE_OPER) && + (ConfigFileEntry.oper_only_umodes & flag)) + { + badflag = 1; + } + else + execute_callback(umode_cb, client_p, source_p, what, flag); + } + else + { + if (MyConnect(source_p)) + badflag = 1; + } + + break; + } + } + } + + if (badflag) + sendto_one(source_p, form_str(ERR_UMODEUNKNOWNFLAG), + me.name, source_p->name); + + if (HasUMode(source_p, UMODE_NCHANGE) && !HasOFlag(source_p, OPER_FLAG_N)) + { + sendto_one(source_p, ":%s NOTICE %s :*** You have no nchange flag;", + me.name, source_p->name); + DelUMode(source_p, UMODE_NCHANGE); + } + + if (MyConnect(source_p) && HasUMode(source_p, UMODE_ADMIN) && + !HasOFlag(source_p, OPER_FLAG_ADMIN)) + { + sendto_one(source_p, ":%s NOTICE %s :*** You have no admin flag;", + me.name, source_p->name); + DelUMode(source_p, UMODE_ADMIN); + } + + if (!(setflags & UMODE_INVISIBLE) && HasUMode(source_p, UMODE_INVISIBLE)) + ++Count.invisi; + if ((setflags & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE)) + --Count.invisi; + + /* + * compare new flags with old flags and send string which + * will cause servers to update correctly. + */ + send_umode_out(client_p, source_p, setflags); +} + +/* send_umode() + * send the MODE string for user (user) to connection client_p + * -avalon + * + * inputs - client_p + * - source_p + * - int old + * - sendmask mask of modes to send + * - suplied umode_buf + * output - NONE + */ +void +send_umode(struct Client *client_p, struct Client *source_p, + unsigned int old, unsigned int sendmask, char *umode_buf) +{ + char *m = umode_buf; + int what = 0; + unsigned int i; + unsigned int flag; + + /* + * build a string in umode_buf to represent the change in the user's + * mode between the new (source_p->umodes) and 'old'. + */ + for (i = 0; i < 128; i++) + { + flag = user_modes[i]; + if (!flag) + continue; + + if (MyClient(source_p) && !(flag & sendmask)) + continue; + + if ((flag & old) && !HasUMode(source_p, flag)) + { + if (what == MODE_DEL) + *m++ = (char)i; + else + { + what = MODE_DEL; + *m++ = '-'; + *m++ = (char)i; + } + } + else if (!(flag & old) && HasUMode(source_p, flag)) + { + if (what == MODE_ADD) + *m++ = (char)i; + else + { + what = MODE_ADD; + *m++ = '+'; + *m++ = (char)i; + } + } + } + + *m = '\0'; + + if (*umode_buf && client_p) + sendto_one(client_p, ":%s!%s@%s MODE %s :%s", + source_p->name, source_p->username, + source_p->host, source_p->name, umode_buf); +} + +/* send_umode_out() + * + * inputs - + * output - NONE + * side effects - Only send ubuf out to servers that know about this client + */ +void +send_umode_out(struct Client *client_p, struct Client *source_p, + unsigned int old) +{ + char buf[IRCD_BUFSIZE] = { '\0' }; + dlink_node *ptr = NULL; + + send_umode(NULL, source_p, old, SEND_UMODES, buf); + + if (buf[0]) + { + DLINK_FOREACH(ptr, serv_list.head) + { + struct Client *target_p = ptr->data; + + if ((target_p != client_p) && (target_p != source_p)) + sendto_one(target_p, ":%s MODE %s :%s", + ID_or_name(source_p, target_p), + ID_or_name(source_p, target_p), buf); + } + } + + if (client_p && MyClient(client_p)) + send_umode(client_p, source_p, old, 0xffffffff, buf); +} + +/* user_welcome() + * + * inputs - client pointer to client to welcome + * output - NONE + * side effects - + */ +static void +user_welcome(struct Client *source_p) +{ +#if defined(__TIME__) && defined(__DATE__) + static const char built_date[] = __DATE__ " at " __TIME__; +#else + static const char built_date[] = "unknown"; +#endif + +#ifdef HAVE_LIBCRYPTO + if (source_p->localClient->fd.ssl != NULL) + sendto_one(source_p, ":%s NOTICE %s :*** Connected securely via %s", + me.name, source_p->name, + ssl_get_cipher(source_p->localClient->fd.ssl)); +#endif + + sendto_one(source_p, form_str(RPL_WELCOME), me.name, source_p->name, + ServerInfo.network_name, source_p->name); + sendto_one(source_p, form_str(RPL_YOURHOST), me.name, source_p->name, + get_listener_name(source_p->localClient->listener), ircd_version); + sendto_one(source_p, form_str(RPL_CREATED), + me.name, source_p->name, built_date); + sendto_one(source_p, form_str(RPL_MYINFO), + me.name, source_p->name, me.name, ircd_version, umode_buffer); + show_isupport(source_p); + + if (source_p->id[0] != '\0') + sendto_one(source_p, form_str(RPL_YOURID), me.name, + source_p->name, source_p->id); + + show_lusers(source_p); + + if (ConfigFileEntry.short_motd) + { + sendto_one(source_p, ":%s NOTICE %s :*** Notice -- motd was last changed at %s", + me.name, source_p->name, ConfigFileEntry.motd.lastChangedDate); + sendto_one(source_p, + ":%s NOTICE %s :*** Notice -- Please read the motd if you haven't " + "read it", me.name, source_p->name); + sendto_one(source_p, form_str(RPL_MOTDSTART), + me.name, source_p->name, me.name); + sendto_one(source_p, form_str(RPL_MOTD), + me.name, source_p->name, + "*** This is the short motd ***"); + sendto_one(source_p, form_str(RPL_ENDOFMOTD), + me.name, source_p->name); + } + else + send_message_file(source_p, &ConfigFileEntry.motd); +} + +/* check_xline() + * + * inputs - pointer to client to test + * outupt - 1 if exiting 0 if ok + * side effects - + */ +static int +check_xline(struct Client *source_p) +{ + struct ConfItem *conf = NULL; + const char *reason = NULL; + + if ((conf = find_matching_name_conf(XLINE_TYPE, source_p->info, NULL, NULL, 0)) || + (conf = find_matching_name_conf(RXLINE_TYPE, source_p->info, NULL, NULL, 0))) + { + struct MatchItem *reg = map_to_conf(conf); + + ++reg->count; + + if (reg->reason != NULL) + reason = reg->reason; + else + reason = "No Reason"; + + sendto_realops_flags(UMODE_REJ, L_ALL, + "X-line Rejecting [%s] [%s], user %s [%s]", + source_p->info, reason, + get_client_name(source_p, HIDE_IP), + source_p->sockhost); + + ++ServerStats.is_ref; + exit_client(source_p, &me, "Bad user info"); + return 1; + } + + return 0; +} + +/* oper_up() + * + * inputs - pointer to given client to oper + * output - NONE + * side effects - Blindly opers up given source_p, using aconf info + * all checks on passwords have already been done. + * This could also be used by rsa oper routines. + */ +void +oper_up(struct Client *source_p) +{ + const unsigned int old = source_p->umodes; + const struct AccessItem *oconf = NULL; + + assert(source_p->localClient->confs.head); + oconf = map_to_conf((source_p->localClient->confs.head)->data); + + ++Count.oper; + SetOper(source_p); + + if (oconf->modes) + AddUMode(source_p, oconf->modes); + else if (ConfigFileEntry.oper_umodes) + AddUMode(source_p, ConfigFileEntry.oper_umodes); + + if (!(old & UMODE_INVISIBLE) && HasUMode(source_p, UMODE_INVISIBLE)) + ++Count.invisi; + if ((old & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE)) + --Count.invisi; + + assert(dlinkFind(&oper_list, source_p) == NULL); + dlinkAdd(source_p, make_dlink_node(), &oper_list); + + AddOFlag(source_p, oconf->port); + + if (HasOFlag(source_p, OPER_FLAG_ADMIN)) + AddUMode(source_p, UMODE_ADMIN); + if (!HasOFlag(source_p, OPER_FLAG_N)) + DelUMode(source_p, UMODE_NCHANGE); + + sendto_realops_flags(UMODE_ALL, L_ALL, "%s is now an operator", + get_oper_name(source_p)); + send_umode_out(source_p, source_p, old); + sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, source_p->name); +} + +static char new_uid[TOTALSIDUID + 1]; /* allow for \0 */ + +int +valid_sid(const char *sid) +{ + if (strlen(sid) == IRC_MAXSID) + if (IsDigit(*sid)) + if (IsAlNum(*(sid + 1)) && IsAlNum(*(sid + 2))) + return 1; + + return 0; +} + +/* + * init_uid() + * + * inputs - NONE + * output - NONE + * side effects - new_uid is filled in with server id portion (sid) + * (first 3 bytes) or defaulted to 'A'. + * Rest is filled in with 'A' + */ +void +init_uid(void) +{ + int i; + + memset(new_uid, 0, sizeof(new_uid)); + + if (!EmptyString(ServerInfo.sid)) + strlcpy(new_uid, ServerInfo.sid, sizeof(new_uid)); + + for (i = 0; i < IRC_MAXSID; ++i) + if (new_uid[i] == '\0') + new_uid[i] = 'A'; + + /* NOTE: if IRC_MAXUID != 6, this will have to be rewritten */ + /* Yes nenolod, I have known it was off by one ever since I wrote it + * But *JUST* for you, though, it really doesn't look as *pretty* + * -Dianora + */ + memcpy(new_uid + IRC_MAXSID, "AAAAA@", IRC_MAXUID); + + entering_umode_cb = register_callback("entering_umode", NULL); + umode_cb = register_callback("changing_umode", change_simple_umode); +} + +/* + * add_one_to_uid + * + * inputs - index number into new_uid + * output - NONE + * side effects - new_uid is incremented by one + * note this is a recursive function + */ +static void +add_one_to_uid(int i) +{ + if (i != IRC_MAXSID) /* Not reached server SID portion yet? */ + { + if (new_uid[i] == 'Z') + new_uid[i] = '0'; + else if (new_uid[i] == '9') + { + new_uid[i] = 'A'; + add_one_to_uid(i-1); + } + else + ++new_uid[i]; + } + else + { + /* NOTE: if IRC_MAXUID != 6, this will have to be rewritten */ + if (new_uid[i] == 'Z') + memcpy(new_uid + IRC_MAXSID, "AAAAAA", IRC_MAXUID); + else + ++new_uid[i]; + } +} + +/* + * uid_get + * + * inputs - struct Client * + * output - new UID is returned to caller + * side effects - new_uid is incremented by one. + */ +static const char * +uid_get(void) +{ + add_one_to_uid(TOTALSIDUID - 1); /* index from 0 */ + return new_uid; +} + +/* + * init_isupport() + * + * input - NONE + * output - NONE + * side effects - Must be called before isupport is enabled + */ +void +init_isupport(void) +{ + isupportFile = init_MessageLine(); + + add_isupport("CALLERID", NULL, -1); + add_isupport("CASEMAPPING", CASEMAP, -1); + add_isupport("DEAF", "D", -1); + add_isupport("KICKLEN", NULL, KICKLEN); + add_isupport("MODES", NULL, MAXMODEPARAMS); + add_isupport("NICKLEN", NULL, NICKLEN); +#ifdef HALFOPS + add_isupport("PREFIX", "(ohv)@%+", -1); + add_isupport("STATUSMSG", "@%+", -1); +#else + add_isupport("PREFIX", "(ov)@+", -1); + add_isupport("STATUSMSG", "@+", -1); +#endif + add_isupport("TOPICLEN", NULL, TOPICLEN); +} + +/* + * add_isupport() + * + * input - name of supported function + * - options if any + * - number if any + * output - NONE + * side effects - Each supported item must call this when activated + */ +void +add_isupport(const char *name, const char *options, int n) +{ + dlink_node *ptr; + struct Isupport *support; + + DLINK_FOREACH(ptr, support_list.head) + { + support = ptr->data; + if (irccmp(support->name, name) == 0) + { + MyFree(support->name); + MyFree(support->options); + break; + } + } + + if (ptr == NULL) + { + support = MyMalloc(sizeof(*support)); + dlinkAddTail(support, &support->node, &support_list); + } + + DupString(support->name, name); + if (options != NULL) + DupString(support->options, options); + support->number = n; + + rebuild_isupport_message_line(); +} + +/* + * delete_isupport() + * + * input - name of supported function + * output - NONE + * side effects - Each supported item must call this when deactivated + */ +void +delete_isupport(const char *name) +{ + dlink_node *ptr; + struct Isupport *support; + + DLINK_FOREACH(ptr, support_list.head) + { + support = ptr->data; + if (irccmp(support->name, name) == 0) + { + dlinkDelete(ptr, &support_list); + MyFree(support->name); + MyFree(support->options); + MyFree(support); + break; + } + } + + rebuild_isupport_message_line(); +} + +/* + * rebuild_isupport_message_line + * + * input - NONE + * output - NONE + * side effects - Destroy the isupport MessageFile lines, and rebuild. + */ +void +rebuild_isupport_message_line(void) +{ + char isupportbuffer[IRCD_BUFSIZE]; + char *p = isupportbuffer; + dlink_node *ptr = NULL; + int n = 0; + int tokens = 0; + size_t len = 0; + size_t reserve = strlen(me.name) + HOSTLEN + strlen(form_str(RPL_ISUPPORT)); + + destroy_MessageLine(isupportFile); + + DLINK_FOREACH(ptr, support_list.head) + { + struct Isupport *support = ptr->data; + + p += (n = ircsprintf(p, "%s", support->name)); + len += n; + + if (support->options != NULL) + { + p += (n = ircsprintf(p, "=%s", support->options)); + len += n; + } + + if (support->number > 0) + { + p += (n = ircsprintf(p, "=%d", support->number)); + len += n; + } + + *p++ = ' '; + len++; + *p = '\0'; + + if (++tokens == (MAXPARA-2) || len >= (sizeof(isupportbuffer)-reserve)) + { /* arbritrary for now */ + if (*--p == ' ') + *p = '\0'; + + addto_MessageLine(isupportFile, isupportbuffer); + p = isupportbuffer; + len = 0; + n = tokens = 0; + } + } + + if (len != 0) + { + if (*--p == ' ') + *p = '\0'; + addto_MessageLine(isupportFile, isupportbuffer); + } +} diff --git a/src/send.c b/src/send.c new file mode 100644 index 0000000..afa684e --- /dev/null +++ b/src/send.c @@ -0,0 +1,1111 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * send.c: Functions for sending messages. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "send.h" +#include "channel.h" +#include "client.h" +#include "dbuf.h" +#include "irc_string.h" +#include "ircd.h" +#include "numeric.h" +#include "fdlist.h" +#include "s_bsd.h" +#include "s_serv.h" +#include "sprintf_irc.h" +#include "conf.h" +#include "log.h" +#include "memory.h" +#include "hook.h" +#include "packet.h" + + +struct Callback *iosend_cb = NULL; +static unsigned int current_serial = 0; + + +/* send_format() + * + * inputs - buffer to format into + * - size of the buffer + * - format pattern to use + * - var args + * output - number of bytes formatted output + * side effects - modifies sendbuf + */ +static inline int +send_format(char *lsendbuf, int bufsize, const char *pattern, va_list args) +{ + int len; + + /* + * from rfc1459 + * + * IRC messages are always lines of characters terminated with a CR-LF + * (Carriage Return - Line Feed) pair, and these messages shall not + * exceed 512 characters in length, counting all characters + * including the trailing CR-LF. + * Thus, there are 510 characters maximum allowed + * for the command and its parameters. There is no provision for + * continuation message lines. See section 7 for more details about + * current implementations. + */ + len = vsnprintf(lsendbuf, bufsize - 1, pattern, args); + if (len > bufsize - 2) + len = bufsize - 2; /* required by some versions of vsnprintf */ + + lsendbuf[len++] = '\r'; + lsendbuf[len++] = '\n'; + return len; +} + +/* + * iosend_default - append a packet to the client's sendq. + */ +void * +iosend_default(va_list args) +{ + struct Client *to = va_arg(args, struct Client *); + int length = va_arg(args, int); + char *buf = va_arg(args, char *); + + dbuf_put(&to->localClient->buf_sendq, buf, length); + return NULL; +} + +/* + ** send_message + ** Internal utility which appends given buffer to the sockets + ** sendq. + */ +static void +send_message(struct Client *to, char *buf, int len) +{ + assert(!IsMe(to)); + assert(to != &me); + + if (dbuf_length(&to->localClient->buf_sendq) + len > get_sendq(to)) + { + if (IsServer(to)) + sendto_realops_flags(UMODE_ALL, L_ALL, + "Max SendQ limit exceeded for %s: %lu > %lu", + get_client_name(to, HIDE_IP), + (unsigned long)(dbuf_length(&to->localClient->buf_sendq) + len), + get_sendq(to)); + if (IsClient(to)) + SetSendQExceeded(to); + dead_link_on_write(to, 0); + return; + } + + execute_callback(iosend_cb, to, len, buf); + + /* + ** Update statistics. The following is slightly incorrect + ** because it counts messages even if queued, but bytes + ** only really sent. Queued bytes get updated in SendQueued. + */ + ++to->localClient->send.messages; + ++me.localClient->send.messages; + + if (dbuf_length(&to->localClient->buf_sendq) > + (IsServer(to) ? (unsigned int) 1024 : (unsigned int) 4096)) + send_queued_write(to); +} + +/* send_message_remote() + * + * inputs - pointer to client from message is being sent + * - pointer to client to send to + * - pointer to preformatted buffer + * - length of input buffer + * output - none + * side effects - Despite the function name, this only sends to directly + * connected clients. + * + */ +static void +send_message_remote(struct Client *to, struct Client *from, + char *buf, int len) +{ + if (!MyConnect(to)) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "server send message to %s [%s] dropped from %s(Not local server)", + to->name, to->from->name, from->name); + return; + } + + /* Optimize by checking if (from && to) before everything */ + /* we set to->from up there.. */ + + if (!MyClient(from) && IsClient(to) && (to == from->from)) + { + if (IsServer(from)) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "Send message to %s [%s] dropped from %s(Fake Dir)", + to->name, to->from->name, from->name); + return; + } + + sendto_realops_flags(UMODE_ALL, L_ALL, + "Ghosted: %s[%s@%s] from %s[%s@%s] (%s)", + to->name, to->username, to->host, + from->name, from->username, from->host, + to->from->name); + + sendto_server(NULL, CAP_TS6, NOCAPS, + ":%s KILL %s :%s (%s[%s@%s] Ghosted %s)", + me.id, to->name, me.name, to->name, + to->username, to->host, to->from->name); + sendto_server(NULL, NOCAPS, CAP_TS6, + ":%s KILL %s :%s (%s[%s@%s] Ghosted %s)", + me.name, to->name, me.name, to->name, + to->username, to->host, to->from->name); + + AddFlag(to, FLAGS_KILLED); + + if (IsClient(from)) + sendto_one(from, form_str(ERR_GHOSTEDCLIENT), + me.name, from->name, to->name, to->username, + to->host, to->from); + + exit_client(to, &me, "Ghosted client"); + + return; + } + + send_message(to, buf, len); +} + +/* + ** sendq_unblocked + ** Called when a socket is ready for writing. + */ +void +sendq_unblocked(fde_t *fd, struct Client *client_p) +{ + ClearSendqBlocked(client_p); + /* let send_queued_write be executed by send_queued_all */ + +#ifdef HAVE_LIBCRYPTO + if (fd->flags.pending_read) + { + fd->flags.pending_read = 0; + read_packet(fd, client_p); + } +#endif +} + +/* + ** send_queued_write + ** This is called when there is a chance that some output would + ** be possible. This attempts to empty the send queue as far as + ** possible, and then if any data is left, a write is rescheduled. + */ +void +send_queued_write(struct Client *to) +{ + int retlen; + struct dbuf_block *first; + + /* + ** Once socket is marked dead, we cannot start writing to it, + ** even if the error is removed... + */ + if (IsDead(to) || IsSendqBlocked(to)) + return; /* no use calling send() now */ + + /* Next, lets try to write some data */ + + if (dbuf_length(&to->localClient->buf_sendq)) + { + do { + first = to->localClient->buf_sendq.blocks.head->data; + +#ifdef HAVE_LIBCRYPTO + if (to->localClient->fd.ssl) + { + retlen = SSL_write(to->localClient->fd.ssl, first->data, first->size); + + /* translate openssl error codes, sigh */ + if (retlen < 0) + switch (SSL_get_error(to->localClient->fd.ssl, retlen)) + { + case SSL_ERROR_WANT_READ: + return; /* retry later, don't register for write events */ + + case SSL_ERROR_WANT_WRITE: + errno = EWOULDBLOCK; + case SSL_ERROR_SYSCALL: + break; + case SSL_ERROR_SSL: + if (errno == EAGAIN) + break; + default: + retlen = errno = 0; /* either an SSL-specific error or EOF */ + } + } + else +#endif + retlen = send(to->localClient->fd.fd, first->data, first->size, 0); + + if (retlen <= 0) + break; + + dbuf_delete(&to->localClient->buf_sendq, retlen); + + /* We have some data written .. update counters */ + to->localClient->send.bytes += retlen; + me.localClient->send.bytes += retlen; + } while (dbuf_length(&to->localClient->buf_sendq)); + + if ((retlen < 0) && (ignoreErrno(errno))) + { + /* we have a non-fatal error, reschedule a write */ + SetSendqBlocked(to); + comm_setselect(&to->localClient->fd, COMM_SELECT_WRITE, + (PF *)sendq_unblocked, (void *)to, 0); + } + else if (retlen <= 0) + { + dead_link_on_write(to, errno); + return; + } + } +} + +/* send_queued_all() + * + * input - NONE + * output - NONE + * side effects - try to flush sendq of each client + */ +void +send_queued_all(void) +{ + dlink_node *ptr; + + /* Servers are processed first, mainly because this can generate + * a notice to opers, which is to be delivered by this function. + */ + DLINK_FOREACH(ptr, serv_list.head) + send_queued_write((struct Client *) ptr->data); + + DLINK_FOREACH(ptr, unknown_list.head) + send_queued_write((struct Client *) ptr->data); + + DLINK_FOREACH(ptr, local_client_list.head) + send_queued_write((struct Client *) ptr->data); + + /* NOTE: This can still put clients on aborted_list; unfortunately, + * exit_aborted_clients takes precedence over send_queued_all, + * because exiting clients can generate server/oper traffic. + * The easiest approach is dealing with aborted clients in the next I/O lap. + * -adx + */ +} + +/* sendto_one() + * + * inputs - pointer to destination client + * - var args message + * output - NONE + * side effects - send message to single client + */ +void +sendto_one(struct Client *to, const char *pattern, ...) +{ + va_list args; + char buffer[IRCD_BUFSIZE]; + int len; + + if (to->from != NULL) + to = to->from; + if (IsDead(to)) + return; /* This socket has already been marked as dead */ + + va_start(args, pattern); + len = send_format(buffer, IRCD_BUFSIZE, pattern, args); + va_end(args); + + send_message(to, buffer, len); +} + +/* sendto_channel_butone() + * + * inputs - pointer to client(server) to NOT send message to + * - pointer to client that is sending this message + * - pointer to channel being sent to + * - vargs message + * output - NONE + * side effects - message as given is sent to given channel members. + * + * WARNING - +D clients are ignored + */ +void +sendto_channel_butone(struct Client *one, struct Client *from, + struct Channel *chptr, unsigned int type, + const char *pattern, ...) +{ + va_list alocal, aremote, auid; + char local_buf[IRCD_BUFSIZE]; + char remote_buf[IRCD_BUFSIZE]; + char uid_buf[IRCD_BUFSIZE]; + int local_len, remote_len, uid_len; + dlink_node *ptr = NULL, *ptr_next = NULL; + + if (IsServer(from)) + local_len = ircsprintf(local_buf, ":%s ", + from->name); + else + local_len = ircsprintf(local_buf, ":%s!%s@%s ", + from->name, from->username, from->host); + remote_len = ircsprintf(remote_buf, ":%s ", + from->name); + uid_len = ircsprintf(uid_buf, ":%s ", + ID(from)); + + va_start(alocal, pattern); + va_start(aremote, pattern); + va_start(auid, pattern); + local_len += send_format(&local_buf[local_len], IRCD_BUFSIZE - local_len, + pattern, alocal); + remote_len += send_format(&remote_buf[remote_len], IRCD_BUFSIZE - remote_len, + pattern, aremote); + uid_len += send_format(&uid_buf[uid_len], IRCD_BUFSIZE - uid_len, pattern, + auid); + va_end(auid); + va_end(aremote); + va_end(alocal); + + ++current_serial; + + DLINK_FOREACH_SAFE(ptr, ptr_next, chptr->members.head) + { + struct Membership *ms = ptr->data; + struct Client *target_p = ms->client_p; + + assert(IsClient(target_p)); + + if (IsDefunct(target_p) || HasUMode(target_p, UMODE_DEAF) || target_p->from == one) + continue; + + if (type != 0 && (ms->flags & type) == 0) + continue; + + if (MyConnect(target_p)) + { + if (target_p->localClient->serial != current_serial) + { + send_message(target_p, local_buf, local_len); + target_p->localClient->serial = current_serial; + } + } + else + { + /* Now check whether a message has been sent to this + * remote link already + */ + if (target_p->from->localClient->serial != current_serial) + { + if (IsCapable(target_p->from, CAP_TS6)) + send_message_remote(target_p->from, from, uid_buf, uid_len); + else + send_message_remote(target_p->from, from, remote_buf, remote_len); + target_p->from->localClient->serial = current_serial; + } + } + } +} + +/* sendto_server() + * + * inputs - pointer to client to NOT send to + * - pointer to channel + * - caps or'd together which must ALL be present + * - caps or'd together which must ALL NOT be present + * - printf style format string + * - args to format string + * output - NONE + * side effects - Send a message to all connected servers, except the + * client 'one' (if non-NULL), as long as the servers + * support ALL capabs in 'caps', and NO capabs in 'nocaps'. + * + * This function was written in an attempt to merge together the other + * billion sendto_*serv*() functions, which sprung up with capabs, + * lazylinks, uids, etc. + * -davidt + */ +void +sendto_server(struct Client *one, + const unsigned int caps, + const unsigned int nocaps, + const char *format, ...) +{ + va_list args; + dlink_node *ptr = NULL; + char buffer[IRCD_BUFSIZE]; + int len = 0; + + va_start(args, format); + len = send_format(buffer, IRCD_BUFSIZE, format, args); + va_end(args); + + DLINK_FOREACH(ptr, serv_list.head) + { + struct Client *client_p = ptr->data; + + /* If dead already skip */ + if (IsDead(client_p)) + continue; + /* check against 'one' */ + if (one != NULL && (client_p == one->from)) + continue; + /* check we have required capabs */ + if ((client_p->localClient->caps & caps) != caps) + continue; + /* check we don't have any forbidden capabs */ + if ((client_p->localClient->caps & nocaps) != 0) + continue; + + send_message(client_p, buffer, len); + } +} + +/* sendto_common_channels_local() + * + * inputs - pointer to client + * - pattern to send + * output - NONE + * side effects - Sends a message to all people on local server who are + * in same channel with user. + * used by m_nick.c and exit_one_client. + */ +void +sendto_common_channels_local(struct Client *user, int touser, + const char *pattern, ...) +{ + va_list args; + dlink_node *uptr; + dlink_node *cptr; + struct Channel *chptr; + struct Membership *ms; + struct Client *target_p; + char buffer[IRCD_BUFSIZE]; + int len; + + va_start(args, pattern); + len = send_format(buffer, IRCD_BUFSIZE, pattern, args); + va_end(args); + + ++current_serial; + + DLINK_FOREACH(cptr, user->channel.head) + { + chptr = ((struct Membership *) cptr->data)->chptr; + assert(chptr != NULL); + + DLINK_FOREACH(uptr, chptr->members.head) + { + ms = uptr->data; + target_p = ms->client_p; + assert(target_p != NULL); + + if (!MyConnect(target_p) || target_p == user || IsDefunct(target_p) || + target_p->localClient->serial == current_serial) + continue; + + target_p->localClient->serial = current_serial; + send_message(target_p, buffer, len); + } + } + + if (touser && MyConnect(user) && !IsDead(user) && + user->localClient->serial != current_serial) + send_message(user, buffer, len); +} + +/* sendto_channel_local() + * + * inputs - member status mask, e.g. CHFL_CHANOP | CHFL_VOICE + * - whether to ignore +D clients (YES/NO) + * - pointer to channel to send to + * - var args pattern + * output - NONE + * side effects - Send a message to all members of a channel that are + * locally connected to this server. + */ +void +sendto_channel_local(int type, int nodeaf, struct Channel *chptr, + const char *pattern, ...) +{ + va_list args; + char buffer[IRCD_BUFSIZE]; + int len; + dlink_node *ptr; + struct Membership *ms; + struct Client *target_p; + + va_start(args, pattern); + len = send_format(buffer, IRCD_BUFSIZE, pattern, args); + va_end(args); + + DLINK_FOREACH(ptr, chptr->members.head) + { + ms = ptr->data; + target_p = ms->client_p; + + if (type != 0 && (ms->flags & type) == 0) + continue; + + if (!MyConnect(target_p) || IsDefunct(target_p) || + (nodeaf && HasUMode(target_p, UMODE_DEAF))) + continue; + + send_message(target_p, buffer, len); + } +} + +/* sendto_channel_local_butone() + * + * inputs - pointer to client to NOT send message to + * - member status mask, e.g. CHFL_CHANOP | CHFL_VOICE + * - pointer to channel to send to + * - var args pattern + * output - NONE + * side effects - Send a message to all members of a channel that are + * locally connected to this server except one. + * + * WARNING - +D clients are omitted + */ +void +sendto_channel_local_butone(struct Client *one, int type, + struct Channel *chptr, const char *pattern, ...) +{ + va_list args; + char buffer[IRCD_BUFSIZE]; + int len; + struct Client *target_p; + struct Membership *ms; + dlink_node *ptr; + + va_start(args, pattern); + len = send_format(buffer, IRCD_BUFSIZE, pattern, args); + va_end(args); + + DLINK_FOREACH(ptr, chptr->members.head) + { + ms = ptr->data; + target_p = ms->client_p; + + if (type != 0 && (ms->flags & type) == 0) + continue; + + if (!MyConnect(target_p) || target_p == one || + IsDefunct(target_p) || HasUMode(target_p, UMODE_DEAF)) + continue; + send_message(target_p, buffer, len); + } +} + + +/* sendto_channel_remote() + * + * inputs - Client not to send towards + * - Client from whom message is from + * - member status mask, e.g. CHFL_CHANOP | CHFL_VOICE + * - pointer to channel to send to + * - var args pattern + * output - NONE + * side effects - Send a message to all members of a channel that are + * remote to this server. + */ +void +sendto_channel_remote(struct Client *one, struct Client *from, int type, + const unsigned int caps, const unsigned int nocaps, + struct Channel *chptr, const char *pattern, ...) +{ + va_list args; + char buffer[IRCD_BUFSIZE]; + int len; + dlink_node *ptr; + struct Client *target_p; + struct Membership *ms; + + va_start(args, pattern); + len = send_format(buffer, IRCD_BUFSIZE, pattern, args); + va_end(args); + + ++current_serial; + + DLINK_FOREACH(ptr, chptr->members.head) + { + ms = ptr->data; + target_p = ms->client_p; + + if (type != 0 && (ms->flags & type) == 0) + continue; + + if (MyConnect(target_p)) + continue; + target_p = target_p->from; + + if (target_p == one->from || + ((target_p->from->localClient->caps & caps) != caps) || + ((target_p->from->localClient->caps & nocaps) != 0)) + continue; + if (target_p->from->localClient->serial != current_serial) + { + send_message(target_p, buffer, len); + target_p->from->localClient->serial = current_serial; + } + } +} + +/* + ** match_it() and sendto_match_butone() ARE only used + ** to send a msg to all ppl on servers/hosts that match a specified mask + ** (used for enhanced PRIVMSGs) for opers + ** + ** addition -- Armin, 8jun90 (gruner@informatik.tu-muenchen.de) + ** + */ + +/* match_it() + * + * inputs - client pointer to match on + * - actual mask to match + * - what to match on, HOST or SERVER + * output - 1 or 0 if match or not + * side effects - NONE + */ +static int +match_it(const struct Client *one, const char *mask, int what) +{ + if (what == MATCH_HOST) + return match(mask, one->host); + + return match(mask, one->servptr->name); +} + +/* sendto_match_butone() + * + * Send to all clients which match the mask in a way defined on 'what'; + * either by user hostname or user servername. + * + * ugh. ONLY used by m_message.c to send an "oper magic" message. ugh. + */ +void +sendto_match_butone(struct Client *one, struct Client *from, char *mask, + int what, const char *pattern, ...) +{ + va_list alocal, aremote; + struct Client *client_p; + dlink_node *ptr, *ptr_next; + char local_buf[IRCD_BUFSIZE], remote_buf[IRCD_BUFSIZE]; + int local_len = ircsprintf(local_buf, ":%s!%s@%s ", from->name, + from->username, from->host); + int remote_len = ircsprintf(remote_buf, ":%s ", from->name); + + va_start(alocal, pattern); + va_start(aremote, pattern); + local_len += send_format(&local_buf[local_len], IRCD_BUFSIZE - local_len, + pattern, alocal); + remote_len += send_format(&remote_buf[remote_len], IRCD_BUFSIZE - remote_len, + pattern, aremote); + va_end(aremote); + va_end(alocal); + + /* scan the local clients */ + DLINK_FOREACH(ptr, local_client_list.head) + { + client_p = ptr->data; + + if (client_p != one && !IsDefunct(client_p) && + match_it(client_p, mask, what)) + send_message(client_p, local_buf, local_len); + } + + /* Now scan servers */ + DLINK_FOREACH_SAFE(ptr, ptr_next, serv_list.head) + { + client_p = ptr->data; + + /* + * The old code looped through every client on the + * network for each server to check if the + * server (client_p) has at least 1 client matching + * the mask, using something like: + * + * for (target_p = GlobalClientList; target_p; target_p = target_p->next) + * if (IsRegisteredUser(target_p) && + * match_it(target_p, mask, what) && + * (target_p->from == client_p)) + * vsendto_prefix_one(client_p, from, pattern, args); + * + * That way, we wouldn't send the message to + * a server who didn't have a matching client. + * However, on a network such as EFNet, that + * code would have looped through about 50 + * servers, and in each loop, loop through + * about 50k clients as well, calling match() + * in each nested loop. That is a very bad + * thing cpu wise - just send the message + * to every connected server and let that + * server deal with it. + * -wnder + */ + if (client_p != one && !IsDefunct(client_p)) + send_message_remote(client_p, from, remote_buf, remote_len); + } +} + +/* sendto_match_servs() + * + * inputs - source client + * - mask to send to + * - capab needed + * - data + * outputs - none + * side effects - data sent to servers matching with capab + */ +void +sendto_match_servs(struct Client *source_p, const char *mask, int cap, + const char *pattern, ...) +{ + va_list args; + struct Client *target_p; + dlink_node *ptr; + char buffer[IRCD_BUFSIZE]; + int found = 0; + + va_start(args, pattern); + vsnprintf(buffer, sizeof(buffer), pattern, args); + va_end(args); + + ++current_serial; + + DLINK_FOREACH(ptr, global_serv_list.head) + { + target_p = ptr->data; + + /* Do not attempt to send to ourselves, or the source */ + if (IsMe(target_p) || target_p->from == source_p->from) + continue; + + if (target_p->from->localClient->serial == current_serial) + continue; + + if (match(mask, target_p->name)) + { + /* + * if we set the serial here, then we'll never do a + * match() again, if !IsCapable() + */ + target_p->from->localClient->serial = current_serial; + found++; + + if (!IsCapable(target_p->from, cap)) + continue; + + sendto_anywhere(target_p, source_p, "%s", buffer); + } + } +} + +/* sendto_anywhere() + * + * inputs - pointer to dest client + * - pointer to from client + * - varags + * output - NONE + * side effects - less efficient than sendto_remote and sendto_one + * but useful when one does not know where target "lives" + */ +void +sendto_anywhere(struct Client *to, struct Client *from, + const char *pattern, ...) +{ + va_list args; + char buffer[IRCD_BUFSIZE]; + int len; + struct Client *send_to = (to->from != NULL ? to->from : to); + + if (IsDead(send_to)) + return; + + if (MyClient(to)) + { + if (IsServer(from)) + { + if (IsCapable(to, CAP_TS6) && HasID(from)) + len = ircsprintf(buffer, ":%s ", from->id); + else + len = ircsprintf(buffer, ":%s ", from->name); + } + else + len = ircsprintf(buffer, ":%s!%s@%s ", + from->name, from->username, from->host); + } + else len = ircsprintf(buffer, ":%s ", ID_or_name(from, send_to)); + + va_start(args, pattern); + len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args); + va_end(args); + + if(MyClient(to)) + send_message(send_to, buffer, len); + else + send_message_remote(send_to, from, buffer, len); +} + +/* sendto_realops_flags() + * + * inputs - flag types of messages to show to real opers + * - flag indicating opers/admins + * - var args input message + * output - NONE + * side effects - Send to *local* ops only but NOT +s nonopers. + */ +void +sendto_realops_flags(unsigned int flags, int level, const char *pattern, ...) +{ + dlink_node *ptr = NULL; + char nbuf[IRCD_BUFSIZE]; + va_list args; + + va_start(args, pattern); + vsnprintf(nbuf, IRCD_BUFSIZE, pattern, args); + va_end(args); + + DLINK_FOREACH(ptr, oper_list.head) + { + struct Client *client_p = ptr->data; + assert(HasUMode(client_p, UMODE_OPER)); + + /* If we're sending it to opers and theyre an admin, skip. + * If we're sending it to admins, and theyre not, skip. + */ + if (((level == L_ADMIN) && !HasUMode(client_p, UMODE_ADMIN)) || + ((level == L_OPER) && HasUMode(client_p, UMODE_ADMIN))) + continue; + + if (HasUMode(client_p, flags)) + sendto_one(client_p, ":%s NOTICE %s :*** Notice -- %s", + me.name, client_p->name, nbuf); + } +} + +void +sendto_globops_flags(unsigned int flags, int level, const char *pattern, ...) +{ + dlink_node *ptr = NULL; + char nbuf[IRCD_BUFSIZE]; + va_list args; + + va_start(args, pattern); + vsnprintf(nbuf, IRCD_BUFSIZE, pattern, args); + va_end(args); + + DLINK_FOREACH(ptr, oper_list.head) + { + struct Client *client_p = ptr->data; + assert(client_p->umodes & UMODE_OPER); + + /* If we're sending it to opers and theyre an admin, skip. + * If we're sending it to admins, and theyre not, skip. + */ + if (((level == L_ADMIN) && !HasUMode(client_p, UMODE_ADMIN)) || + ((level == L_OPER) && HasUMode(client_p, UMODE_ADMIN))) + continue; + + if (HasUMode(client_p, flags)) + sendto_one(client_p, ":%s NOTICE %s :*** Global -- %s", + me.name, client_p->name, nbuf); + } +} + +/* sendto_wallops_flags() + * + * inputs - flag types of messages to show to real opers + * - client sending request + * - var args input message + * output - NONE + * side effects - Send a wallops to local opers + */ +void +sendto_wallops_flags(unsigned int flags, struct Client *source_p, + const char *pattern, ...) +{ + dlink_node *ptr = NULL; + va_list args; + char buffer[IRCD_BUFSIZE]; + int len; + + if (IsClient(source_p)) + len = ircsprintf(buffer, ":%s!%s@%s WALLOPS :", + source_p->name, source_p->username, source_p->host); + else + len = ircsprintf(buffer, ":%s WALLOPS :", source_p->name); + + va_start(args, pattern); + len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args); + va_end(args); + + DLINK_FOREACH(ptr, oper_list.head) + { + struct Client *client_p = ptr->data; + assert(client_p->umodes & UMODE_OPER); + + if (HasUMode(client_p, flags) && !IsDefunct(client_p)) + send_message(client_p, buffer, len); + } +} + +/* ts_warn() + * + * inputs - var args message + * output - NONE + * side effects - Call sendto_realops_flags, with some flood checking + * (at most 5 warnings every 5 seconds) + */ +void +ts_warn(const char *pattern, ...) +{ + va_list args; + char buffer[IRCD_BUFSIZE]; + static time_t last = 0; + static int warnings = 0; + + /* + ** if we're running with TS_WARNINGS enabled and someone does + ** something silly like (remotely) connecting a nonTS server, + ** we'll get a ton of warnings, so we make sure we don't send + ** more than 5 every 5 seconds. -orabidoo + */ + + if (CurrentTime - last < 5) + { + if (++warnings > 5) + return; + } + else + { + last = CurrentTime; + warnings = 0; + } + + va_start(args, pattern); + vsnprintf(buffer, sizeof(buffer), pattern, args); + va_end(args); + + sendto_realops_flags(UMODE_ALL, L_ALL, "%s", buffer); + ilog(LOG_TYPE_IRCD, "%s", buffer); +} + +/* kill_client() + * + * inputs - client to send kill towards + * - pointer to client to kill + * - reason for kill + * output - NONE + * side effects - NONE + */ +void +kill_client(struct Client *client_p, struct Client *diedie, + const char *pattern, ...) +{ + va_list args; + char buffer[IRCD_BUFSIZE]; + int len; + + if (client_p->from != NULL) + client_p = client_p->from; + if (IsDead(client_p)) + return; + + len = ircsprintf(buffer, ":%s KILL %s :", ID_or_name(&me, client_p->from), + ID_or_name(diedie, client_p)); + + va_start(args, pattern); + len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args); + va_end(args); + + send_message(client_p, buffer, len); +} + +/* kill_client_ll_serv_butone() + * + * inputs - pointer to client to not send to + * - pointer to client to kill + * output - NONE + * side effects - Send a KILL for the given client + * message to all connected servers + * except the client 'one'. Also deal with + * client being unknown to leaf, as in lazylink... + */ +void +kill_client_ll_serv_butone(struct Client *one, struct Client *source_p, + const char *pattern, ...) +{ + va_list args; + int have_uid = 0; + dlink_node *ptr = NULL; + char buf_uid[IRCD_BUFSIZE], buf_nick[IRCD_BUFSIZE]; + int len_uid = 0, len_nick = 0; + + if (HasID(source_p)) + { + have_uid = 1; + va_start(args, pattern); + len_uid = ircsprintf(buf_uid, ":%s KILL %s :", me.id, ID(source_p)); + len_uid += send_format(&buf_uid[len_uid], IRCD_BUFSIZE - len_uid, pattern, + args); + va_end(args); + } + + va_start(args, pattern); + len_nick = ircsprintf(buf_nick, ":%s KILL %s :", me.name, source_p->name); + len_nick += send_format(&buf_nick[len_nick], IRCD_BUFSIZE - len_nick, pattern, + args); + va_end(args); + + DLINK_FOREACH(ptr, serv_list.head) + { + struct Client *client_p = ptr->data; + + if (one != NULL && (client_p == one->from)) + continue; + if (IsDefunct(client_p)) + continue; + + if (have_uid && IsCapable(client_p, CAP_TS6)) + send_message(client_p, buf_uid, len_uid); + else + send_message(client_p, buf_nick, len_nick); + } +} diff --git a/src/sprintf_irc.c b/src/sprintf_irc.c new file mode 100644 index 0000000..8a3ea56 --- /dev/null +++ b/src/sprintf_irc.c @@ -0,0 +1,472 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * sprintf_irc.c: Functions for printing to a string. + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "sprintf_irc.h" +#include "irc_string.h" + + +static const char atoi_tab[4000] = { + '0','0','0',0, '0','0','1',0, '0','0','2',0, '0','0','3',0, '0','0','4',0, + '0','0','5',0, '0','0','6',0, '0','0','7',0, '0','0','8',0, '0','0','9',0, + '0','1','0',0, '0','1','1',0, '0','1','2',0, '0','1','3',0, '0','1','4',0, + '0','1','5',0, '0','1','6',0, '0','1','7',0, '0','1','8',0, '0','1','9',0, + '0','2','0',0, '0','2','1',0, '0','2','2',0, '0','2','3',0, '0','2','4',0, + '0','2','5',0, '0','2','6',0, '0','2','7',0, '0','2','8',0, '0','2','9',0, + '0','3','0',0, '0','3','1',0, '0','3','2',0, '0','3','3',0, '0','3','4',0, + '0','3','5',0, '0','3','6',0, '0','3','7',0, '0','3','8',0, '0','3','9',0, + '0','4','0',0, '0','4','1',0, '0','4','2',0, '0','4','3',0, '0','4','4',0, + '0','4','5',0, '0','4','6',0, '0','4','7',0, '0','4','8',0, '0','4','9',0, + '0','5','0',0, '0','5','1',0, '0','5','2',0, '0','5','3',0, '0','5','4',0, + '0','5','5',0, '0','5','6',0, '0','5','7',0, '0','5','8',0, '0','5','9',0, + '0','6','0',0, '0','6','1',0, '0','6','2',0, '0','6','3',0, '0','6','4',0, + '0','6','5',0, '0','6','6',0, '0','6','7',0, '0','6','8',0, '0','6','9',0, + '0','7','0',0, '0','7','1',0, '0','7','2',0, '0','7','3',0, '0','7','4',0, + '0','7','5',0, '0','7','6',0, '0','7','7',0, '0','7','8',0, '0','7','9',0, + '0','8','0',0, '0','8','1',0, '0','8','2',0, '0','8','3',0, '0','8','4',0, + '0','8','5',0, '0','8','6',0, '0','8','7',0, '0','8','8',0, '0','8','9',0, + '0','9','0',0, '0','9','1',0, '0','9','2',0, '0','9','3',0, '0','9','4',0, + '0','9','5',0, '0','9','6',0, '0','9','7',0, '0','9','8',0, '0','9','9',0, + '1','0','0',0, '1','0','1',0, '1','0','2',0, '1','0','3',0, '1','0','4',0, + '1','0','5',0, '1','0','6',0, '1','0','7',0, '1','0','8',0, '1','0','9',0, + '1','1','0',0, '1','1','1',0, '1','1','2',0, '1','1','3',0, '1','1','4',0, + '1','1','5',0, '1','1','6',0, '1','1','7',0, '1','1','8',0, '1','1','9',0, + '1','2','0',0, '1','2','1',0, '1','2','2',0, '1','2','3',0, '1','2','4',0, + '1','2','5',0, '1','2','6',0, '1','2','7',0, '1','2','8',0, '1','2','9',0, + '1','3','0',0, '1','3','1',0, '1','3','2',0, '1','3','3',0, '1','3','4',0, + '1','3','5',0, '1','3','6',0, '1','3','7',0, '1','3','8',0, '1','3','9',0, + '1','4','0',0, '1','4','1',0, '1','4','2',0, '1','4','3',0, '1','4','4',0, + '1','4','5',0, '1','4','6',0, '1','4','7',0, '1','4','8',0, '1','4','9',0, + '1','5','0',0, '1','5','1',0, '1','5','2',0, '1','5','3',0, '1','5','4',0, + '1','5','5',0, '1','5','6',0, '1','5','7',0, '1','5','8',0, '1','5','9',0, + '1','6','0',0, '1','6','1',0, '1','6','2',0, '1','6','3',0, '1','6','4',0, + '1','6','5',0, '1','6','6',0, '1','6','7',0, '1','6','8',0, '1','6','9',0, + '1','7','0',0, '1','7','1',0, '1','7','2',0, '1','7','3',0, '1','7','4',0, + '1','7','5',0, '1','7','6',0, '1','7','7',0, '1','7','8',0, '1','7','9',0, + '1','8','0',0, '1','8','1',0, '1','8','2',0, '1','8','3',0, '1','8','4',0, + '1','8','5',0, '1','8','6',0, '1','8','7',0, '1','8','8',0, '1','8','9',0, + '1','9','0',0, '1','9','1',0, '1','9','2',0, '1','9','3',0, '1','9','4',0, + '1','9','5',0, '1','9','6',0, '1','9','7',0, '1','9','8',0, '1','9','9',0, + '2','0','0',0, '2','0','1',0, '2','0','2',0, '2','0','3',0, '2','0','4',0, + '2','0','5',0, '2','0','6',0, '2','0','7',0, '2','0','8',0, '2','0','9',0, + '2','1','0',0, '2','1','1',0, '2','1','2',0, '2','1','3',0, '2','1','4',0, + '2','1','5',0, '2','1','6',0, '2','1','7',0, '2','1','8',0, '2','1','9',0, + '2','2','0',0, '2','2','1',0, '2','2','2',0, '2','2','3',0, '2','2','4',0, + '2','2','5',0, '2','2','6',0, '2','2','7',0, '2','2','8',0, '2','2','9',0, + '2','3','0',0, '2','3','1',0, '2','3','2',0, '2','3','3',0, '2','3','4',0, + '2','3','5',0, '2','3','6',0, '2','3','7',0, '2','3','8',0, '2','3','9',0, + '2','4','0',0, '2','4','1',0, '2','4','2',0, '2','4','3',0, '2','4','4',0, + '2','4','5',0, '2','4','6',0, '2','4','7',0, '2','4','8',0, '2','4','9',0, + '2','5','0',0, '2','5','1',0, '2','5','2',0, '2','5','3',0, '2','5','4',0, + '2','5','5',0, '2','5','6',0, '2','5','7',0, '2','5','8',0, '2','5','9',0, + '2','6','0',0, '2','6','1',0, '2','6','2',0, '2','6','3',0, '2','6','4',0, + '2','6','5',0, '2','6','6',0, '2','6','7',0, '2','6','8',0, '2','6','9',0, + '2','7','0',0, '2','7','1',0, '2','7','2',0, '2','7','3',0, '2','7','4',0, + '2','7','5',0, '2','7','6',0, '2','7','7',0, '2','7','8',0, '2','7','9',0, + '2','8','0',0, '2','8','1',0, '2','8','2',0, '2','8','3',0, '2','8','4',0, + '2','8','5',0, '2','8','6',0, '2','8','7',0, '2','8','8',0, '2','8','9',0, + '2','9','0',0, '2','9','1',0, '2','9','2',0, '2','9','3',0, '2','9','4',0, + '2','9','5',0, '2','9','6',0, '2','9','7',0, '2','9','8',0, '2','9','9',0, + '3','0','0',0, '3','0','1',0, '3','0','2',0, '3','0','3',0, '3','0','4',0, + '3','0','5',0, '3','0','6',0, '3','0','7',0, '3','0','8',0, '3','0','9',0, + '3','1','0',0, '3','1','1',0, '3','1','2',0, '3','1','3',0, '3','1','4',0, + '3','1','5',0, '3','1','6',0, '3','1','7',0, '3','1','8',0, '3','1','9',0, + '3','2','0',0, '3','2','1',0, '3','2','2',0, '3','2','3',0, '3','2','4',0, + '3','2','5',0, '3','2','6',0, '3','2','7',0, '3','2','8',0, '3','2','9',0, + '3','3','0',0, '3','3','1',0, '3','3','2',0, '3','3','3',0, '3','3','4',0, + '3','3','5',0, '3','3','6',0, '3','3','7',0, '3','3','8',0, '3','3','9',0, + '3','4','0',0, '3','4','1',0, '3','4','2',0, '3','4','3',0, '3','4','4',0, + '3','4','5',0, '3','4','6',0, '3','4','7',0, '3','4','8',0, '3','4','9',0, + '3','5','0',0, '3','5','1',0, '3','5','2',0, '3','5','3',0, '3','5','4',0, + '3','5','5',0, '3','5','6',0, '3','5','7',0, '3','5','8',0, '3','5','9',0, + '3','6','0',0, '3','6','1',0, '3','6','2',0, '3','6','3',0, '3','6','4',0, + '3','6','5',0, '3','6','6',0, '3','6','7',0, '3','6','8',0, '3','6','9',0, + '3','7','0',0, '3','7','1',0, '3','7','2',0, '3','7','3',0, '3','7','4',0, + '3','7','5',0, '3','7','6',0, '3','7','7',0, '3','7','8',0, '3','7','9',0, + '3','8','0',0, '3','8','1',0, '3','8','2',0, '3','8','3',0, '3','8','4',0, + '3','8','5',0, '3','8','6',0, '3','8','7',0, '3','8','8',0, '3','8','9',0, + '3','9','0',0, '3','9','1',0, '3','9','2',0, '3','9','3',0, '3','9','4',0, + '3','9','5',0, '3','9','6',0, '3','9','7',0, '3','9','8',0, '3','9','9',0, + '4','0','0',0, '4','0','1',0, '4','0','2',0, '4','0','3',0, '4','0','4',0, + '4','0','5',0, '4','0','6',0, '4','0','7',0, '4','0','8',0, '4','0','9',0, + '4','1','0',0, '4','1','1',0, '4','1','2',0, '4','1','3',0, '4','1','4',0, + '4','1','5',0, '4','1','6',0, '4','1','7',0, '4','1','8',0, '4','1','9',0, + '4','2','0',0, '4','2','1',0, '4','2','2',0, '4','2','3',0, '4','2','4',0, + '4','2','5',0, '4','2','6',0, '4','2','7',0, '4','2','8',0, '4','2','9',0, + '4','3','0',0, '4','3','1',0, '4','3','2',0, '4','3','3',0, '4','3','4',0, + '4','3','5',0, '4','3','6',0, '4','3','7',0, '4','3','8',0, '4','3','9',0, + '4','4','0',0, '4','4','1',0, '4','4','2',0, '4','4','3',0, '4','4','4',0, + '4','4','5',0, '4','4','6',0, '4','4','7',0, '4','4','8',0, '4','4','9',0, + '4','5','0',0, '4','5','1',0, '4','5','2',0, '4','5','3',0, '4','5','4',0, + '4','5','5',0, '4','5','6',0, '4','5','7',0, '4','5','8',0, '4','5','9',0, + '4','6','0',0, '4','6','1',0, '4','6','2',0, '4','6','3',0, '4','6','4',0, + '4','6','5',0, '4','6','6',0, '4','6','7',0, '4','6','8',0, '4','6','9',0, + '4','7','0',0, '4','7','1',0, '4','7','2',0, '4','7','3',0, '4','7','4',0, + '4','7','5',0, '4','7','6',0, '4','7','7',0, '4','7','8',0, '4','7','9',0, + '4','8','0',0, '4','8','1',0, '4','8','2',0, '4','8','3',0, '4','8','4',0, + '4','8','5',0, '4','8','6',0, '4','8','7',0, '4','8','8',0, '4','8','9',0, + '4','9','0',0, '4','9','1',0, '4','9','2',0, '4','9','3',0, '4','9','4',0, + '4','9','5',0, '4','9','6',0, '4','9','7',0, '4','9','8',0, '4','9','9',0, + '5','0','0',0, '5','0','1',0, '5','0','2',0, '5','0','3',0, '5','0','4',0, + '5','0','5',0, '5','0','6',0, '5','0','7',0, '5','0','8',0, '5','0','9',0, + '5','1','0',0, '5','1','1',0, '5','1','2',0, '5','1','3',0, '5','1','4',0, + '5','1','5',0, '5','1','6',0, '5','1','7',0, '5','1','8',0, '5','1','9',0, + '5','2','0',0, '5','2','1',0, '5','2','2',0, '5','2','3',0, '5','2','4',0, + '5','2','5',0, '5','2','6',0, '5','2','7',0, '5','2','8',0, '5','2','9',0, + '5','3','0',0, '5','3','1',0, '5','3','2',0, '5','3','3',0, '5','3','4',0, + '5','3','5',0, '5','3','6',0, '5','3','7',0, '5','3','8',0, '5','3','9',0, + '5','4','0',0, '5','4','1',0, '5','4','2',0, '5','4','3',0, '5','4','4',0, + '5','4','5',0, '5','4','6',0, '5','4','7',0, '5','4','8',0, '5','4','9',0, + '5','5','0',0, '5','5','1',0, '5','5','2',0, '5','5','3',0, '5','5','4',0, + '5','5','5',0, '5','5','6',0, '5','5','7',0, '5','5','8',0, '5','5','9',0, + '5','6','0',0, '5','6','1',0, '5','6','2',0, '5','6','3',0, '5','6','4',0, + '5','6','5',0, '5','6','6',0, '5','6','7',0, '5','6','8',0, '5','6','9',0, + '5','7','0',0, '5','7','1',0, '5','7','2',0, '5','7','3',0, '5','7','4',0, + '5','7','5',0, '5','7','6',0, '5','7','7',0, '5','7','8',0, '5','7','9',0, + '5','8','0',0, '5','8','1',0, '5','8','2',0, '5','8','3',0, '5','8','4',0, + '5','8','5',0, '5','8','6',0, '5','8','7',0, '5','8','8',0, '5','8','9',0, + '5','9','0',0, '5','9','1',0, '5','9','2',0, '5','9','3',0, '5','9','4',0, + '5','9','5',0, '5','9','6',0, '5','9','7',0, '5','9','8',0, '5','9','9',0, + '6','0','0',0, '6','0','1',0, '6','0','2',0, '6','0','3',0, '6','0','4',0, + '6','0','5',0, '6','0','6',0, '6','0','7',0, '6','0','8',0, '6','0','9',0, + '6','1','0',0, '6','1','1',0, '6','1','2',0, '6','1','3',0, '6','1','4',0, + '6','1','5',0, '6','1','6',0, '6','1','7',0, '6','1','8',0, '6','1','9',0, + '6','2','0',0, '6','2','1',0, '6','2','2',0, '6','2','3',0, '6','2','4',0, + '6','2','5',0, '6','2','6',0, '6','2','7',0, '6','2','8',0, '6','2','9',0, + '6','3','0',0, '6','3','1',0, '6','3','2',0, '6','3','3',0, '6','3','4',0, + '6','3','5',0, '6','3','6',0, '6','3','7',0, '6','3','8',0, '6','3','9',0, + '6','4','0',0, '6','4','1',0, '6','4','2',0, '6','4','3',0, '6','4','4',0, + '6','4','5',0, '6','4','6',0, '6','4','7',0, '6','4','8',0, '6','4','9',0, + '6','5','0',0, '6','5','1',0, '6','5','2',0, '6','5','3',0, '6','5','4',0, + '6','5','5',0, '6','5','6',0, '6','5','7',0, '6','5','8',0, '6','5','9',0, + '6','6','0',0, '6','6','1',0, '6','6','2',0, '6','6','3',0, '6','6','4',0, + '6','6','5',0, '6','6','6',0, '6','6','7',0, '6','6','8',0, '6','6','9',0, + '6','7','0',0, '6','7','1',0, '6','7','2',0, '6','7','3',0, '6','7','4',0, + '6','7','5',0, '6','7','6',0, '6','7','7',0, '6','7','8',0, '6','7','9',0, + '6','8','0',0, '6','8','1',0, '6','8','2',0, '6','8','3',0, '6','8','4',0, + '6','8','5',0, '6','8','6',0, '6','8','7',0, '6','8','8',0, '6','8','9',0, + '6','9','0',0, '6','9','1',0, '6','9','2',0, '6','9','3',0, '6','9','4',0, + '6','9','5',0, '6','9','6',0, '6','9','7',0, '6','9','8',0, '6','9','9',0, + '7','0','0',0, '7','0','1',0, '7','0','2',0, '7','0','3',0, '7','0','4',0, + '7','0','5',0, '7','0','6',0, '7','0','7',0, '7','0','8',0, '7','0','9',0, + '7','1','0',0, '7','1','1',0, '7','1','2',0, '7','1','3',0, '7','1','4',0, + '7','1','5',0, '7','1','6',0, '7','1','7',0, '7','1','8',0, '7','1','9',0, + '7','2','0',0, '7','2','1',0, '7','2','2',0, '7','2','3',0, '7','2','4',0, + '7','2','5',0, '7','2','6',0, '7','2','7',0, '7','2','8',0, '7','2','9',0, + '7','3','0',0, '7','3','1',0, '7','3','2',0, '7','3','3',0, '7','3','4',0, + '7','3','5',0, '7','3','6',0, '7','3','7',0, '7','3','8',0, '7','3','9',0, + '7','4','0',0, '7','4','1',0, '7','4','2',0, '7','4','3',0, '7','4','4',0, + '7','4','5',0, '7','4','6',0, '7','4','7',0, '7','4','8',0, '7','4','9',0, + '7','5','0',0, '7','5','1',0, '7','5','2',0, '7','5','3',0, '7','5','4',0, + '7','5','5',0, '7','5','6',0, '7','5','7',0, '7','5','8',0, '7','5','9',0, + '7','6','0',0, '7','6','1',0, '7','6','2',0, '7','6','3',0, '7','6','4',0, + '7','6','5',0, '7','6','6',0, '7','6','7',0, '7','6','8',0, '7','6','9',0, + '7','7','0',0, '7','7','1',0, '7','7','2',0, '7','7','3',0, '7','7','4',0, + '7','7','5',0, '7','7','6',0, '7','7','7',0, '7','7','8',0, '7','7','9',0, + '7','8','0',0, '7','8','1',0, '7','8','2',0, '7','8','3',0, '7','8','4',0, + '7','8','5',0, '7','8','6',0, '7','8','7',0, '7','8','8',0, '7','8','9',0, + '7','9','0',0, '7','9','1',0, '7','9','2',0, '7','9','3',0, '7','9','4',0, + '7','9','5',0, '7','9','6',0, '7','9','7',0, '7','9','8',0, '7','9','9',0, + '8','0','0',0, '8','0','1',0, '8','0','2',0, '8','0','3',0, '8','0','4',0, + '8','0','5',0, '8','0','6',0, '8','0','7',0, '8','0','8',0, '8','0','9',0, + '8','1','0',0, '8','1','1',0, '8','1','2',0, '8','1','3',0, '8','1','4',0, + '8','1','5',0, '8','1','6',0, '8','1','7',0, '8','1','8',0, '8','1','9',0, + '8','2','0',0, '8','2','1',0, '8','2','2',0, '8','2','3',0, '8','2','4',0, + '8','2','5',0, '8','2','6',0, '8','2','7',0, '8','2','8',0, '8','2','9',0, + '8','3','0',0, '8','3','1',0, '8','3','2',0, '8','3','3',0, '8','3','4',0, + '8','3','5',0, '8','3','6',0, '8','3','7',0, '8','3','8',0, '8','3','9',0, + '8','4','0',0, '8','4','1',0, '8','4','2',0, '8','4','3',0, '8','4','4',0, + '8','4','5',0, '8','4','6',0, '8','4','7',0, '8','4','8',0, '8','4','9',0, + '8','5','0',0, '8','5','1',0, '8','5','2',0, '8','5','3',0, '8','5','4',0, + '8','5','5',0, '8','5','6',0, '8','5','7',0, '8','5','8',0, '8','5','9',0, + '8','6','0',0, '8','6','1',0, '8','6','2',0, '8','6','3',0, '8','6','4',0, + '8','6','5',0, '8','6','6',0, '8','6','7',0, '8','6','8',0, '8','6','9',0, + '8','7','0',0, '8','7','1',0, '8','7','2',0, '8','7','3',0, '8','7','4',0, + '8','7','5',0, '8','7','6',0, '8','7','7',0, '8','7','8',0, '8','7','9',0, + '8','8','0',0, '8','8','1',0, '8','8','2',0, '8','8','3',0, '8','8','4',0, + '8','8','5',0, '8','8','6',0, '8','8','7',0, '8','8','8',0, '8','8','9',0, + '8','9','0',0, '8','9','1',0, '8','9','2',0, '8','9','3',0, '8','9','4',0, + '8','9','5',0, '8','9','6',0, '8','9','7',0, '8','9','8',0, '8','9','9',0, + '9','0','0',0, '9','0','1',0, '9','0','2',0, '9','0','3',0, '9','0','4',0, + '9','0','5',0, '9','0','6',0, '9','0','7',0, '9','0','8',0, '9','0','9',0, + '9','1','0',0, '9','1','1',0, '9','1','2',0, '9','1','3',0, '9','1','4',0, + '9','1','5',0, '9','1','6',0, '9','1','7',0, '9','1','8',0, '9','1','9',0, + '9','2','0',0, '9','2','1',0, '9','2','2',0, '9','2','3',0, '9','2','4',0, + '9','2','5',0, '9','2','6',0, '9','2','7',0, '9','2','8',0, '9','2','9',0, + '9','3','0',0, '9','3','1',0, '9','3','2',0, '9','3','3',0, '9','3','4',0, + '9','3','5',0, '9','3','6',0, '9','3','7',0, '9','3','8',0, '9','3','9',0, + '9','4','0',0, '9','4','1',0, '9','4','2',0, '9','4','3',0, '9','4','4',0, + '9','4','5',0, '9','4','6',0, '9','4','7',0, '9','4','8',0, '9','4','9',0, + '9','5','0',0, '9','5','1',0, '9','5','2',0, '9','5','3',0, '9','5','4',0, + '9','5','5',0, '9','5','6',0, '9','5','7',0, '9','5','8',0, '9','5','9',0, + '9','6','0',0, '9','6','1',0, '9','6','2',0, '9','6','3',0, '9','6','4',0, + '9','6','5',0, '9','6','6',0, '9','6','7',0, '9','6','8',0, '9','6','9',0, + '9','7','0',0, '9','7','1',0, '9','7','2',0, '9','7','3',0, '9','7','4',0, + '9','7','5',0, '9','7','6',0, '9','7','7',0, '9','7','8',0, '9','7','9',0, + '9','8','0',0, '9','8','1',0, '9','8','2',0, '9','8','3',0, '9','8','4',0, + '9','8','5',0, '9','8','6',0, '9','8','7',0, '9','8','8',0, '9','8','9',0, + '9','9','0',0, '9','9','1',0, '9','9','2',0, '9','9','3',0, '9','9','4',0, + '9','9','5',0, '9','9','6',0, '9','9','7',0, '9','9','8',0, '9','9','9',0 +}; + +static char scratch_buffer[32]; + +/* + * sprintf_irc + * + * sprintf_irc is optimized for the formats: %c, %s, %lu, %d and %u. + * Where %lu actually equals %l09u (for printing time_t timestamps). + * + * sprintf_irc is NOT optimized for any other format and resorts to using + * the normal sprintf when it encounters a format it doesn't understand + * (including padding, width, precision etc). + * + * The following benchmark was measured on a PPro200 with linux 2.0.30, + * libc 5.4.28, compiled with gcc-2.7.2.1 with -O3. + * + * Format sprintf sprintf_irc Speed up factor + * + * "12345678901234567890" 3.385 us 0.859 us 3.94 + * "%s", buffer (20 chars) 3.780 us 0.547 us 6.91 + * "%c%c%c", c1, c2, c3 3.640 us 0.376 us 9.68 + * "%lu", (time_t)t 5.851 us 0.842 us 6.95 + * + * Less important: + * "%d", 31337 4.487 us 0.852 us 5.27 + * "%u.%u.%u.%u", 9.069 us 2.431 us 3.73 + * + * Not used: + * "%03d", 401 4.348 us + * "%N" 0.216 us 20.13 + * + * --Run + */ + +int +vsprintf_irc(char *str, const char *format, va_list args) +{ + char c; + int bytes = 0; + + while ((c = *format++)) + { + if (c == '%') + { + c = *format++; /* May never be '\0' ! */ + + if (c == 's') + { + const char *p1 = va_arg(args, const char *); + if ((*str = *p1)) + { + ++bytes; + while ((*++str = *++p1)) + ++bytes; + } + + continue; + } + + if (c == 'c') + { + *str++ = (char) va_arg(args, int); + ++bytes; + + continue; + } + + /* + * Prints time_t value in interval + * [ 100000000 , 4294967295 ] + * Actually prints like "%09lu" + */ + if (c == 'l' && *format == 'u') + { + unsigned long v1, v2; + const char *ap; + + ++format; + v1 = va_arg(args, unsigned long); + if (v1 == 0) + { + *str++ = '0'; + ++bytes; + continue; + } + if (v1 > 999999999L) + { + v2 = v1 / 1000000000; + v1 -= v2 * 1000000000; + *str++ = '0' + v2; + ++bytes; + } + + v2 = v1 / 1000000; + v1 -= v2 * 1000000; + ap = atoi_tab + (v2 << 2); + *str++ = *ap++; + *str++ = *ap++; + *str++ = *ap; + v2 = v1 / 1000; + v1 -= v2 * 1000; + ap = atoi_tab + (v2 << 2); + *str++ = *ap++; + *str++ = *ap++; + *str++ = *ap; + ap = atoi_tab + (v1 << 2); + *str++ = *ap++; + *str++ = *ap++; + *str++ = *ap; + + bytes += 9; + + continue; + } + if (c == 't') + { + unsigned int v1; + + v1 = va_arg(args,int); + + *str++ = (v1/10) + '0'; + *str++ = v1%10 + '0'; + + bytes += 2; + + continue; + } + + if (c == 'd') + { + unsigned int v1, v2; + const char *ap; + char *s = &scratch_buffer[sizeof(scratch_buffer) - 2]; + + v1 = va_arg(args, int); + if ((int)v1 <= 0) + { + if (v1 == 0) + { + *str++ = '0'; + ++bytes; + continue; + } + *str++ = '-'; + ++bytes; + v1 = -v1; + } + + do + { + v2 = v1 / 1000; + ap = atoi_tab + 2 + ((v1 - 1000 * v2) << 2); + *s-- = *ap--; + *s-- = *ap--; + *s-- = *ap; + } + while ((v1 = v2) > 0); + + while ('0' == *++s); + + *str = *s; + ++bytes; + + while ((*++str = *++s)) + ++bytes; + + continue; + } + + if (c == 'u') + { + unsigned int v1, v2; + const char *ap; + char *s = &scratch_buffer[sizeof(scratch_buffer) - 2]; + + v1 = va_arg(args, unsigned int); + if (v1 == 0) + { + *str++ = '0'; + ++bytes; + continue; + } + + do + { + v2 = v1 / 1000; + ap = atoi_tab + 2 + ((v1 - 1000 * v2) << 2); + *s-- = *ap--; + *s-- = *ap--; + *s-- = *ap; + } + while ((v1 = v2) > 0); + + while ('0' == *++s); + + *str = *s; + ++bytes; + + while ((*++str = *++s)) + ++bytes; + + continue; + } + + if (c != '%') + { + int ret; + + format -= 2; + ret = vsprintf(str, format, args); + str += ret; + bytes += ret; + + break; + } + } + + *str++ = c; + ++bytes; + } + + *str = '\0'; + + return(bytes); +} /* vsprintf_irc() */ + +int +ircsprintf(char *str, const char *format, ...) +{ + va_list args; + int bytes; + + va_start(args, format); + + bytes = vsprintf_irc(str, format, args); + + va_end(args); + + return(bytes); +} /* ircsprintf() */ + diff --git a/src/version.c b/src/version.c new file mode 100644 index 0000000..f80cca5 --- /dev/null +++ b/src/version.c @@ -0,0 +1,105 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 2002 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "patchlevel.h" +#include "serno.h" +#include "ircd.h" + +const char *ircd_version = PATCHLEVEL; +const char *serno = SERIALNUM; + +const char *infotext[] = +{ + "IRC --", + "Based on the original code written by Jarkko Oikarinen", + "Copyright 1988, 1989, 1990, 1991 University of Oulu, Computing Center", + "Copyright (c) 1997-2012 Hybrid 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, or", + "(at your option) any later version.", + "", + "", + "The hybrid team is a group of ircd coders who were frustrated", + "with the instability and all-out dirtiness of the EFnet ircd's", + "available. hybrid is the name for the collective efforts of a group", + "of people, all of us.", + "", + "Anyone is welcome to contribute to this effort. You are encouraged", + "to participate in the Hybrid mailing list. To subscribe to the", + "Hybrid List, use this link:", + " https://lists.ircd-hybrid.org/mailman/listinfo/hybrid", + "", + "The core team as, of this major release:", + "", + "billy-jon, William Bierman III <bill@mu.org>", + "cryogen, Stuart Walsh <stu@ipng.org.uk>", + "Dianora, Diane Bruce <db@db.net>", + "metalrock, Jack Low <jclow@csupomona.edu>", + "Michael, Michael Wobst <michael@wobst.at>", + "Rodder, Jon Lusky <lusky@blown.net>", + "Wohali, Joan Touzet <joant@ieee.org>", + "", + "The following people have contributed blood, sweat, and/or code to", + "recent releases of Hybrid, in nick alphabetical order:", + "", + "A1kmm, Andrew Miller <a1kmm@mware.virtualave.net>", + "adx, Piotr Nizynski <nizynski@sysplex.pl>", + "AndroSyn, Aaron Sethman <androsyn@ratbox.org>", + "bane, Dragan Dosen <bane@idolnet.org>", + "bysin, Ben Kittridge <bkittridge@cfl.rr.com>", + "cosine, Patrick Alken <wnder@uwns.underworld.net>", + "David-T, David Taylor <davidt@yadt.co.uk>", + "fgeek, Henri Salo <henri@nerv.fi>", + "fl, Lee Hardy <lee@leeh.co.uk>", + "Garion, Joost Vunderink <garion@efnet.nl>", + "Habeeb, David Supuran <habeeb@cfl.rr.com>", + "Hwy101, W. Campbell <wcampbel@botbay.net>", + "jmallett, Juli Mallett <jmallett@FreeBSD.org>", + "joshk, Joshua Kwan <joshk@triplehelix.org>", + "jv, Jakub Vlasek <jv@pilsedu.cz>", + "k9, Jeremy Chadwick <ircd@jdc.parodius.com>", + "kire, Erik Small <smalle@hawaii.edu>", + "knight, Alan LeVee <alan.levee@prometheus-designs.net>", + "kre, Dinko Korunic <kreator@fly.srk.fer.hr>", + "madmax, Paul Lomax <madmax@efnet.org>", + "nenolod, William Pitcock <nenolod@nenolod.net>", + "Riedel, Dennis Vink, <riedel@chaotic.nl>", + "scuzzy, David Todd <scuzzy@aniverse.net>", + "spookey, David Colburn <spookey@spookey.org>", + "TimeMr14C, Yusuf Iskenderoglu <uhc0@stud.uni-karlsruhe.de>", + "toot, Toby Verrall <to7@antipope.fsnet.co.uk>", + "vx0, Mark Miller <mark@oc768.net>", + "wiz, Jason Dambrosio <jason@wiz.cx>", + "Xride, Søren Straarup <xride@x12.dk>", + "zb^3, Alfred Perlstein <alfred@freebsd.org>", + "", + "Others are welcome. Always. And if we left anyone off the above list,", + "be sure to let us know that too. Many others have contributed to", + "previous versions of this ircd and its ancestors, too many to list", + "here.", + "", + "Send bug fixes/complaints/rotten tomatoes to bugs@ircd-hybrid.org.", + "", 0 +}; diff --git a/src/watch.c b/src/watch.c new file mode 100644 index 0000000..ba7db13 --- /dev/null +++ b/src/watch.c @@ -0,0 +1,235 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * + * Copyright (C) 1997 Jukka Santala (Donwulff) + * Copyright (C) 2005 by the Hybrid 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 + */ + +/*! \file watch.c + * \brief File including functions for WATCH support + * \version $Id$ + */ + +#include "stdinc.h" +#include "list.h" +#include "balloc.h" +#include "s_user.h" +#include "s_misc.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "sprintf_irc.h" +#include "ircd.h" +#include "numeric.h" +#include "conf.h" +#include "s_serv.h" +#include "send.h" +#include "supported.h" +#include "whowas.h" +#include "memory.h" +#include "packet.h" +#include "watch.h" + +#define WATCH_HEAP_SIZE 32 + +static dlink_list watchTable[HASHSIZE]; + +static BlockHeap *watch_heap = NULL; + +/*! \brief Initializes the watch table + */ +void +watch_init(void) +{ + watch_heap = BlockHeapCreate("watch", sizeof(struct Watch), WATCH_HEAP_SIZE); +} + +/* + * Rough figure of the datastructures for watch: + * + * NOTIFY HASH client_p1 + * | |- nick1 + * nick1-|- client_p1 |- nick2 + * | |- client_p2 client_p3 + * | |- client_p3 client_p2 |- nick1 + * | |- nick1 + * nick2-|- client_p2 |- nick2 + * |- client_p1 + */ + +/*! \brief Counts up memory used by watch list headers + */ +void +watch_count_memory(unsigned int *const count, uint64_t *const memory) +{ + unsigned int idx; + + for (idx = 0; idx < HASHSIZE; ++idx) + *count += dlink_list_length(&watchTable[idx]); + + *memory = *count * sizeof(struct Watch); +} + +/*! \brief Notifies all clients that have client_p's nick name on + * their watch list. + * \param client_p pointer to Client struct + * \param reply numeric to send. Either RPL_LOGON or RPL_LOGOFF + */ +void +watch_check_hash(struct Client *client_p, int reply) +{ + struct Watch *anptr = NULL; + dlink_node *ptr = NULL; + assert(IsClient(client_p)); + if ((anptr = watch_find_hash(client_p->name)) == NULL) + return; /* This nick isn't on watch */ + + /* Update the time of last change to item */ + anptr->lasttime = CurrentTime; + + /* Send notifies out to everybody on the list in header */ + DLINK_FOREACH(ptr, anptr->watched_by.head) + { + struct Client *target_p = ptr->data; + + sendto_one(target_p, form_str(reply), + me.name, target_p->name, client_p->name, + client_p->username, client_p->host, + anptr->lasttime, client_p->info); + } +} + +/*! \brief Looks up the watch table for a given nick + * \param name nick name to look up + */ +struct Watch * +watch_find_hash(const char *name) +{ + dlink_node *ptr = NULL; + + DLINK_FOREACH(ptr, watchTable[strhash(name)].head) + { + struct Watch *anptr = ptr->data; + + if (!irccmp(anptr->nick, name)) + return anptr; + } + + return NULL; +} + +/*! \brief Adds a watch entry to client_p's watch list + * \param nick nick name to add + * \param client_p Pointer to Client struct + */ +void +watch_add_to_hash_table(const char *nick, struct Client *client_p) +{ + struct Watch *anptr = NULL; + dlink_node *ptr = NULL; + + /* If found NULL (no header for this nick), make one... */ + if ((anptr = watch_find_hash(nick)) == NULL) + { + anptr = BlockHeapAlloc(watch_heap); + anptr->lasttime = CurrentTime; + strlcpy(anptr->nick, nick, sizeof(anptr->nick)); + + dlinkAdd(anptr, &anptr->node, &watchTable[strhash(nick)]); + } + else + { + /* Is this client already on the watch-list? */ + ptr = dlinkFind(&anptr->watched_by, client_p); + } + + if (ptr == NULL) + { + /* No it isn't, so add it in the bucket and client addint it */ + dlinkAdd(client_p, make_dlink_node(), &anptr->watched_by); + dlinkAdd(anptr, make_dlink_node(), &client_p->localClient->watches); + } +} + +/*! \brief Removes a single entry from client_p's watch list + * \param nick nick name to remove + * \param client_p Pointer to Client struct + */ +void +watch_del_from_hash_table(const char *nick, struct Client *client_p) +{ + struct Watch *anptr = NULL; + dlink_node *ptr = NULL; + + if ((anptr = watch_find_hash(nick)) == NULL) + return; /* No header found for that nick. i.e. it's not being watched */ + + if ((ptr = dlinkFind(&anptr->watched_by, client_p)) == NULL) + return; /* This nick isn't being watched by client_p */ + + dlinkDelete(ptr, &anptr->watched_by); + free_dlink_node(ptr); + + if ((ptr = dlinkFindDelete(&client_p->localClient->watches, anptr))) + free_dlink_node(ptr); + + /* In case this header is now empty of notices, remove it */ + if (anptr->watched_by.head == NULL) + { + assert(dlinkFind(&watchTable[strhash(nick)], anptr) != NULL); + dlinkDelete(&anptr->node, &watchTable[strhash(nick)]); + BlockHeapFree(watch_heap, anptr); + } +} + +/*! \brief Removes all entries from client_p's watch list + * and deletes headers that are no longer being watched. + * \param client_p Pointer to Client struct + */ +void +watch_del_watch_list(struct Client *client_p) +{ + dlink_node *ptr = NULL, *ptr_next = NULL; + dlink_node *tmp = NULL; + + DLINK_FOREACH_SAFE(ptr, ptr_next, client_p->localClient->watches.head) + { + struct Watch *anptr = ptr->data; + + assert(anptr); + + assert(dlinkFind(&anptr->watched_by, client_p) != NULL); + if ((tmp = dlinkFindDelete(&anptr->watched_by, client_p))) + free_dlink_node(tmp); + + /* If this leaves a header without notifies, remove it. */ + if (anptr->watched_by.head == NULL) + { + assert(dlinkFind(&watchTable[strhash(anptr->nick)], anptr) != NULL); + dlinkDelete(&anptr->node, &watchTable[strhash(anptr->nick)]); + + BlockHeapFree(watch_heap, anptr); + } + + dlinkDelete(ptr, &client_p->localClient->watches); + free_dlink_node(ptr); + } + + assert(client_p->localClient->watches.head == NULL); + assert(client_p->localClient->watches.tail == NULL); +} diff --git a/src/whowas.c b/src/whowas.c new file mode 100644 index 0000000..7d0e087 --- /dev/null +++ b/src/whowas.c @@ -0,0 +1,142 @@ +/* + * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). + * whowas.c: WHOWAS user cache. + * + * Copyright (C) 2005 by the past and present ircd coders, and others. + * + * 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$ + */ + +#include "stdinc.h" +#include "list.h" +#include "whowas.h" +#include "client.h" +#include "hash.h" +#include "irc_string.h" +#include "ircd.h" + + +static struct Whowas WHOWAS[NICKNAMEHISTORYLENGTH]; +dlink_list WHOWASHASH[HASHSIZE]; + + +void +add_history(struct Client *client_p, int online) +{ + static unsigned int whowas_next = 0; + struct Whowas *who = &WHOWAS[whowas_next]; + + assert(client_p && client_p->servptr); + + if (++whowas_next == NICKNAMEHISTORYLENGTH) + whowas_next = 0; + + if (who->hashv != -1) + { + if (who->online) + dlinkDelete(&who->cnode, &who->online->whowas); + + dlinkDelete(&who->tnode, &WHOWASHASH[who->hashv]); + } + + who->hashv = strhash(client_p->name); + who->logoff = CurrentTime; + + strlcpy(who->name, client_p->name, sizeof(who->name)); + strlcpy(who->username, client_p->username, sizeof(who->username)); + strlcpy(who->hostname, client_p->host, sizeof(who->hostname)); + strlcpy(who->realname, client_p->info, sizeof(who->realname)); + strlcpy(who->servername, client_p->servptr->name, sizeof(who->servername)); + + if (online) + { + who->online = client_p; + dlinkAdd(who, &who->cnode, &client_p->whowas); + } + else + who->online = NULL; + + dlinkAdd(who, &who->tnode, &WHOWASHASH[who->hashv]); +} + +void +off_history(struct Client *client_p) +{ + dlink_node *ptr = NULL, *ptr_next = NULL; + + DLINK_FOREACH_SAFE(ptr, ptr_next, client_p->whowas.head) + { + struct Whowas *temp = ptr->data; + + temp->online = NULL; + dlinkDelete(&temp->cnode, &client_p->whowas); + } +} + +struct Client * +get_history(const char *nick, time_t timelimit) +{ + dlink_node *ptr = NULL; + + timelimit = CurrentTime - timelimit; + + DLINK_FOREACH(ptr, WHOWASHASH[strhash(nick)].head) + { + struct Whowas *temp = ptr->data; + + if (temp->logoff < timelimit) + continue; + if (irccmp(nick, temp->name)) + continue; + return temp->online; + } + + return NULL; +} + +void +count_whowas_memory(unsigned int *wwu, uint64_t *wwum) +{ + const struct Whowas *tmp; + int i; + unsigned int u = 0; + uint64_t um = 0; + + /* count the number of used whowas structs in 'u' */ + /* count up the memory used of whowas structs in um */ + for (i = 0, tmp = &WHOWAS[0]; i < NICKNAMEHISTORYLENGTH; ++i, ++tmp) + { + if (tmp->hashv != -1) + { + ++u; + um += sizeof(struct Whowas); + } + } + + *wwu = u; + *wwum = um; +} + +void +whowas_init(void) +{ + unsigned int idx; + + for (idx = 0; idx < NICKNAMEHISTORYLENGTH; ++idx) + WHOWAS[idx].hashv = -1; +} diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 0000000..d1272e7 --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,8 @@ +AUTOMAKE_OPTIONS = foreign + +bin_PROGRAMS = mkpasswd +if ENABLE_SSL +bin_PROGRAMS += respond +respond_SOURCES = respond.c +endif +mkpasswd_SOURCES = mkpasswd.c diff --git a/tools/Makefile.in b/tools/Makefile.in new file mode 100644 index 0000000..6146275 --- /dev/null +++ b/tools/Makefile.in @@ -0,0 +1,588 @@ +# Makefile.in generated by automake 1.12.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = mkpasswd$(EXEEXT) $(am__EXEEXT_1) +@ENABLE_SSL_TRUE@am__append_1 = respond +subdir = tools +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +@ENABLE_SSL_TRUE@am__EXEEXT_1 = respond$(EXEEXT) +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am_mkpasswd_OBJECTS = mkpasswd.$(OBJEXT) +mkpasswd_OBJECTS = $(am_mkpasswd_OBJECTS) +mkpasswd_LDADD = $(LDADD) +am__respond_SOURCES_DIST = respond.c +@ENABLE_SSL_TRUE@am_respond_OBJECTS = respond.$(OBJEXT) +respond_OBJECTS = $(am_respond_OBJECTS) +respond_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(mkpasswd_SOURCES) $(respond_SOURCES) +DIST_SOURCES = $(mkpasswd_SOURCES) $(am__respond_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBDIR = @LIBDIR@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PREFIX = @PREFIX@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +@ENABLE_SSL_TRUE@respond_SOURCES = respond.c +mkpasswd_SOURCES = mkpasswd.c +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tools/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tools/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +mkpasswd$(EXEEXT): $(mkpasswd_OBJECTS) $(mkpasswd_DEPENDENCIES) $(EXTRA_mkpasswd_DEPENDENCIES) + @rm -f mkpasswd$(EXEEXT) + $(LINK) $(mkpasswd_OBJECTS) $(mkpasswd_LDADD) $(LIBS) +respond$(EXEEXT): $(respond_OBJECTS) $(respond_DEPENDENCIES) $(EXTRA_respond_DEPENDENCIES) + @rm -f respond$(EXEEXT) + $(LINK) $(respond_OBJECTS) $(respond_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkpasswd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/respond.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscopelist: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool cscopelist ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-binPROGRAMS install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tools/README b/tools/README new file mode 100644 index 0000000..a90b098 --- /dev/null +++ b/tools/README @@ -0,0 +1,10 @@ +$Id$ + +A directory of support programs for ircd. + +mkkeypair - a small program used for generating a public and private + key pair +mkpasswd.c - makes password for operator{} blocks +respond.c - a tool to generate an RSA response to the challenge asked + by the server, and a tool to generate a keypair for the + C/R system diff --git a/tools/README.mkpasswd b/tools/README.mkpasswd new file mode 100644 index 0000000..3c179da --- /dev/null +++ b/tools/README.mkpasswd @@ -0,0 +1,50 @@ +$Id$ + +This is documentation for the mkpasswd.c included in ircd-hybrid-8. + +This version of mkpasswd can create both DES and MD5 passwords, with +either randomly generated or user provided salts. + +Options: +-6 - Create a SHA-512 password +-5 - Create a SHA-256 password +-m - Create an MD5 password +-b - Create a BlowFish password +-d - Create a DES password +-e - Create an Extended DES password +-l - Specify the length of a random MD5 salt +-r - Specify a number of rounds for a BlowFish or Extended DES password +-p - Specify the plaintext password at the command line +-s - Specify the salt at the command line +-R - Specify a raw salt passed directly to crypt() +-h - Get help + +Without the presence of any parameters, it'll behave like the old mkpasswd, +creating a DES password with a randomly generated salt and prompting for +the password (without echo). + +A DES salt is a pair of alphanumeric characters ('.' and '/' are permitted +as well), such as 'a4' or 'Td'. + +An MD5 salt consists of up to 16 (though most implementations limit you to +8) alphanumeric characters (plus '.' and '/'), +such as 'tGd' or 'J6d4dfG'. + +Known bugs: +Blowfish (on OpenBSD) is not yet supported +The encryption algorithms supported depend on your system's crypt() + implementation. +The maximum length of an MD5 salt is limited to your systems crypt() + implementation, typically 8. + +Supported Platforms (Known and tested): +Linux glibc (SHA since glibc 2.7, DES and MD5) +FreeBSD 3.x (DES (MD5 maybe)) +FreeBSD 4.x (DES and MD5) +Solaris 2.5-2.6 (DES only) +Cygwin 1.1.4 (DES only) +Prior Cygwin with the MD5 libcrypt (MD5 only) +OpenBSD 2.7 (don't link with -lcrypt) (DES and MD5, no Blowfish support) +Mac OS-X (Darwin) (don't link with -lcrypt) (DES only) + +Other systems probably work, but they haven't been amply tested. diff --git a/tools/README.respond b/tools/README.respond new file mode 100644 index 0000000..898bf85 --- /dev/null +++ b/tools/README.respond @@ -0,0 +1,36 @@ + rsa_respond + +respond: + +respond takes the challenge from the server and creates a valid response +to pass back to the server. + +Syntax: +$ ./respond <private key> <challenge> [passphrase] + +Notes: + +The private key file is protected by a passphrase, entered when the key is +created. The passphrase is prompted for whenever respond is called. + +Do not use mkkeypair to create a RSA key. The shell script will create it +without a passphrase. + +If the passphrase is passed on the command line (insecure mode), the +program will not prompt for a passphrase. This is primarily for running +rsa_respond from a script. + +Compiling: + +Untar the distribution +Read this document +Run 'configure' (not so foolproof, tweak the Makefile if necessary) +...and 'make' + +libcrypto from OpenSSL must be available in order to use this program. + +System support: +respond compiles properly, and have been tested on FreeBSD 4.x, Linux glibc, +Solaris 8, and Cygwin 1.2 or higher. + +# $Id: README 33 2005-10-02 20:50:00Z knight $ diff --git a/tools/mkkeypair b/tools/mkkeypair new file mode 100755 index 0000000..7393a10 --- /dev/null +++ b/tools/mkkeypair @@ -0,0 +1,54 @@ +#!/bin/sh +# $Id$ +# +# mkkeypair - short shell script to generate a OpenSSL RSA key suitable +# for use with cryptlinks. +# +# (C) 2003 Joshua Kwan and the IRCD-Hybrid team +# See LICENSE for the terms of copying. + +if test -f rsa.key; then + echo Moving old key out of the way to rsa.key.old + mv rsa.key rsa.key.old +fi + +if test -f rsa.pub; then + echo Moving old public key out of the way to rsa.pub.old + mv rsa.pub rsa.pub.old +fi + +echo Generating random bytes + +if test -c /dev/urandom; then + RANDGEN=/dev/urandom +elif test -c /dev/random; then + RANDGEN=/dev/random +else + RANDGEN=input +fi + +if test "$RANDGEN" = input; then + echo "Your system doesn't have a suitable random data generator," + echo "so type 150 characters of gibberish here to simulate it." + read -n 150 randomdata + echo + echo "$randomdata" > randdata + sort < randdata >> randdata.1 + cat randdata.1 >> randdata + rm -f randdata.1 +else + dd if=$RANDGEN of=randdata count=1 bs=2048 +fi + +echo Creating the private key. +openssl genrsa -rand randdata -out rsa.key 2048 || exit 1 +chmod 600 rsa.key +echo Creating the public key from the private key. +openssl rsa -in rsa.key -out rsa.pub -pubout || exit 1 +chmod 644 rsa.pub + +echo +echo Private key now exists as rsa.key +echo Public key now exists as rsa.pub + +rm -f randdata diff --git a/tools/mkpasswd.c b/tools/mkpasswd.c new file mode 100644 index 0000000..c4234d5 --- /dev/null +++ b/tools/mkpasswd.c @@ -0,0 +1,533 @@ +/* simple password generator by Nelson Minar (minar@reed.edu) +** copyright 1991, all rights reserved. +** You can use this code as long as my name stays with it. +** +** md5 patch by W. Campbell <wcampbel@botbay.net> +** Modernization, getopt, etc for the Hybrid IRCD team +** by W. Campbell +** +** /dev/random for salt generation added by +** Aaron Sethman <androsyn@ratbox.org> +** +** $Id$ +*/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> +#include <fcntl.h> + +#define FLAG_MD5 0x00000001 +#define FLAG_DES 0x00000002 +#define FLAG_SALT 0x00000004 +#define FLAG_PASS 0x00000008 +#define FLAG_LENGTH 0x00000010 +#define FLAG_BLOWFISH 0x00000020 +#define FLAG_ROUNDS 0x00000040 +#define FLAG_EXT 0x00000080 +#define FLAG_RAW 0x00000100 +#define FLAG_SHA256 0x00000200 +#define FLAG_SHA512 0x00000400 + + +extern char *crypt(); + + +static char *make_sha256_salt(int); +static char *make_sha256_salt_para(const char *); +static char *make_sha512_salt(int); +static char *make_sha512_salt_para(const char *); +static char *make_des_salt(void); +static char *make_ext_salt(int); +static char *make_ext_salt_para(int, const char *); +static char *make_md5_salt(int); +static char *make_md5_salt_para(const char *); +static char *make_bf_salt(int, int); +static char *make_bf_salt_para(int, const char *); +static char *int_to_base64(int); +static char *generate_random_salt(char *, int); +static char *generate_poor_salt(char *, int); +static void full_usage(void); +static void brief_usage(void); + +static const char saltChars[] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + /* 0 .. 63, ascii - 64 */ + +int +main(int argc, char *argv[]) +{ + const char *plaintext = NULL; + int c; + char *saltpara = NULL; + char *salt; + int flag = 0; + int length = 0; /* Not Set */ + int rounds = 0; /* Not set, since extended DES needs 25 and blowfish needs + ** 4 by default, a side effect of this being the encryption + ** type parameter must be specified before the rounds + ** parameter. + */ + + while ((c = getopt(argc, argv, "56mdber:h?l:s:p:R:")) != -1) + { + switch (c) + { + case '5': + flag |= FLAG_SHA256; + break; + case '6': + flag |= FLAG_SHA512; + break; + case 'm': + flag |= FLAG_MD5; + break; + case 'd': + flag |= FLAG_DES; + break; + case 'b': + flag |= FLAG_BLOWFISH; + rounds = 4; + break; + case 'e': + flag |= FLAG_EXT; + rounds = 25; + break; + case 'l': + flag |= FLAG_LENGTH; + length = atoi(optarg); + break; + case 'r': + flag |= FLAG_ROUNDS; + rounds = atoi(optarg); + break; + case 's': + flag |= FLAG_SALT; + saltpara = optarg; + break; + case 'p': + flag |= FLAG_PASS; + plaintext = optarg; + break; + case 'R': + flag |= FLAG_RAW; + saltpara = optarg; + break; + case 'h': + full_usage(); + /* NOT REACHED */ + break; + case '?': + brief_usage(); + /* NOT REACHED */ + break; + default: + printf("Invalid Option: -%c\n", c); + break; + } + } + + if (flag & FLAG_MD5) + { + if (length == 0) + length = 8; + if (flag & FLAG_SALT) + salt = make_md5_salt_para(saltpara); + else + salt = make_md5_salt(length); + } + else if (flag & FLAG_SHA256) + { + if (length == 0) + length = 16; + if (flag & FLAG_SALT) + salt = make_sha256_salt_para(saltpara); + else + salt = make_sha256_salt(length); + } + else if (flag & FLAG_SHA512) + { + if (length == 0) + length = 16; + if (flag & FLAG_SALT) + salt = make_sha512_salt_para(saltpara); + else + salt = make_sha512_salt(length); + } + else if (flag & FLAG_BLOWFISH) + { + if (length == 0) + length = 22; + if (flag & FLAG_SALT) + salt = make_bf_salt_para(rounds, saltpara); + else + salt = make_bf_salt(rounds, length); + } + else if (flag & FLAG_EXT) + { + /* XXX - rounds needs to be done */ + if (flag & FLAG_SALT) + { + if ((strlen(saltpara) == 4)) + { + salt = make_ext_salt_para(rounds, saltpara); + } + else + { + printf("Invalid salt, please enter 4 alphanumeric characters\n"); + exit(1); + } + } + else + { + salt = make_ext_salt(rounds); + } + } + else if (flag & FLAG_RAW) + { + salt = saltpara; + } + else /* Default to DES */ + { + if (flag & FLAG_SALT) + { + if ((strlen(saltpara) == 2)) + { + salt = saltpara; + } + else + { + printf("Invalid salt, please enter 2 alphanumeric characters\n"); + exit(1); + } + } + else + { + salt = make_des_salt(); + } + } + + if (flag & FLAG_PASS) + { + if (!plaintext) + printf("Please enter a valid password\n"); + } + else + plaintext = getpass("plaintext: "); + + printf("%s\n", crypt(plaintext, salt)); + return 0; +} + +static char * +make_des_salt(void) +{ + static char salt[3]; + + generate_random_salt(salt, 2); + salt[2] = '\0'; + return salt; +} + +static char * +int_to_base64(int value) +{ + static char buf[5]; + int i; + + for (i = 0; i < 4; i++) + { + buf[i] = saltChars[value & 63]; + value >>= 6; /* Right shifting 6 places is the same as dividing by 64 */ + } + + buf[i] = '\0'; /* not REALLY needed as it's static, and thus initialized + ** to \0. + */ + return buf; +} + +static char * +make_ext_salt(int rounds) +{ + static char salt[10]; + + sprintf(salt, "_%s", int_to_base64(rounds)); + generate_random_salt(&salt[5], 4); + salt[9] = '\0'; + + return salt; +} + +static char * +make_ext_salt_para(int rounds, const char *saltpara) +{ + static char salt[10]; + + sprintf(salt, "_%s%s", int_to_base64(rounds), saltpara); + return salt; +} + +static char * +make_sha256_salt_para(const char *saltpara) +{ + static char salt[21]; + + if (saltpara && (strlen(saltpara) <= 16)) + { + /* + * sprintf used because of portability requirements, the length + * is checked above, so it should not be too much of a concern + */ + sprintf(salt, "$5$%s$", saltpara); + return salt; + } + + printf("Invalid Salt, please use up to 16 random alphanumeric characters\n"); + exit(1); + + /* NOT REACHED */ + return NULL; +} + +static char * +make_sha256_salt(int length) +{ + static char salt[21]; + + if (length > 16) + { + printf("SHA256 salt length too long\n"); + exit(0); + } + + salt[0] = '$'; + salt[1] = '5'; + salt[2] = '$'; + + generate_random_salt(&salt[3], length); + + salt[length + 3] = '$'; + salt[length + 4] = '\0'; + + return salt; +} + +static char * +make_sha512_salt_para(const char *saltpara) +{ + static char salt[21]; + + if (saltpara && (strlen(saltpara) <= 16)) + { + /* + * sprintf used because of portability requirements, the length + * is checked above, so it should not be too much of a concern + */ + sprintf(salt, "$6$%s$", saltpara); + return salt; + } + + printf("Invalid Salt, please use up to 16 random alphanumeric characters\n"); + exit(1); + + /* NOT REACHED */ + return NULL; +} + +static char * +make_sha512_salt(int length) +{ + static char salt[21]; + + if (length > 16) + { + printf("SHA512 salt length too long\n"); + exit(0); + } + + salt[0] = '$'; + salt[1] = '6'; + salt[2] = '$'; + + generate_random_salt(&salt[3], length); + + salt[length + 3] = '$'; + salt[length + 4] = '\0'; + + return salt; +} + +static char * +make_md5_salt_para(const char *saltpara) +{ + static char salt[21]; + + if (saltpara && (strlen(saltpara) <= 16)) + { + /* + * sprintf used because of portability requirements, the length + * is checked above, so it should not be too much of a concern + */ + sprintf(salt, "$1$%s$", saltpara); + return salt; + } + + printf("Invalid Salt, please use up to 16 random alphanumeric characters\n"); + exit(1); + + /* NOT REACHED */ + return NULL; +} + +static char * +make_md5_salt(int length) +{ + static char salt[21]; + + if (length > 16) + { + printf("MD5 salt length too long\n"); + exit(0); + } + + salt[0] = '$'; + salt[1] = '1'; + salt[2] = '$'; + + generate_random_salt(&salt[3], length); + + salt[length + 3] = '$'; + salt[length + 4] = '\0'; + + return salt; +} + +static char * +make_bf_salt_para(int rounds, const char *saltpara) +{ + static char salt[31]; + char tbuf[3]; + + if (saltpara && (strlen(saltpara) <= 22)) + { + /* + * sprintf used because of portability requirements, the length + * is checked above, so it should not be too much of a concern + */ + sprintf(tbuf, "%02d", rounds); + sprintf(salt, "$2a$%s$%s$", tbuf, saltpara); + return salt; + } + + printf("Invalid Salt, please use up to 22 random alphanumeric characters\n"); + exit(1); + + /* NOT REACHED */ + return NULL; +} + +static char * +make_bf_salt(int rounds, int length) +{ + static char salt[31]; + char tbuf[3]; + + if (length > 22) + { + printf("BlowFish salt length too long\n"); + exit(0); + } + + sprintf(tbuf, "%02d", rounds); + sprintf(salt, "$2a$%s$", tbuf); + + generate_random_salt(&salt[7], length); + + salt[length + 7] = '$'; + salt[length + 8] = '\0'; + + return salt; +} + +static char * +generate_poor_salt(char *salt, int length) +{ + int i; + + srandom(time(NULL)); + + for (i = 0; i < length; i++) + salt[i] = saltChars[random() % 64]; + + return salt; +} + +static char * +generate_random_salt(char *salt, int length) +{ + char *buf; + int fd, i; + + if ((fd = open("/dev/random", O_RDONLY)) < 0) + return generate_poor_salt(salt, length); + + buf = calloc(1, length); + + if (read(fd, buf, length) != length) + { + close(fd); + free(buf); + + return generate_poor_salt(salt, length); + } + + for (i = 0; i < length; i++) + salt[i] = saltChars[abs(buf[i]) % 64]; + + close(fd); + free(buf); + + return salt; +} + +static void +full_usage(void) +{ + printf("mkpasswd [-5|-6|-m|-d|-b|-e] [-l saltlength] [-r rounds] [-s salt] [-p plaintext]\n"); + printf(" [-R rawsalt]\n"); + printf("-5 Generate a SHA-256 password\n"); + printf("-6 Generate a SHA-512 password\n"); + printf("-m Generate an MD5 password\n"); + printf("-d Generate a DES password\n"); + printf("-b Generate a BlowFish password\n"); + printf("-e Generate an Extended DES password\n"); + printf("-l Specify a length for a random MD5 or BlowFish salt\n"); + printf("-r Specify a number of rounds for a BlowFish or Extended DES password\n"); + printf(" BlowFish: default 4, no more than 6 recommended\n"); + printf(" Extended DES: default 25\n"); + printf("-s Specify a salt, 2 alphanumeric characters for DES, up to 16 for SHA/MD5,\n"); + printf(" up to 22 for BlowFish, and 4 for Extended DES\n"); + printf("-R Specify a raw salt passed directly to crypt()\n"); + printf("-p Specify a plaintext password to use\n"); + printf("Example: mkpasswd -m -s 3dr -p test\n"); + exit(0); +} + +static void +brief_usage(void) +{ + printf("mkpasswd - password hash generator\n"); + printf("Standard DES: mkpasswd [-d] [-s salt] [-p plaintext]\n"); + printf("Extended DES: mkpasswd -e [-r rounds] [-s salt] [-p plaintext]\n"); + printf(" SHA-256: mkpasswd -5 [-l saltlength] [-s salt] [-p plaintext]\n"); + printf(" SHA-512: mkpasswd -6 [-l saltlength] [-s salt] [-p plaintext]\n"); + printf(" MD5: mkpasswd -m [-l saltlength] [-s salt] [-p plaintext]\n"); + printf(" BlowFish: mkpasswd -b [-r rounds] [-l saltlength] [-s salt]\n"); + printf(" [-p plaintext]\n"); + printf(" Raw: mkpasswd -R <rawsalt> [-p plaintext]\n"); + printf("Use -h for full usage\n"); + exit(0); +} diff --git a/tools/respond.c b/tools/respond.c new file mode 100644 index 0000000..9a2169c --- /dev/null +++ b/tools/respond.c @@ -0,0 +1,166 @@ +/* + * tools/rsa_respond/respond.c + * A simple RSA authentification challenge response generator for the + * ircd-hybrid CHALLENGE command. + * This code is Copyright(C)2001 by the past and present ircd-hybrid + * developers. + * 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: respond.c 33 2005-10-02 20:50:00Z knight $ + */ +#include <stdio.h> +#include <string.h> +#include <openssl/err.h> +#include <openssl/rsa.h> +#include <openssl/pem.h> +#include <openssl/md5.h> +#include <unistd.h> + +static int insecure_mode = 0; +static char *pass_param = NULL; + +static int pass_cb(char *buf, int size, int rwflag, void *u) +{ + int len; + char *tmp; + + if (insecure_mode != 0) + { + if (pass_param == NULL) + return 0; + len = strlen(pass_param); + if (len <= 0) /* This SHOULDN'T happen */ + return 0; + if (len > size) + len = size; + memcpy(buf, pass_param, len); + return len; + } + + tmp = getpass("Enter passphrase for challenge: "); + if (!tmp) + { + puts("Couldn't read passphrase from stdin!"); + exit(-1); + } + len = strlen(tmp); + if (len <= 0) + return 0; + if (len > size) + len = size; + memcpy(buf, tmp, len); + return len; +} + +static void +binary_to_hex( unsigned char * bin, char * hex, int length ) +{ + static const char trans[] = "0123456789ABCDEF"; + int i; + + for( i = 0; i < length; i++ ) + { + hex[i<<1] = trans[bin[i] >> 4]; + hex[(i<<1)+1] = trans[bin[i] & 0xf]; + } + hex[i<<1] = '\0'; +} + +static int +hex_to_binary(const char *from, char *to, int len) +{ + char a, b=1; + int p=0; + const char *ptr = from; + while (-1) + { + a = *ptr++; + if (!a) + break; + b = *ptr++; + + /* If this happens, we got bad input. */ + if (!b) + break; + if (p >= len) + break; + if (!((a >= '0' && a <= '9') || (a >= 'A' && a <= 'F'))) + break; + if (!((b >= '0' && b <= '9') || (b >= 'A' && b <= 'F'))) + break; + to[p++] = ((a <= '9') ? (a - '0') : (a - 'A' + 0xA))<<4 | + ((b <= '9') ? (b - '0') : (b - 'A' + 0xA)); + } + return p; +} + +int +main(int argc, char **argv) +{ + FILE *kfile; + RSA *rsa = NULL; + char ndata[257], ddata[257]; + /* respond privatefile challenge */ + if (argc < 3) + { + puts("Usage: respond privatefile challenge [passphrase]"); + return 0; + } + + if (argc == 4) + { + /* This is TOTALLY insecure and not recommended, but for + ** interfacing with irc client scripts, it's either this + ** or don't use a passphrase. + ** + ** The likelihood of a passphrase leaking isn't TOO great, + ** only ps auxww will show it, and even then, only at the + ** precise moment this is called. + */ + insecure_mode = 1; + pass_param = argv[3]; + } + + if (!(kfile = fopen(argv[1], "r"))) + { + puts("Could not open the private keyfile."); + return 0; + } + + SSLeay_add_all_ciphers(); + rsa = PEM_read_RSAPrivateKey(kfile, NULL,pass_cb, NULL); + + if(!rsa) + { + puts("Unable to read your private key, is the passphrase wrong?"); + return 0; + } + + fclose(kfile); + if (hex_to_binary(argv[2], ndata, 128) != 128) + { + puts("Bad challenge."); + return -1; + } + + if (RSA_private_decrypt(128, (unsigned char*)ndata, + (unsigned char*)ddata, rsa, RSA_PKCS1_PADDING) == -1) + { + puts("Decryption error."); + return -1; + } + binary_to_hex((unsigned char*)ddata, ndata, 32); + puts(ndata); + return 0; +} @@ -0,0 +1,240 @@ +#! /bin/sh +# ylwrap - wrapper for lex/yacc invocations. + +scriptversion=2012-07-14.08; # UTC + +# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# +# Written by Tom Tromey <tromey@cygnus.com>. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to <bug-automake@gnu.org> or send patches to +# <automake-patches@gnu.org>. + +get_dirname () +{ + case $1 in + */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';; + # Otherwise, we want the empty string (not "."). + esac +} + +# guard FILE +# ---------- +# The CPP macro used to guard inclusion of FILE. +guard() +{ + printf '%s\n' "$from" \ + | sed \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\ + -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g' +} + +# quote_for_sed [STRING] +# ---------------------- +# Return STRING (or stdin) quoted to be used as a sed pattern. +quote_for_sed () +{ + case $# in + 0) cat;; + 1) printf '%s\n' "$1";; + esac \ + | sed -e 's|[][\\.*]|\\&|g' +} + +case "$1" in + '') + echo "$0: No files given. Try '$0 --help' for more information." 1>&2 + exit 1 + ;; + --basedir) + basedir=$2 + shift 2 + ;; + -h|--h*) + cat <<\EOF +Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... + +Wrapper for lex/yacc invocations, renaming files as desired. + + INPUT is the input file + OUTPUT is one file PROG generates + DESIRED is the file we actually want instead of OUTPUT + PROGRAM is program to run + ARGS are passed to PROG + +Any number of OUTPUT,DESIRED pairs may be used. + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v|--v*) + echo "ylwrap $scriptversion" + exit $? + ;; +esac + + +# The input. +input="$1" +shift +# We'll later need for a correct munging of "#line" directives. +input_sub_rx=`get_dirname "$input" | quote_for_sed` +case "$input" in + [\\/]* | ?:[\\/]*) + # Absolute path; do nothing. + ;; + *) + # Relative path. Make it absolute. + input="`pwd`/$input" + ;; +esac +input_rx=`get_dirname "$input" | quote_for_sed` + +# Since DOS filename conventions don't allow two dots, +# the DOS version of Bison writes out y_tab.c instead of y.tab.c +# and y_tab.h instead of y.tab.h. Test to see if this is the case. +y_tab_nodot=false +if test -f y_tab.c || test -f y_tab.h; then + y_tab_nodot=true +fi + +# The parser itself, the first file, is the destination of the .y.c +# rule in the Makefile. +parser=$1 +# A sed program to s/FROM/TO/g for all the FROM/TO so that, for +# instance, we rename #include "y.tab.h" into #include "parse.h" +# during the conversion from y.tab.c to parse.c. +rename_sed= +while test "$#" -ne 0; do + if test "$1" = "--"; then + shift + break + fi + from=$1 + # Handle y_tab.c and y_tab.h output by DOS + if $y_tab_nodot; then + case $from in + "y.tab.c") from=y_tab.c;; + "y.tab.h") from=y_tab.h;; + esac + fi + shift + to=$1 + shift + rename_sed="${rename_sed}s|"`quote_for_sed "$from"`"|$to|g;" +done + +# The program to run. +prog="$1" +shift +# Make any relative path in $prog absolute. +case "$prog" in + [\\/]* | ?:[\\/]*) ;; + *[\\/]*) prog="`pwd`/$prog" ;; +esac + +# FIXME: add hostname here for parallel makes that run commands on +# other machines. But that might take us over the 14-char limit. +dirname=ylwrap$$ +do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret' +trap "ret=129; $do_exit" 1 +trap "ret=130; $do_exit" 2 +trap "ret=141; $do_exit" 13 +trap "ret=143; $do_exit" 15 +mkdir $dirname || exit 1 + +cd $dirname + +case $# in + 0) "$prog" "$input" ;; + *) "$prog" "$@" "$input" ;; +esac +ret=$? + +if test $ret -eq 0; then + for from in * + do + to=`printf '%s\n' "$from" | sed "$rename_sed"` + if test -f "$from"; then + # If $2 is an absolute path name, then just use that, + # otherwise prepend '../'. + case $to in + [\\/]* | ?:[\\/]*) target=$to;; + *) target="../$to";; + esac + + # Do not overwrite unchanged header files to avoid useless + # recompilations. Always update the parser itself: it is the + # destination of the .y.c rule in the Makefile. Divert the + # output of all other files to a temporary file so we can + # compare them to existing versions. + if test $from != $parser; then + realtarget="$target" + target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'` + fi + + # Munge "#line" or "#" directives. Don't let the resulting + # debug information point at an absolute srcdir. Use the real + # output file name, not yy.lex.c for instance. Adjust the + # include guards too. + FROM=`guard "$from"` + TARGET=`guard "$to"` + sed -e "/^#/!b" -e "s|$input_rx|$input_sub_rx|" -e "$rename_sed" \ + -e "s|$FROM|$TARGET|" "$from" >"$target" || ret=$? + + # Check whether files must be updated. + if test "$from" != "$parser"; then + if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then + echo "$to is unchanged" + rm -f "$target" + else + echo "updating $to" + mv -f "$target" "$realtarget" + fi + fi + else + # A missing file is only an error for the parser. This is a + # blatant hack to let us support using "yacc -d". If -d is not + # specified, don't fail when the header file is "missing". + if test "$from" = "$parser"; then + ret=1 + fi + fi + done +fi + +# Remove the directory. +cd .. +rm -rf $dirname + +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: |