0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

Pull in libratbox from ircd-ratbox-3.0.0beta1 and integrate into the build system.

This commit is contained in:
William Pitcock 2008-04-01 11:52:26 -05:00
parent 1f112a04f4
commit db13786793
62 changed files with 66509 additions and 1 deletions

View file

@ -46,7 +46,7 @@ CFLAGS = @CFLAGS@
# the system one.
#CFLAGS= -DNDEBUG -g -O2 -D"FD_SETSIZE=1024"
SHELL=/bin/sh
SUBDIRS=modules extensions libcharybdis src tools servlink doc help
SUBDIRS=libratbox modules extensions libcharybdis src tools servlink doc help
CLEANDIRS = ${SUBDIRS}
RSA_FILES=rsa_respond/README rsa_respond/respond.c rsa_respond/Makefile

View file

@ -26,6 +26,8 @@ AC_LANG(C)
dnl Make sure autoconf doesn't interfere with cflags -jmallett
CFLAGS="$OLD_CFLAGS"
AC_CONFIG_SUBDIRS(libratbox)
dnl Check for various compilers. -jmallett
dnl But if $CC turns out to be gcc, sure as hell it's, well, gcc. -joshk

1
libratbox/.indent.pro vendored Normal file
View file

@ -0,0 +1 @@
-i8 -bli0 -ut -nsai -l100 -npcs

340
libratbox/COPYING Normal file
View file

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 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.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

18
libratbox/CREDITS Normal file
View file

@ -0,0 +1,18 @@
$Id: CREDITS 23020 2006-09-01 18:20:19Z androsyn $
ircd-ratbox is an evolution where ircd-hybrid left off around version 7-rc1.
Currently the ircd-ratbox team consists of the following developers:
AndroSyn, Aaron Sethman <androsyn -at- ratbox.org>
anfl, Lee Hardy <lee -at- leeh.co.uk>
Special thanks for support, code and ideas to:
Hwy, W. Campbell <wcampbel -at- botbay.net>
jilles, Jilles Tjoelker <jilles -at- stack.nl>
larne, Edward Brocklesby <ejb -at- sdf.lonestar.org>
Of course our work is based on the work of many, many others over the past
10 or so years since irc has existed, including the work done by the Hybrid
team, our thanks goes to them.

3153
libratbox/ChangeLog Normal file

File diff suppressed because it is too large Load diff

182
libratbox/INSTALL Normal file
View file

@ -0,0 +1,182 @@
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

3
libratbox/Makefile.am Normal file
View file

@ -0,0 +1,3 @@
AUTOMAKE_OPTIONS = foreign
SUBDIRS = src

643
libratbox/Makefile.in Normal file
View file

@ -0,0 +1,643 @@
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006 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@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@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 $(top_srcdir)/configure \
$(top_srcdir)/include/libratbox_config.h.in COPYING ChangeLog \
INSTALL TODO config.guess config.sub depcomp install-sh \
ltmain.sh missing
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 = $(top_builddir)/include/libratbox_config.h
CONFIG_CLEAN_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
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
{ test ! -d $(distdir) \
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr $(distdir); }; }
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CP = @CP@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CRYPT_LIB = @CRYPT_LIB@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN = @LN@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
MV = @MV@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PICFLAGS = @PICFLAGS@
RANLIB = @RANLIB@
RB_PREFIX = @RB_PREFIX@
RM = @RM@
SED = @SED@
SEDOBJ = @SEDOBJ@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SSL_INCLUDES = @SSL_INCLUDES@
SSL_LIBS = @SSL_LIBS@
STRIP = @STRIP@
TOUCH = @TOUCH@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
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@
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@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign
SUBDIRS = src
all: all-recursive
.SUFFIXES:
am--refresh:
@:
$(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 '; \
cd $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
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)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
include/libratbox_config.h: include/stamp-h1
@if test ! -f $@; then \
rm -f include/stamp-h1; \
$(MAKE) $(AM_MAKEFLAGS) include/stamp-h1; \
else :; fi
include/stamp-h1: $(top_srcdir)/include/libratbox_config.h.in $(top_builddir)/config.status
@rm -f include/stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status include/libratbox_config.h
$(top_srcdir)/include/libratbox_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_srcdir) && $(AUTOHEADER)
rm -f include/stamp-h1
touch $@
distclean-hdr:
-rm -f include/libratbox_config.h include/stamp-h1
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
# 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):
@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//`; \
list='$(SUBDIRS)'; 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; \
(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"
$(RECURSIVE_CLEAN_TARGETS):
@failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
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; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
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 || \
tags="$$tags $$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; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
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; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
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 $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$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 \
test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
distdir=`$(am__cd) $(distdir) && pwd`; \
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$top_distdir" \
distdir="$$distdir/$$subdir" \
am__remove_distdir=: \
am__skip_length_check=: \
distdir) \
|| exit 1; \
fi; \
done
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -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__remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
dist-tarZ: distdir
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
dist-shar: distdir
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__remove_distdir)
dist dist-all: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__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) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& cd $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(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
$(am__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:
@cd $(distuninstallcheck_dir) \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { 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
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:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-exec-am:
install-html: install-html-recursive
install-info: install-info-recursive
install-man:
install-pdf: install-pdf-recursive
install-ps: install-ps-recursive
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) install-am \
install-strip
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am am--refresh check check-am clean clean-generic \
clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
dist-gzip dist-shar dist-tarZ 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-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:

11
libratbox/README Normal file
View file

@ -0,0 +1,11 @@
This is libircd from ircd-ratbox. A few notes about this library:
1. Most of this code isn't anywhere near threadsafe at this point. Don't
hold your breath on this either.
2. The linebuf code is designed to deal with pretty much 512 bytes per line
and that is it. Anything beyond that length unless in raw mode, gets
discard. For some non-irc purposes, this can be a problem, but for
ircd stuff its fine.
3. The helper code when transmitting data between helpers, the same 512 byte
limit applies there as we recycle the linebuf code for this.

2
libratbox/TODO Normal file
View file

@ -0,0 +1,2 @@
1. Make i/o loop engines interchangable at run time.
2. Finish TODO list

191
libratbox/acinclude.m4 Normal file
View file

@ -0,0 +1,191 @@
# $Id: acinclude.m4 23020 2006-09-01 18:20:19Z androsyn $ - aclocal.m4 - Autoconf fun...
AC_DEFUN([AC_DEFINE_DIR], [
test "x$prefix" = xNONE && prefix="$ac_default_prefix"
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
ac_define_dir=`eval echo [$]$2`
ac_define_dir=`eval echo [$]ac_define_dir`
$1="$ac_define_dir"
AC_SUBST($1)
ifelse($3, ,
AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
])
AC_DEFUN([AC_SUBST_DIR], [
ifelse($2,,,$1="[$]$2")
$1=`(
test "x$prefix" = xNONE && prefix="$ac_default_prefix"
test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
eval echo \""[$]$1"\"
)`
AC_SUBST($1)
])
# RB_TYPE_INTMAX_T
# -----------------
AC_DEFUN([RB_TYPE_INTMAX_T],
[
AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
AC_CHECK_TYPE([intmax_t],
[AC_DEFINE([HAVE_INTMAX_T], 1,
[Define to 1 if the system has the type `intmax_t'.]) ac_cv_c_intmax_t=yes],
[test $ac_cv_type_long_long_int = yes \
&& ac_type='long long int' \
|| ac_type='long int'
AC_DEFINE_UNQUOTED([intmax_t], [$ac_type],
[Define to the widest signed integer type
if <stdint.h> and <inttypes.h> do not define.]) ac_cv_c_intmax_t="$ac_type"])
])
# RB_TYPE_UINTMAX_T
# -----------------
AC_DEFUN([RB_TYPE_UINTMAX_T],
[
AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
AC_CHECK_TYPE([uintmax_t],
[AC_DEFINE([HAVE_UINTMAX_T], 1,
[Define to 1 if the system has the type `uintmax_t'.]) ac_cv_c_uintmax_t=yes],
[test $ac_cv_type_unsigned_long_long_int = yes \
&& ac_type='unsigned long long int' \
|| ac_type='unsigned long int'
AC_DEFINE_UNQUOTED([uintmax_t], [$ac_type],
[Define to the widest unsigned integer type
if <stdint.h> and <inttypes.h> do not define.]) ac_cv_c_uintmax_t="$ac_type"])
])
# RB_TYPE_INTPTR_T
# -----------------
AC_DEFUN([RB_TYPE_INTPTR_T],
[
AC_CHECK_TYPE([intptr_t],
[AC_DEFINE([HAVE_INTPTR_T], 1,
[Define to 1 if the system has the type `intptr_t'.]) ac_cv_c_intptr_t=yes],
[for ac_type in 'int' 'long int' 'long long int'; do
AC_COMPILE_IFELSE(
[AC_LANG_BOOL_COMPILE_TRY(
[AC_INCLUDES_DEFAULT],
[[sizeof (void *) <= sizeof ($ac_type)]])],
[AC_DEFINE_UNQUOTED([intptr_t], [$ac_type],
[Define to the type of a signed integer type wide enough to
hold a pointer, if such a type exists, and if the system
does not define it.]) ac_cv_c_intptr_t="$ac_type"
ac_type=])
test -z "$ac_type" && break
done])
])
# RB_TYPE_UINTPTR_T
# -----------------
AC_DEFUN([RB_TYPE_UINTPTR_T],
[
AC_CHECK_TYPE([uintptr_t],
[AC_DEFINE([HAVE_UINTPTR_T], 1,
[Define to 1 if the system has the type `uintptr_t'.]) ac_cv_c_uintptr_t=yes],
[for ac_type in 'unsigned int' 'unsigned long int' \
'unsigned long long int'; do
AC_COMPILE_IFELSE(
[AC_LANG_BOOL_COMPILE_TRY(
[AC_INCLUDES_DEFAULT],
[[sizeof (void *) <= sizeof ($ac_type)]])],
[AC_DEFINE_UNQUOTED([uintptr_t], [$ac_type],
[Define to the type of an unsigned integer type wide enough to
hold a pointer, if such a type exists, and if the system
does not define it.]) ac_cv_c_uintptr_t="$ac_type"
ac_type=])
test -z "$ac_type" && break
done])
])
dnl IPv6 support macros..pretty much swiped from wget
dnl RB_PROTO_INET6
AC_DEFUN([RB_PROTO_INET6],[
AC_CACHE_CHECK([for INET6 protocol support], [rb_cv_proto_inet6],[
AC_TRY_CPP([
#include <sys/types.h>
#include <sys/socket.h>
#ifndef PF_INET6
#error Missing PF_INET6
#endif
#ifndef AF_INET6
#error Mlssing AF_INET6
#endif
],[
rb_cv_proto_inet6=yes
],[
rb_cv_proto_inet6=no
])
])
if test "X$rb_cv_proto_inet6" = "Xyes"; then :
$1
else :
$2
fi
])
AC_DEFUN([RB_TYPE_STRUCT_SOCKADDR_IN6],[
rb_have_sockaddr_in6=
AC_CHECK_TYPES([struct sockaddr_in6],[
rb_have_sockaddr_in6=yes
],[
rb_have_sockaddr_in6=no
],[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
])
if test "X$rb_have_sockaddr_in6" = "Xyes"; then :
$1
else :
$2
fi
])
AC_DEFUN([RB_CHECK_TIMER_CREATE],
[AC_CACHE_CHECK([for a working timer_create(CLOCK_REALTIME)],
[rb__cv_timer_create_works],
[AC_TRY_RUN([
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
int main(int argc, char *argv[])
{
#if HAVE_TIMER_CREATE
struct sigevent ev;
timer_t timer;
ev.sigev_notify = SIGEV_SIGNAL;
ev.sigev_signo = SIGVTALRM;
if (timer_create(CLOCK_REALTIME, &ev, &timer) != 0) {
return 1;
}
#else
return 1;
#endif
return 0;
}
],
[rb__cv_timer_create_works=yes],
[rb__cv_timer_create_works=no])
])
case $rb__cv_timer_create_works in
yes) AC_DEFINE([USE_TIMER_CREATE], 1,
[Define to 1 if we can use timer_create(CLOCK_REALTIME,...)]);;
esac
])

7583
libratbox/aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load diff

1516
libratbox/config.guess vendored Executable file

File diff suppressed because it is too large Load diff

1626
libratbox/config.sub vendored Executable file

File diff suppressed because it is too large Load diff

27656
libratbox/configure vendored Executable file

File diff suppressed because it is too large Load diff

675
libratbox/configure.ac Normal file
View file

@ -0,0 +1,675 @@
dnl $Id: configure.ac 23020 2006-09-01 18:20:19Z androsyn $
dnl Process this file with autoconf to produce a configure script.
dnl TODO: clean up all the OpenSSL and shared module checking stuff;
dnl the most major changes have already been made and it looks like
dnl said functions need to be just about as complex as they already are.
AC_PREREQ(2.60)
AUTOMAKE_OPTIONS = 1.10
dnl Sneaky way to get an Id tag into the configure script
AC_COPYRIGHT([$Id: configure.ac 23020 2006-09-01 18:20:19Z androsyn $])
AC_INIT([libratbox],[devel])
AM_INIT_AUTOMAKE(AC_PACKAGE_TARNAME, AC_PACKAGE_VERSION, -)
AM_CONFIG_HEADER(include/libratbox_config.h)
AC_PREFIX_DEFAULT(/usr/local/libratbox)
AC_GNU_SOURCE
dnl Checks for programs.
AC_PROG_CC_C99
if test x"$ac_cv_prog_cc_c99" = "xno"; then
AC_ERROR([ircd-ratbox requires a C99 capable compiler])
fi
AC_PROG_INSTALL
AC_PROG_EGREP
AC_PROG_SED
F77=no
CXX=no
GCJ=no
AM_DISABLE_STATIC
AM_ENABLE_SHARED
AM_MAINTAINER_MODE
AC_ISC_POSIX
AC_C_INLINE
AC_C_CONST
AC_PROG_MAKE_SET
AC_PROG_INSTALL
AC_PATH_PROG(AUTOMAKE, automake)
AC_PATH_PROG(ACLOCAL, aclocal)
AC_PATH_PROG(AUTOHEADER, autoheader)
AC_PATH_PROG(AS, as)
AC_PATH_PROG(RM, rm)
AC_PATH_PROG(CP, cp)
AC_PATH_PROG(MV, mv)
AC_PATH_PROG(LN, ln)
AC_PATH_PROG(AR, ar)
AC_PATH_PROG(LD, ld)
AC_PATH_PROG(RANLIB, ranlib)
AC_PATH_PROG(TOUCH, touch)
AC_LANG(C)
AC_PROG_LIBTOOL
LIBTOOL="$LIBTOOL --silent"
AC_CONFIG_SUBDIRS(libltdl)
case "$host_os" in
*cygwin*)
AC_DEFINE_UNQUOTED(CYGWIN,1,[This is a Cygwin system])
AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
;;
*mingw*)
AC_DEFINE_UNQUOTED(MINGW,1,[This is a MinGW system])
AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
AC_CHECK_HEADER(windows.h, , [AC_MSG_ERROR([** MinGW and no windows.h. I give up.])])
AC_CHECK_HEADER(winsock2.h, , [AC_MSG_ERROR([** MinGW and no winsock2.h. I give up.])])
LIBS="$LIBS -lws2_32 -liphlpapi"
is_mingw="yes"
;;
*interix*)
CPPFLAGS="$CFLAGS -D_ALL_SOURCE -D_XOPEN_SOURCE=500"
;;
*solaris*)
CPPFLAGS="$CFLAGS -D_POSIX_PTHREAD_SEMANTICS"
;;
*)
;;
esac
AM_CONDITIONAL([MINGW], [test "$is_mingw" = "yes"])
# backwards support for IRC_CFLAGS
CFLAGS="$IRC_CFLAGS $CFLAGS -O0 -Wall"
dnl use directory structure of cached as default (hack)
if test "$libexecdir" = '${exec_prefix}/libexec' &&
test "$localstatedir" = '${prefix}/var'; then
libexecdir='${bindir}'
localstatedir='${prefix}'
fi
AC_TYPE_INT8_T
AC_TYPE_INT16_T
AC_TYPE_INT32_T
AC_TYPE_INT64_T
AC_TYPE_UINT8_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
RB_TYPE_INTPTR_T
RB_TYPE_INTMAX_T
RB_TYPE_UINTMAX_T
RB_TYPE_UINTPTR_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UID_T
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([crypt.h unistd.h sys/socket.h sys/stat.h sys/time.h time.h netinet/in.h arpa/inet.h errno.h sys/uio.h spawn.h sys/poll.h sys/epoll.h sys/select.h sys/devpoll.h sys/event.h port.h signal.h sys/signalfd.h])
AC_HEADER_TIME
dnl Networking Functions
dnl ====================
AC_SEARCH_LIBS(socket, [socket],,)
AC_CHECK_MEMBER([struct sockaddr.sa_len], [AC_DEFINE(SOCKADDR_IN_HAS_LEN, 1, [Define to 1 if sockaddr has a 'sa_len'
member.])],,[[
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#endif
]])
AC_CHECK_TYPE(socklen_t, ,
[AC_DEFINE([socklen_t], [unsigned int],
[If we don't have a real socklen_t, unsigned int is good enough.])],
[
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#endif
])
AC_ARG_ENABLE(ipv6,AC_HELP_STRING([--disable-ipv6],[Disable IPv6 support]),[ipv6=$enableval],[ipv6=yes])
if test x$ipv6 != xyes; then
have_v6="no"
else
have_v6=yes
RB_PROTO_INET6([], [
AC_MSG_NOTICE([Disabling IPv6 support: PF_INET6 not found])
have_v6=no
])
if test "X$have_v6" = "Xyes"; then
RB_TYPE_STRUCT_SOCKADDR_IN6([], [
AC_MSG_NOTICE([Disabling IPv6 support: struct sockaddr_in6 not found])
have_v6=no
])
fi
fi
AC_CHECK_TYPES([struct sockaddr_storage],[
rb_have_sockaddr_storage=yes
],[], [
#include <sys/types.h>
#include <sys/socket.h>
])
save_LIBS=$LIBS
AC_SEARCH_LIBS(crypt, [crypt descrypt],,)
LIBS=$save_LIBS
CRYPT_LIB=$ac_cv_search_crypt
if test "$CRYPT_LIB" = "none required"; then
unset CRYPT_LIB
elif test "$CRYPT_LIB" = no; then
need_crypt=yes;
AC_DEFINE(NEED_CRYPT, 1, [Define if your system needs crypt.])
unset CRYPT_LIB
fi
AM_CONDITIONAL([NEED_CRYPT], [test x"$need_crypt" == "xyes"])
AC_SUBST(CRYPT_LIB)
dnl Check for stdarg.h - if we cant find it, halt configure
AC_CHECK_HEADER(stdarg.h, , [AC_MSG_ERROR([** stdarg.h could not be found - libratbox will not compile without it **])])
AC_CHECK_TYPE([sa_family_t], [],
[AC_DEFINE(sa_family_t, [u_int16_t], [If system does not define sa_family_t, define it here.])],
[[#include <sys/types.h>
#include <sys/socket.h>]])
dnl check for various functions...
AC_CHECK_FUNCS([socketpair gettimeofday writev sendmsg gmtime_r strtok_r usleep posix_spawn strlcpy strlcat strnlen fstat signalfd select poll kevent port_create epoll_ctl])
AC_SEARCH_LIBS(nanosleep, rt posix4, AC_DEFINE(HAVE_NANOSLEEP, 1, [Define if you have nanosleep]))
AC_SEARCH_LIBS(timer_create, rt, AC_DEFINE(HAVE_TIMER_CREATE, 1, [Define if you have timer_create]))
RB_CHECK_TIMER_CREATE
AC_FUNC_ALLOCA
AC_FUNC_VFORK
AC_FUNC_MMAP
AC_MSG_CHECKING(for /dev/poll)
if test -c "/dev/poll"; then
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_DEVPOLL, [1], [Define to 1 if you have devpoll])
else
AC_MSG_RESULT(no)
fi
if test "$is_mingw" = "yes"; then
AC_DEFINE(HAVE_WIN32, [1], [Define to 1 if you are on windows])
fi
dnl OpenSSL support
AC_MSG_CHECKING(for OpenSSL)
AC_ARG_ENABLE(openssl,
[AC_HELP_STRING([--enable-openssl[=DIR]],[Enable OpenSSL support (DIR optional).])
AC_HELP_STRING([--disable-openssl],[Disable OpenSSL support.])],
[cf_enable_openssl=$enableval],
[cf_enable_openssl="auto"])
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="`echo ${cf_enable_openssl} | sed 's/\/$//'`"
else
dnl Do the auto-probe here. Check some common directory paths.
for dirs in /usr/local/ssl /usr/pkg /usr/local \
/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
SSL_INCLUDES="-I${cf_openssl_basedir}/include"
SSL_LIBS="-L${cf_openssl_basedir}/lib"
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. Specify a correct path?])
cf_enable_openssl="no"
fi
unset cf_openssl_basedir
else
dnl If --disable-openssl was specified
AC_MSG_RESULT(disabled)
fi
save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $SSL_INCLUDES"
save_LIBS="$LIBS"
LIBS="$LIBS $SSL_LIBS"
if test "$cf_enable_openssl" != no; then
dnl Check OpenSSL version (must be 0.9.7 or above!)
AC_MSG_CHECKING(for OpenSSL 0.9.7 or above)
AC_RUN_IFELSE(
AC_LANG_PROGRAM(
[#include <openssl/opensslv.h>
#include <stdlib.h>],
[[if (OPENSSL_VERSION_NUMBER >= 0x00907000)
exit(0); else exit(1);]]),
cf_enable_openssl=yes,
cf_enable_openssl=no,
cf_enable_openssl=no)
if test "$cf_enable_openssl" != no; then
AC_MSG_RESULT(found)
else
AC_MSG_RESULT(no - OpenSSL support disabled)
fi
fi
if test "$cf_enable_openssl" != no; then
CPPFLAGS="$CPPFLAGS $SSL_LIBS"
AC_CHECK_LIB(crypto, RAND_status,
[cf_enable_openssl=yes],
[cf_enable_openssl=no])
fi
if test "$cf_enable_openssl" != no; then
CPPFLAGS="$CPPFLAGS $SSL_LIBS"
AC_CHECK_LIB(ssl, SSL_read,
[SSL_LIBS="-lssl -lcrypto"],
[cf_enable_openssl=no], [-lcrypto])
fi
if test "$cf_enable_openssl" != no; then
AC_DEFINE(HAVE_OPENSSL,1,[Has OpenSSL])
fi
CPPFLAGS="$save_CPPFLAGS"
LIBS="$save_LIBS"
dnl End OpenSSL detection
dnl Debug-related options
dnl =====================
AC_ARG_ENABLE(assert,
AC_HELP_STRING([--enable-assert],[Enable assert(). Choose between soft(warnings) and hard(aborts the daemon)]),
[assert=$enableval], [assert=no])
if test "$assert" = no; then
AC_DEFINE(NDEBUG, 1, [Define this to disable debugging support.])
elif test "$assert" = soft; then
AC_DEFINE(SOFT_ASSERT, 1, [Define this to enable soft asserts.])
AC_DEFINE(NDEBUG, 1, [Define this to disable debugging support.])
elif test "$assert" = yes; then
assert = "hard";
fi
AC_MSG_CHECKING(if you want to do a profile build)
AC_ARG_ENABLE(profile,
AC_HELP_STRING([--enable-profile],[Enable profiling]),
[profile=$enableval], [profile=no])
if test "$profile" = yes; then
if test "$ac_cv_c_compiler_gnu" = yes; then
CFLAGS="$CFLAGS -pg -static"
AC_MSG_RESULT([yes, adding -pg -static])
AC_DEFINE(RATBOX_PROFILE, 1, [Defined to mark profiling is enabled])
else
AC_MSG_RESULT([no, profile builds only work with gcc])
fi
else
AC_MSG_RESULT(no)
fi
AC_ARG_ENABLE(balloc,
AC_HELP_STRING([--disable-balloc],[Disable the block allocator.]),
[balloc=$enableval], [balloc=yes])
if test "$balloc" = no; then
AC_DEFINE([NOBALLOC], 1, [Define to 1 if you wish to disable the block allocator.])
fi
AC_ARG_ENABLE(warnings,
AC_HELP_STRING([--enable-warnings],[Enable all sorts of warnings for debugging.]),
[CFLAGS="$CFLAGS -Wall -Werror -Wcast-qual -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings -W -Wno-unused -Wunused-function -Wunused-variable"],[])
AC_SUBST(LDFLAGS)
AC_SUBST(PICFLAGS)
AC_SUBST(CFLAGS)
AC_SUBST(SEDOBJ)
AC_SUBST(SSL_INCLUDES)
AC_SUBST(SSL_LIBS)
if test "$prefix" = "NONE"; then
AC_DEFINE_UNQUOTED(RB_PREFIX, "$ac_default_prefix", [Prefix where libratbox is installed.])
else
dnl Don't get bitten by Cygwin's stupidity if the user specified
dnl a custom prefix with a trailing slash
prefix=`echo $prefix | sed 's/\/$//'`
AC_DEFINE_UNQUOTED(RB_PREFIX, "$prefix", [Prefix where libratbox is installed.])
fi
AC_SUBST(RB_PREFIX)
for dtype in uint64_t uint32_t uint16_t uint8_t int64_t int32_t int16_t int8_t intmax_t intptr_t uintmax_t uintptr_t
do
var="\$ac_cv_c_${dtype}"
t_type=$(eval echo $var);
if test "x$t_type" = "xyes"; then
eval rb_$dtype="\"$dtype\""
else
eval rb_$dtype="\"$t_type\""
fi
done
AC_CONFIG_COMMANDS([include/librb-config.h],
[
outfile=include/librb-config.h.tmp
cat > $outfile <<\_______EOF
/*
* librb-config.h: libratbox config file. Please modify configure.ac
*/
#ifndef __LIBRB_CONFIG_H
#define __LIBRB_CONFIG_H
_______EOF
if test "x$rb_have_ipv6" = "xyes"; then
echo "#define RB_IPV6 1" >> $outfile
fi
if test "x$rb_windows_h" = "xyes"; then
echo '#define WIN32_LEAN_AND_MEAN 1' >> $outfile
echo '#include <windows.h>' >> $outfile
echo '#include <winsock2.h>' >> $outfile
echo '#include <iphlpapi.h>' >> $outfile
fi
if test "x$rb_alloca_h" = "xyes"; then
echo '#define RB_HAVE_ALLOCA_H 1' >> $outfile
fi
if test "x$rb_header_stdc" = "xyes"; then
echo '#include <stdlib.h>' >> $outfile
echo '#include <stddef.h>' >> $outfile
elif test "x$rb_header_stdlib" = "xyes"; then
echo '#include <stdlib.h>' >> $outfile
fi
if test "x$rb_header_string_h" = "xyes"; then
echo '#include <string.h>' >> $outfile
fi
if test "x$rb_stdint_h" = "xyes"; then
echo '#include <stdint.h>' >> $outfile
fi
if test "x$rb_inttypes_h" = "xyes"; then
echo '#include <inttypes.h>' >> $outfile
fi
if test "x$rb_sys_types_h" = "xyes"; then
echo '#include <sys/types.h>' >> $outfile
fi
if test "x$rb_sys_time_h" = "xyes"; then
echo '#include <sys/time.h>' >> $outfile
fi
if test "x$rb_sys_stat_h" = "xyes"; then
echo '#include <sys/stat.h>' >> $outfile
fi
if test "x$rb_time_h" = "xyes"; then
echo '#include <time.h>' >> $outfile
fi
if test "x$rb_sys_socket_h" = "xyes"; then
echo '#include <sys/socket.h>' >> $outfile
fi
if test "x$rb_netinet_in_h" = "xyes"; then
echo '#include <netinet/in.h>' >> $outfile
fi
if test "x$rb_arpa_inet_h" = "xyes"; then
echo '#include <arpa/inet.h>' >> $outfile
fi
if test "x$rb_unistd_h" = "xyes"; then
echo '#include <unistd.h>' >> $outfile
fi
if test "x$rb_crypt_h" = "xyes"; then
echo '#include <crypt.h>' >> $outfile
fi
if test "x$rb_errno_h" = "xyes"; then
echo '#include <errno.h>' >> $outfile
fi
if test "x$rb_sockaddr_sa_len" = "xyes"; then
echo '#define RB_SOCKADDR_HAS_SA_LEN 1' >> $outfile
fi
echo "typedef $rb_uint64_t rb_uint64_t;" >> $outfile
echo "typedef $rb_uint32_t rb_uint32_t;" >> $outfile
echo "typedef $rb_uint16_t rb_uint16_t;" >> $outfile
echo "typedef $rb_uint8_t rb_uint8_t;" >> $outfile
echo "typedef $rb_int64_t rb_int64_t;" >> $outfile
echo "typedef $rb_int32_t rb_int32_t;" >> $outfile
echo "typedef $rb_int16_t rb_int16_t;" >> $outfile
echo "typedef $rb_int8_t rb_int8_t;" >> $outfile
echo "typedef $rb_intmax_t rb_intmax_t;" >> $outfile
echo "typedef $rb_intptr_t rb_intptr_t;" >> $outfile
echo "typedef $rb_uintmax_t rb_uintmax_t;" >> $outfile
echo "typedef $rb_uintptr_t rb_uintptr_t;" >> $outfile
echo "typedef $rb_socklen_t rb_socklen_t;" >> $outfile
if test "x$rb_sockaddr_storage" = "xyes"; then
echo '#define rb_sockaddr_storage sockaddr_storage' >> $outfile
else
echo 'struct rb_sockaddr_storage { rb_uint8_t _padding[128]; };' >> $outfile
fi
cat >> $outfile <<\_______EOF
#endif /* __LIBRB_CONFIG_H */
_______EOF
if cmp -s $outfile include/librb-config.h; then
AC_MSG_NOTICE([include/librb-config.h is unchanged])
${rb_rm} -f $outfile
else
${rb_mv} $outfile include/librb-config.h
fi
],[
rb_uint64_t="$rb_uint64_t"
rb_uint32_t="$rb_uint32_t"
rb_uint16_t="$rb_uint16_t"
rb_uint8_t="$rb_uint8_t"
rb_int64_t="$rb_int64_t"
rb_int32_t="$rb_int32_t"
rb_int16_t="$rb_int16_t"
rb_int8_t="$rb_int8_t"
rb_intmax_t="$rb_intmax_t"
rb_intptr_t="$rb_intptr_t"
rb_uintmax_t="$rb_uintmax_t"
rb_uintptr_t="$rb_uintptr_t"
if test x$ac_cv_header_stdc = xyes; then
rb_header_stdc=yes
fi
if test x$ac_cv_header_stdlib_h = xyes; then
rb_header_stdlib_h=yes
fi
if test x$ac_cv_header_string_h = xyes; then
rb_header_string_h=yes
fi
if test x$ac_cv_header_memory_h = xyes; then
rb_header_memory_h=yes
fi
if test "x${ac_cv_working_alloca_h+set}" = xset ; then
rb_alloca_h="$ac_cv_working_alloca_h"
else
rb_alloc_h="$ac_cv_header_alloca_h"
fi
if test x$ac_cv_member_struct_sockaddr_sa_len = xyes; then
rb_sockaddr_sa_len=yes
fi
if test x$ac_cv_header_sys_socket_h = xyes; then
rb_sys_socket_h=yes
fi
if test x$ac_cv_header_sys_types_h = xyes; then
rb_sys_types_h=yes
fi
if test x$ac_cv_header_sys_stat_h = xyes; then
rb_sys_stat_h=yes
fi
if test x$ac_cv_header_sys_time_h = xyes; then
rb_sys_time_h=yes
fi
if test x$ac_cv_header_time = xyes; then
rb_time_h=yes
fi
if test x$ac_cv_header_stdint_h = xyes; then
rb_stdint_h=yes
fi
if test x$ac_cv_header_inttypes_h = xyes; then
rb_inttypes_h=yes
fi
if test x$ac_cv_header_netinet_in_h = xyes; then
rb_netinet_in_h=yes
fi
if test x$ac_cv_header_crypt_h = xyes; then
rb_crypt_h=yes
fi
if test x$ac_cv_header_errno_h = xyes; then
rb_errno_h=yes
fi
if test x$ac_cv_header_unistd_h = xyes; then
rb_unistd_h=yes
fi
if test x$ac_cv_header_windows_h = xyes; then
rb_windows_h=yes
fi
if test x$ac_cv_header_winsock2_h = xyes; then
rb_winsock2_h=yes
fi
if test x$ac_cv_type_socklen_t = xyes; then
rb_socklen_t="socklen_t"
else
rb_socklen_t="unsigned int"
fi
if test "x$rb_have_sockaddr_storage" = "xyes"; then
rb_sockaddr_storage="yes"
else
rb_sockaddr_storage="no"
fi
rb_have_ipv6="$have_v6"
rb_mv="$MV"
rb_rm="$RM"
]
)
AC_CONFIG_FILES( \
src/Makefile \
Makefile \
)
AC_OUTPUT
dnl Make it look sexay!
echo
echo "Compiling $PACKAGE_NAME $PACKAGE_VERSION"
echo
echo "Installing into: $prefix"
echo "IPv6 support ................... $have_v6"
echo "Assert debugging ............... $assert"
echo "Block allocator ................ $balloc"
echo "OpenSSL ........................ $cf_enable_openssl"
echo

526
libratbox/depcomp Executable file
View file

@ -0,0 +1,526 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2004-04-25.13
# Copyright (C) 1999, 2000, 2003, 2004 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by 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'.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit 0
;;
-v | --v*)
echo "depcomp $scriptversion"
exit 0
;;
esac
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
# `libtool' can also be set to `yes' or `no'.
if test -z "$depfile"; then
base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
dir=`echo "$object" | sed 's,/.*$,/,'`
if test "$dir" = "$object"; then
dir=
fi
# FIXME: should be _deps on DOS.
depfile="$dir.deps/$base"
fi
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
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.
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
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 ' ' '
' < "$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.
## 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"
;;
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 ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$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"
;;
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.
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test -f "$tmpdepfile"; then :
else
stripped=`echo "$stripped" | sed 's,^.*/,,'`
tmpdepfile="$stripped.u"
fi
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
outname="$stripped.o"
# 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,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$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 understands `-MD -MF file'. However on
# icc -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 ... \
# ...
"$@" -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 "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"
;;
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
# Dependencies are output in .lo.d with libtool 1.4.
# They are output in .o.d with libtool 1.5.
tmpdepfile1="$dir.libs/$base.lo.d"
tmpdepfile2="$dir.libs/$base.o.d"
tmpdepfile3="$dir.libs/$base.d"
"$@" -Wc,-MD
else
tmpdepfile1="$dir$base.o.d"
tmpdepfile2="$dir$base.d"
tmpdepfile3="$dir$base.d"
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
if test -f "$tmpdepfile1"; then
tmpdepfile="$tmpdepfile1"
elif test -f "$tmpdepfile2"; then
tmpdepfile="$tmpdepfile2"
else
tmpdepfile="$tmpdepfile3"
fi
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#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 $1 != '--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:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$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 $1 != '--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
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.
-*|$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"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## 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 $1 != '--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 '/^# [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, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
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-end: "$"
# End:

View file

@ -0,0 +1,232 @@
/*
* ircd-ratbox: A slightly useful ircd.
* commio-int.h: A header for the network subsystem.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2007 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: commio.h 24059 2007-07-24 17:25:41Z androsyn $
*/
#define RB_FD_HASH_BITS 12
#define RB_FD_HASH_SIZE (1UL << RB_FD_HASH_BITS)
#define RB_FD_HASH_MASK (RB_FD_HASH_SIZE-1)
#define FD_DESC_SZ 128 /* hostlen + comment */
#ifdef WIN32
#define rb_get_errno() do { errno = WSAGetLastError(); WSASetLastError(errno); } while(0)
#else
#define rb_get_errno()
#endif
#define rb_hash_fd(x) ((x ^ (x >> RB_FD_HASH_BITS) ^ (x >> (RB_FD_HASH_BITS * 2))) & RB_FD_HASH_MASK)
#ifdef HAVE_WRITEV
#ifndef UIO_MAXIOV
# if defined(__FreeBSD__) || defined(__APPLE__) || defined(__NetBSD__)
/* FreeBSD 4.7 defines it in sys/uio.h only if _KERNEL is specified */
# define RB_UIO_MAXIOV 1024
# elif defined(__sgi)
/* IRIX 6.5 has sysconf(_SC_IOV_MAX) which might return 512 or bigger */
# define RB_UIO_MAXIOV 512
# elif defined(__sun)
/* Solaris (and SunOS?) defines IOV_MAX instead */
# ifndef IOV_MAX
# define RB_UIO_MAXIOV 16
# else
# define RB_UIO_MAXIOV IOV_MAX
# endif
# elif defined(IOV_MAX)
# define RB_UIO_MAXIOV IOV_MAX
# else
# define RB_UIO_MAXIOV 16
# endif
#else
#define RB_UIO_MAXIOV UIO_MAXIOV
#endif
#else
#define RB_UIO_MAXIOV 16
#endif
struct conndata
{
/* We don't need the host here ? */
struct rb_sockaddr_storage S;
struct rb_sockaddr_storage hostaddr;
time_t t;
CNCB *callback;
void *data;
/* We'd also add the retry count here when we get to that -- adrian */
};
struct acceptdata
{
struct rb_sockaddr_storage S;
rb_socklen_t addrlen;
ACCB *callback;
ACPRE *precb;
void *data;
};
/* Only have open flags for now, could be more later */
#define FLAG_OPEN 0x1
#define IsFDOpen(F) (F->flags & FLAG_OPEN)
#define SetFDOpen(F) (F->flags |= FLAG_OPEN)
#define ClearFDOpen(F) (F->flags &= ~FLAG_OPEN)
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?
*/
rb_dlink_node node;
int fd; /* So we can use the rb_fde_t as a callback ptr */
rb_uint8_t flags;
rb_uint8_t type;
int pflags;
char *desc;
PF *read_handler;
void *read_data;
PF *write_handler;
void *write_data;
struct timeout_data *timeout;
struct conndata *connect;
struct acceptdata *accept;
void *ssl;
unsigned long ssl_errno;
};
typedef void (*comm_event_cb_t)(void *);
#ifdef USE_TIMER_CREATE
typedef struct timer_data {
timer_t td_timer_id;
comm_event_cb_t td_cb;
void *td_udata;
int td_repeat;
} *comm_event_id;
#endif
extern rb_dlink_list *rb_fd_table;
static inline rb_fde_t *
rb_find_fd(int fd)
{
rb_dlink_list *hlist;
rb_dlink_node *ptr;
if(unlikely(fd < 0))
return NULL;
hlist = &rb_fd_table[rb_hash_fd(fd)];
if(hlist->head == NULL)
return NULL;
RB_DLINK_FOREACH(ptr, hlist->head)
{
rb_fde_t *F = ptr->data;
if(F->fd == fd)
return F;
}
return NULL;
}
int rb_setup_fd(rb_fde_t *F);
void rb_connect_callback(rb_fde_t *F, int status);
int rb_io_sched_event(struct ev_entry *ev, int when);
void rb_io_unsched_event(struct ev_entry *ev);
int rb_io_supports_event(void);
void rb_io_init_event(void);
/* epoll versions */
void rb_setselect_epoll(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
int rb_init_netio_epoll(void);
int rb_select_epoll(long);
int rb_setup_fd_epoll(rb_fde_t *F);
void rb_epoll_init_event(void);
int rb_epoll_sched_event(struct ev_entry *event, int when);
void rb_epoll_unsched_event(struct ev_entry *event);
int rb_epoll_supports_event(void);
/* poll versions */
void rb_setselect_poll(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
int rb_init_netio_poll(void);
int rb_select_poll(long);
int rb_setup_fd_poll(rb_fde_t *F);
/* devpoll versions */
void rb_setselect_devpoll(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
int rb_init_netio_devpoll(void);
int rb_select_devpoll(long);
int rb_setup_fd_devpoll(rb_fde_t *F);
/* sigio versions */
void rb_setselect_sigio(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
int rb_init_netio_sigio(void);
int rb_select_sigio(long);
int rb_setup_fd_sigio(rb_fde_t *F);
void rb_sigio_init_event(void);
int rb_sigio_sched_event(struct ev_entry *event, int when);
void rb_sigio_unsched_event(struct ev_entry *event);
int rb_sigio_supports_event(void);
/* ports versions */
void rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
int rb_init_netio_ports(void);
int rb_select_ports(long);
int rb_setup_fd_ports(rb_fde_t *F);
/* kqueue versions */
void rb_setselect_kqueue(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
int rb_init_netio_kqueue(void);
int rb_select_kqueue(long);
int rb_setup_fd_kqueue(rb_fde_t *F);
void rb_kqueue_init_event(void);
int rb_kqueue_sched_event(struct ev_entry *event, int when);
void rb_kqueue_unsched_event(struct ev_entry *event);
int rb_kqueue_supports_event(void);
/* select versions */
void rb_setselect_select(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
int rb_init_netio_select(void);
int rb_select_select(long);
int rb_setup_fd_select(rb_fde_t *F);
/* win32 versions */
void rb_setselect_win32(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
int rb_init_netio_win32(void);
int rb_select_win32(long);
int rb_setup_fd_win32(rb_fde_t *F);

View file

@ -0,0 +1,17 @@
int rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile);
int rb_init_ssl(void);
int rb_ssl_listen(rb_fde_t *F, int backlog);
int rb_init_prng(const char *path, prng_seed_t seed_type);
int rb_get_random(void *buf, size_t length);
const char *rb_get_ssl_strerror(rb_fde_t *F);
void rb_ssl_start_accepted(rb_fde_t *new_F, ACCB *cb, void *data, int timeout);
void rb_ssl_start_connected(rb_fde_t *F, CNCB *callback, void *data, int timeout);
void rb_connect_tcp_ssl(rb_fde_t *F, struct sockaddr *dest, struct sockaddr *clocal, int socklen, CNCB *callback, void *data, int timeout);
void rb_ssl_accept_setup(rb_fde_t *F, int new_fd, struct sockaddr *st, int addrlen);
void rb_ssl_shutdown(rb_fde_t *F);
ssize_t rb_ssl_read(rb_fde_t *F, void *buf, size_t count);
ssize_t rb_ssl_write(rb_fde_t *F, const void *buf, size_t count);

View file

@ -0,0 +1,38 @@
/*
* ircd-ratbox: A slightly useful ircd.
* event-int.h: internal structs for events
*
* Copyright (C) 2007 ircd-ratbox development team
* Copyright (C) 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: event-int.h 24840 2008-01-03 19:42:17Z androsyn $
*/
struct ev_entry
{
rb_dlink_node node;
EVH *func;
void *arg;
const char *name;
time_t frequency;
time_t when;
void *data;
void *comm_ptr;
};
void rb_event_io_register_all(void);

View file

@ -0,0 +1,374 @@
/* include/libratbox_config.h.in. Generated from configure.ac by autoheader. */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
#undef CRAY_STACKSEG_END
/* This is a Cygwin system */
#undef CYGWIN
/* Define to 1 if using `alloca.c'. */
#undef C_ALLOCA
/* Define to 1 if you have `alloca', as a function or macro. */
#undef HAVE_ALLOCA
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#undef HAVE_ALLOCA_H
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define to 1 if you have the <crypt.h> header file. */
#undef HAVE_CRYPT_H
/* Define to 1 if you have devpoll */
#undef HAVE_DEVPOLL
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `epoll_ctl' function. */
#undef HAVE_EPOLL_CTL
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define to 1 if you have the `fstat' function. */
#undef HAVE_FSTAT
/* Define to 1 if you have the `getpagesize' function. */
#undef HAVE_GETPAGESIZE
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the `gmtime_r' function. */
#undef HAVE_GMTIME_R
/* Define to 1 if the system has the type `intmax_t'. */
#undef HAVE_INTMAX_T
/* Define to 1 if the system has the type `intptr_t'. */
#undef HAVE_INTPTR_T
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `kevent' function. */
#undef HAVE_KEVENT
/* Define to 1 if the system has the type `long long int'. */
#undef HAVE_LONG_LONG_INT
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have a working `mmap' system call. */
#undef HAVE_MMAP
/* Define if you have nanosleep */
#undef HAVE_NANOSLEEP
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Has OpenSSL */
#undef HAVE_OPENSSL
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL
/* Define to 1 if you have the `port_create' function. */
#undef HAVE_PORT_CREATE
/* Define to 1 if you have the <port.h> header file. */
#undef HAVE_PORT_H
/* Define to 1 if you have the `posix_spawn' function. */
#undef HAVE_POSIX_SPAWN
/* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT
/* Define to 1 if you have the `sendmsg' function. */
#undef HAVE_SENDMSG
/* Define to 1 if you have the `signalfd' function. */
#undef HAVE_SIGNALFD
/* Define to 1 if you have the <signal.h> header file. */
#undef HAVE_SIGNAL_H
/* Define to 1 if you have the `socketpair' function. */
#undef HAVE_SOCKETPAIR
/* Define to 1 if you have the <spawn.h> header file. */
#undef HAVE_SPAWN_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 `strnlen' function. */
#undef HAVE_STRNLEN
/* Define to 1 if you have the `strtok_r' function. */
#undef HAVE_STRTOK_R
/* Define to 1 if the system has the type `struct sockaddr_in6'. */
#undef HAVE_STRUCT_SOCKADDR_IN6
/* 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/epoll.h> header file. */
#undef HAVE_SYS_EPOLL_H
/* Define to 1 if you have the <sys/event.h> header file. */
#undef HAVE_SYS_EVENT_H
/* Define to 1 if you have the <sys/poll.h> header file. */
#undef HAVE_SYS_POLL_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/signalfd.h> header file. */
#undef HAVE_SYS_SIGNALFD_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/uio.h> header file. */
#undef HAVE_SYS_UIO_H
/* Define if you have timer_create */
#undef HAVE_TIMER_CREATE
/* Define to 1 if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* Define to 1 if the system has the type `uintmax_t'. */
#undef HAVE_UINTMAX_T
/* Define to 1 if the system has the type `uintptr_t'. */
#undef HAVE_UINTPTR_T
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if the system has the type `unsigned long long int'. */
#undef HAVE_UNSIGNED_LONG_LONG_INT
/* Define to 1 if you have the `usleep' function. */
#undef HAVE_USLEEP
/* Define to 1 if you have the `vfork' function. */
#undef HAVE_VFORK
/* Define to 1 if you have the <vfork.h> header file. */
#undef HAVE_VFORK_H
/* Define to 1 if you are on windows */
#undef HAVE_WIN32
/* Define to 1 if `fork' works. */
#undef HAVE_WORKING_FORK
/* Define to 1 if `vfork' works. */
#undef HAVE_WORKING_VFORK
/* Define to 1 if you have the `writev' function. */
#undef HAVE_WRITEV
/* This is a MinGW system */
#undef MINGW
/* Define this to disable debugging support. */
#undef NDEBUG
/* Define if your system needs crypt. */
#undef NEED_CRYPT
/* Define to 1 if you wish to disable the block allocator. */
#undef NOBALLOC
/* 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 version of this package. */
#undef PACKAGE_VERSION
/* Defined to mark profiling is enabled */
#undef RATBOX_PROFILE
/* Prefix where libratbox is installed. */
#undef RB_PREFIX
/* Define to 1 if sockaddr has a 'sa_len' member. */
#undef SOCKADDR_IN_HAS_LEN
/* Define this to enable soft asserts. */
#undef SOFT_ASSERT
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#undef STACK_DIRECTION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define to 1 if we can use timer_create(CLOCK_REALTIME,...) */
#undef USE_TIMER_CREATE
/* This is a Windows system */
#undef WINDOWS
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef was allowed, the
#define below would cause a syntax error. */
#undef _UINT32_T
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef was allowed, the
#define below would cause a syntax error. */
#undef _UINT64_T
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef was allowed, the
#define below would cause a syntax error. */
#undef _UINT8_T
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to the type of a signed integer type of width exactly 16 bits if
such a type exists and the standard includes do not define it. */
#undef int16_t
/* Define to the type of a signed integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
#undef int32_t
/* Define to the type of a signed integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
#undef int64_t
/* Define to the type of a signed integer type of width exactly 8 bits if such
a type exists and the standard includes do not define it. */
#undef int8_t
/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
not define. */
#undef intmax_t
/* Define to the type of a signed integer type wide enough to hold a pointer,
if such a type exists, and if the system does not define it. */
#undef intptr_t
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* If system does not define sa_family_t, define it here. */
#undef sa_family_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* If we don't have a real socklen_t, unsigned int is good enough. */
#undef socklen_t
/* Define to `int' if <sys/types.h> does not define. */
#undef ssize_t
/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t
/* Define to the type of an unsigned integer type of width exactly 16 bits if
such a type exists and the standard includes do not define it. */
#undef uint16_t
/* Define to the type of an unsigned integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
#undef uint32_t
/* Define to the type of an unsigned integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
#undef uint64_t
/* Define to the type of an unsigned integer type of width exactly 8 bits if
such a type exists and the standard includes do not define it. */
#undef uint8_t
/* Define to the widest unsigned integer type if <stdint.h> and <inttypes.h>
do not define. */
#undef uintmax_t
/* Define to the type of an unsigned integer type wide enough to hold a
pointer, if such a type exists, and if the system does not define it. */
#undef uintptr_t
/* Define as `fork' if `vfork' does not work. */
#undef vfork

View file

@ -0,0 +1,224 @@
/*
* $Id: ratbox_lib.h 24866 2008-01-10 16:33:54Z androsyn $
*/
#ifndef RB_LIB_H
#define RB_LIB_H 1
#include <librb-config.h>
#include <stdio.h>
#include <limits.h>
#include <stdarg.h>
#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <ctype.h>
#ifdef __GNUC__
#undef alloca
#define alloca __builtin_alloca
#else
# ifdef _MSC_VER
# include <malloc.h>
# define alloca _alloca
# else
# if RB_HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca();
# endif
# endif
# endif
# endif
#endif /* __GNUC__ */
#ifdef __GNUC__
#ifdef likely
#undef likely
#endif
#ifdef unlikely
#undef unlikely
#endif
#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
# define __builtin_expect(x, expected_value) (x)
#endif
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else /* !__GNUC__ */
#define UNUSED(x) x
#ifdef likely
#undef likely
#endif
#ifdef unlikely
#undef unlikely
#endif
#define likely(x) (x)
#define unlikely(x) (x)
#endif
#ifdef WIN32
#include <process.h>
#ifndef MAXPATHLEN
#define MAXPATHLEN 128
#endif
#ifdef strerror
#undef strerror
#endif
#define strerror(x) wsock_strerror(x)
const char *wsock_strerror(int error);
#define ENOBUFS WSAENOBUFS
#define EINPROGRESS WSAEINPROGRESS
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EMSGSIZE WSAEMSGSIZE
#define EALREADY WSAEALREADY
#define EISCONN WSAEISCONN
#define EADDRINUSE WSAEADDRINUSE
#define EAFNOSUPPORT WSAEAFNOSUPPORT
#define pipe(x) _pipe(x, 1024, O_BINARY)
#define ioctl(x,y,z) ioctlsocket(x,y, (u_long *)z)
int setenv(const char *, const char *, int);
int kill(int pid, int sig);
#define WNOHANG 1
pid_t waitpid(pid_t pid, int *status, int options);
pid_t getpid(void);
unsigned int geteuid(void);
#ifndef SIGKILL
#define SIGKILL SIGTERM
#endif
#endif /* WIN32 */
#ifndef HOSTIPLEN
#define HOSTIPLEN 53
#endif
#ifdef SOFT_ASSERT
#ifdef __GNUC__
#define lrb_assert(expr) do \
if(unlikely(!(expr))) { \
lib_ilog(L_MAIN, \
"file: %s line: %d (%s): Assertion failed: (%s)", \
__FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
sendto_realops_flags(UMODE_ALL, L_ALL, \
"file: %s line: %d (%s): Assertion failed: (%s)", \
__FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
} \
while(0)
#else
#define lrb_assert(expr) do \
if(unlikely(!(expr))) { \
lib_ilog(L_MAIN, \
"file: %s line: %d: Assertion failed: (%s)", \
__FILE__, __LINE__, #expr); \
sendto_realops_flags(UMODE_ALL, L_ALL, \
"file: %s line: %d: Assertion failed: (%s)" \
__FILE__, __LINE__, #expr); \
} \
while(0)
#endif
#else
#define lrb_assert(expr) assert(expr)
#endif
#ifdef SOCKADDR_IN_HAS_LEN
#define ss_len sa_len
#endif
#define GET_SS_FAMILY(x) (((struct sockaddr *)(x))->sa_family)
#ifdef SOCKADDR_IN_HAS_LEN
#define SET_SS_LEN(x, y) do { \
struct sockaddr *storage; \
storage = ((struct sockaddr *)(x));\
storage->sa_len = (y); \
} while (0)
#define GET_SS_LEN(x) (((struct sockaddr *)(x))->sa_len)
#else /* !SOCKADDR_IN_HAS_LEN */
#define SET_SS_LEN(x, y) (((struct sockaddr *)(x))->sa_family = ((struct sockaddr *)(x))->sa_family)
#ifdef RB_IPV6
#define GET_SS_LEN(x) (((struct sockaddr *)(x))->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))
#else
#define GET_SS_LEN(x) (((struct sockaddr *)(x))->sa_family == AF_INET ? sizeof(struct sockaddr_in) : 0)
#endif
#endif
#ifndef INADDRSZ
#define INADDRSZ 4
#endif
#ifndef IN6ADDRSZ
#define IN6ADDRSZ 16
#endif
#ifndef INT16SZ
#define INT16SZ 2
#endif
typedef void log_cb(const char *buffer);
typedef void restart_cb(const char *buffer);
typedef void die_cb(const char *buffer);
char *rb_ctime(const time_t, char *, size_t);
char *rb_date(const time_t, char *, size_t);
void rb_lib_log(const char *, ...);
void rb_lib_restart(const char *, ...);
void rb_lib_die(const char *, ...);
void rb_set_time(void);
const char *rb_lib_version(void);
void rb_lib_init(log_cb * xilog, restart_cb * irestart, die_cb * idie, int closeall, int maxfds,
size_t dh_size, size_t fd_heap_size);
void rb_lib_loop(long delay);
time_t rb_current_time(void);
const struct timeval *rb_current_time_tv(void);
pid_t rb_spawn_process(const char *, const char **);
char *rb_strtok_r(char *, const char *, char **);
int rb_gettimeofday(struct timeval *, void *);
void rb_sleep(unsigned int seconds, unsigned int useconds);
char *rb_crypt(const char *, const char *);
unsigned char *rb_base64_encode(const unsigned char *str, int length);
unsigned char *rb_base64_decode(const unsigned char *str, int length, int *ret);
#include <rb_tools.h>
#include <rb_memory.h>
#include <rb_commio.h>
#include <rb_balloc.h>
#include <rb_linebuf.h>
#include <rb_snprintf.h>
#include <rb_event.h>
#include <rb_helper.h>
#include <rb_rawbuf.h>
#include <rb_patricia.h>
#endif

View file

@ -0,0 +1,51 @@
/*
* ircd-ratbox: A slightly useful ircd.
* balloc.h: The ircd block allocator header.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: rb_balloc.h 24324 2007-08-31 22:05:45Z androsyn $
*/
#ifndef RB_LIB_H
# error "Do not use balloc.h directly"
#endif
#ifndef INCLUDED_balloc_h
#define INCLUDED_balloc_h
struct rb_bh;
typedef struct rb_bh rb_bh;
typedef void rb_bh_usage_cb(size_t bused, size_t bfree, size_t bmemusage, size_t heapalloc, const char *desc, void *data);
int rb_bh_free(rb_bh *, void *);
void *rb_bh_alloc(rb_bh *);
rb_bh *rb_bh_create(size_t elemsize, int elemsperblock, const char *desc);
int rb_bh_destroy(rb_bh * bh);
int rb_bh_gc(rb_bh *bh);
void rb_init_bh(void);
void rb_bh_usage(rb_bh * bh, size_t * bused, size_t * bfree, size_t * bmemusage, const char **desc);
void rb_bh_usage_all(rb_bh_usage_cb *cb, void *data);
void rb_bh_total_usage(size_t *total_alloc, size_t *total_used);
#endif /* INCLUDED_balloc_h */

View file

@ -0,0 +1,172 @@
/*
* ircd-ratbox: A slightly useful ircd.
* commio.h: A header for the network subsystem.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: rb_commio.h 25038 2008-01-23 16:03:08Z androsyn $
*/
#ifndef RB_LIB_H
# error "Do not use commio.h directly"
#endif
#ifndef INCLUDED_commio_h
#define INCLUDED_commio_h
struct sockaddr;
struct _fde;
typedef struct _fde rb_fde_t;
/* Callback for completed IO events */
typedef void PF(rb_fde_t *, void *);
/* Callback for completed connections */
/* int fd, int status, void * */
typedef void CNCB(rb_fde_t *, int, void *);
/* callback for fd table dumps */
typedef void DUMPCB(int, const char *desc, void *);
/* callback for accept callbacks */
typedef void ACCB(rb_fde_t *, int status, struct sockaddr *addr, rb_socklen_t len, void *);
/* callback for pre-accept callback */
typedef int ACPRE(rb_fde_t *, struct sockaddr *addr, rb_socklen_t len, void *);
enum
{
RB_OK,
RB_ERR_BIND,
RB_ERR_DNS,
RB_ERR_TIMEOUT,
RB_ERR_CONNECT,
RB_ERROR,
RB_ERROR_SSL,
RB_ERR_MAX
};
#define RB_FD_NONE 0x01
#define RB_FD_FILE 0x02
#define RB_FD_SOCKET 0x04
#ifndef WIN32
#define RB_FD_PIPE 0x08
#else
#define RB_FD_PIPE RB_FD_SOCKET
#endif
#define RB_FD_LISTEN 0x10
#define RB_FD_SSL 0x20
#define RB_FD_UNKNOWN 0x40
#define RB_RW_IO_ERROR -1 /* System call error */
#define RB_RW_SSL_ERROR -2 /* SSL Error */
#define RB_RW_SSL_NEED_READ -3 /* SSL Needs read */
#define RB_RW_SSL_NEED_WRITE -4 /* SSL Needs write */
struct rb_iovec
{
void *iov_base;
size_t iov_len;
};
void rb_fdlist_init(int closeall, int maxfds, size_t heapsize);
rb_fde_t * rb_open(int, rb_uint8_t, const char *);
void rb_close(rb_fde_t *);
void rb_dump_fd(DUMPCB *, void *xdata);
void rb_note(rb_fde_t *, const char *);
/* Type of IO */
#define RB_SELECT_READ 0x1
#define RB_SELECT_WRITE 0x2
#define RB_SELECT_ACCEPT RB_SELECT_READ
#define RB_SELECT_CONNECT RB_SELECT_WRITE
int rb_set_nb(rb_fde_t *);
int rb_set_buffers(rb_fde_t *, int);
int rb_get_sockerr(rb_fde_t *);
void rb_settimeout(rb_fde_t *, time_t, PF *, void *);
void rb_checktimeouts(void *);
void rb_connect_tcp(rb_fde_t *, struct sockaddr *,
struct sockaddr *, int, CNCB *, void *, int);
void rb_connect_tcp_ssl(rb_fde_t *, struct sockaddr *,
struct sockaddr *, int, CNCB *, void *, int);
int rb_connect_sockaddr(rb_fde_t *, struct sockaddr *addr, int len);
const char *rb_errstr(int status);
rb_fde_t *rb_socket(int family, int sock_type, int proto, const char *note);
int rb_socketpair(int family, int sock_type, int proto, rb_fde_t **F1, rb_fde_t **F2, const char *note);
void rb_accept_tcp(rb_fde_t *, ACPRE *precb, ACCB *callback, void *data);
ssize_t rb_write(rb_fde_t *, const void *buf, int count);
ssize_t rb_writev(rb_fde_t *, struct rb_iovec *vector, int count);
ssize_t rb_read(rb_fde_t *, void *buf, int count);
int rb_pipe(rb_fde_t **, rb_fde_t **, const char *desc);
int rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile);
int rb_ssl_listen(rb_fde_t *, int backlog);
int rb_listen(rb_fde_t *, int backlog);
const char *rb_inet_ntop(int af, const void *src, char *dst, unsigned int size);
int rb_inet_pton(int af, const char *src, void *dst);
const char *rb_inet_ntop_sock(struct sockaddr *src, char *dst, unsigned int size);
int rb_inet_pton_sock(const char *src, struct sockaddr *dst);
int rb_getmaxconnect(void);
int rb_ignore_errno(int);
/* Generic wrappers */
void rb_setselect(rb_fde_t *, unsigned int type, PF * handler, void *client_data);
void rb_init_netio(void);
int rb_select(unsigned long);
int rb_fd_ssl(rb_fde_t *F);
int rb_get_fd(rb_fde_t *F);
const char *rb_get_ssl_strerror(rb_fde_t *F);
rb_fde_t *rb_get_fde(int fd);
int rb_send_fd_buf(rb_fde_t *xF, rb_fde_t **F, int count, void *data, size_t datasize);
int rb_recv_fd_buf(rb_fde_t *F, void *data, size_t datasize, rb_fde_t **xF, int count);
void rb_set_type(rb_fde_t *F, rb_uint8_t type);
rb_uint8_t rb_get_type(rb_fde_t *F);
const char *rb_get_iotype(void);
typedef enum {
RB_PRNG_EGD,
RB_PRNG_FILE,
#ifdef WIN32
RB_PRNGWIN32,
#endif
RB_PRNG_DEFAULT,
} prng_seed_t;
int rb_init_prng(const char *path, prng_seed_t seed_type);
int rb_get_random(void *buf, size_t len);
void rb_ssl_start_accepted(rb_fde_t *new_F, ACCB *cb, void *data, int timeout);
void rb_ssl_start_connected(rb_fde_t *F, CNCB *callback, void *data, int timeout);
int rb_supports_ssl(void);
#endif /* INCLUDED_commio_h */

View file

@ -0,0 +1,50 @@
/*
* ircd-ratbox: A slightly useful ircd.
* event.h: The ircd event header.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: rb_event.h 25151 2008-03-28 17:19:12Z androsyn $
*/
#ifndef RB_LIB_H
# error "Do not use event.h directly"
#endif
#ifndef INCLUDED_event_h
#define INCLUDED_event_h
struct ev_entry;
typedef void EVH(void *);
struct ev_entry *rb_event_add(const char *name, EVH * func, void *arg, time_t when);
struct ev_entry *rb_event_addonce(const char *name, EVH * func, void *arg, time_t when);
struct ev_entry *rb_event_addish(const char *name, EVH * func, void *arg, time_t delta_ish);
void rb_event_run(void);
void rb_event_init(void);
void rb_event_delete(struct ev_entry *);
void rb_event_find_delete(EVH * func, void *);
void rb_event_update(struct ev_entry *, time_t freq);
void rb_set_back_events(time_t);
void rb_dump_events(void (*func)(char *, void *), void *ptr);
void rb_run_event(struct ev_entry *);
time_t rb_event_next(void);
#endif /* INCLUDED_event_h */

View file

@ -0,0 +1,60 @@
/*
* ircd-ratbox: A slightly useful ircd
* helper.h: Starts and deals with ircd helpers
*
* Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: rb_helper.h 24936 2008-01-14 20:43:23Z androsyn $
*/
#ifndef RB_LIB_H
# error "Do not use helper.h directly"
#endif
#ifndef INCLUDED_helper_h
#define INCLUDED_helper_h
struct _rb_helper;
typedef struct _rb_helper rb_helper;
typedef void rb_helper_cb(rb_helper *);
rb_helper *rb_helper_start(const char *name, const char *fullpath, rb_helper_cb *read_cb, rb_helper_cb *error_cb);
rb_helper *rb_helper_child(rb_helper_cb *read_cb, rb_helper_cb *error_cb,
log_cb *ilog, restart_cb *irestart, die_cb *idie,
int maxcon, size_t lb_heap_size, size_t dh_size, size_t fd_heap_size);
void rb_helper_restart(rb_helper *helper);
#ifdef __GNUC__
void rb_helper_write(rb_helper *helper, const char *format, ...) __attribute((format(printf, 2, 3)));
void rb_helper_write_queue(rb_helper *helper, const char *format, ...) __attribute((format(printf, 2, 3)));
#else
void rb_helper_write(rb_helper *helper, const char *format, ...);
void rb_helper_write_queue(rb_helper *helper, const char *format, ...);
#endif
void rb_helper_write_flush(rb_helper *helper);
void rb_helper_run(rb_helper *helper);
void rb_helper_close(rb_helper *helper);
int rb_helper_read(rb_helper *helper, void *buf, size_t bufsize);
void rb_helper_loop(rb_helper *helper, long delay);
#endif

View file

@ -0,0 +1,84 @@
/*
* ircd-ratbox: A slightly useful ircd.
* linebuf.h: A header for the linebuf code.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: rb_linebuf.h 24324 2007-08-31 22:05:45Z androsyn $
*/
#ifndef RB_LIB_H
# error "Do not use linebuf.h directly"
#endif
#ifndef __LINEBUF_H__
#define __LINEBUF_H__
#define LINEBUF_COMPLETE 0
#define LINEBUF_PARTIAL 1
#define LINEBUF_PARSED 0
#define LINEBUF_RAW 1
struct _buf_line;
struct _buf_head;
/* How big we want a buffer - 510 data bytes, plus space for a '\0' */
#define BUF_DATA_SIZE 511
typedef struct _buf_line
{
char buf[BUF_DATA_SIZE + 2];
rb_uint8_t terminated; /* Whether we've terminated the buffer */
rb_uint8_t flushing; /* Whether we're flushing .. */
rb_uint8_t raw; /* Whether this linebuf may hold 8-bit data */
int len; /* How much data we've got */
int refcount; /* how many linked lists are we in? */
} buf_line_t;
typedef struct _buf_head
{
rb_dlink_list list; /* the actual dlink list */
int len; /* length of all the data */
int alloclen; /* Actual allocated data length */
int writeofs; /* offset in the first line for the write */
int numlines; /* number of lines */
} buf_head_t;
/* they should be functions, but .. */
#define rb_linebuf_len(x) ((x)->len)
#define rb_linebuf_alloclen(x) ((x)->alloclen)
#define rb_linebuf_numlines(x) ((x)->numlines)
void rb_linebuf_init(size_t heap_size);
void rb_linebuf_newbuf(buf_head_t *);
void rb_linebuf_donebuf(buf_head_t *);
int rb_linebuf_parse(buf_head_t *, char *, int, int);
int rb_linebuf_get(buf_head_t *, char *, int, int, int);
void rb_linebuf_putmsg(buf_head_t *, const char *, va_list *, const char *, ...);
void rb_linebuf_put(buf_head_t *, const char *, ...);
void rb_linebuf_putbuf(buf_head_t *bufhead, const char *buffer);
void rb_linebuf_attach(buf_head_t *, buf_head_t *);
void rb_count_rb_linebuf_memory(size_t *, size_t *);
int rb_linebuf_flush(rb_fde_t *F, buf_head_t *);
#endif

View file

@ -0,0 +1,86 @@
/*
* ircd-ratbox: A slightly useful ircd.
* memory.h: A header for the memory functions.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: rb_memory.h 25022 2008-01-23 03:54:00Z androsyn $
*/
#ifndef RB_LIB_H
#error "Do not use rb_memory.h directly"
#endif
#ifndef _RB_MEMORY_H
#define _RB_MEMORY_H
#include <stdlib.h>
void rb_outofmemory(void);
static inline void *
rb_malloc(size_t size)
{
void *ret = calloc(1, size);
if(unlikely(ret == NULL))
rb_outofmemory();
return (ret);
}
static inline void *
rb_realloc(void *x, size_t y)
{
void *ret = realloc(x, y);
if(unlikely(ret == NULL))
rb_outofmemory();
return (ret);
}
static inline char *
rb_strndup(const char *x, size_t y)
{
char *ret = malloc(y);
if(unlikely(ret == NULL))
rb_outofmemory();
rb_strlcpy(ret, x, y);
return(ret);
}
static inline char *
rb_strdup(const char *x)
{
char *ret = malloc(strlen(x) + 1);
if(unlikely(ret == NULL))
rb_outofmemory();
strcpy(ret, x);
return(ret);
}
static inline void
rb_free(void *ptr)
{
if(likely(ptr != NULL))
free(ptr);
}
#endif /* _I_MEMORY_H */

View file

@ -0,0 +1,142 @@
/*
* $Id: patricia.h 23020 2006-09-01 18:20:19Z androsyn $
* Dave Plonka <plonka@doit.wisc.edu>
*
* This product includes software developed by the University of Michigan,
* Merit Network, Inc., and their contributors.
*
* This file had been called "radix.h" in the MRT sources.
*
* I renamed it to "patricia.h" since it's not an implementation of a general
* radix trie. Also, pulled in various requirements from "mrt.h" and added
* some other things it could be used as a standalone API.
*/
#ifndef _RB_PATRICIA_H
#define _RB_PATRICIA_H
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE !(FALSE)
#endif
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif
/* typedef unsigned int u_int; */
typedef void (*void_fn_t) ();
#define rb_prefix_touchar(prefix) ((unsigned char *)&(prefix)->add.sin)
#define MAXLINE 1024
#define BIT_TEST(f, b) ((f) & (b))
typedef struct _rb_prefix_t
{
unsigned short family; /* AF_INET | AF_INET6 */
unsigned short bitlen; /* same as mask? */
int ref_count; /* reference count */
union
{
struct in_addr sin;
#ifdef RB_IPV6
struct in6_addr sin6;
#endif /* RB_IPV6 */
}
add;
}
rb_prefix_t;
typedef struct _rb_patricia_node_t
{
unsigned int bit; /* flag if this node used */
rb_prefix_t *prefix; /* who we are in patricia tree */
struct _rb_patricia_node_t *l, *r; /* left and right children */
struct _rb_patricia_node_t *parent; /* may be used */
void *data;
}
rb_patricia_node_t;
typedef struct _rb_patricia_tree_t
{
rb_patricia_node_t *head;
unsigned int maxbits; /* for IP, 32 bit addresses */
int num_active_node; /* for debug purpose */
}
rb_patricia_tree_t;
rb_patricia_node_t *rb_match_ip(rb_patricia_tree_t * tree, struct sockaddr *ip);
rb_patricia_node_t *rb_match_ip_exact(rb_patricia_tree_t * tree, struct sockaddr *ip, unsigned int len);
rb_patricia_node_t *rb_match_string(rb_patricia_tree_t * tree, const char *string);
rb_patricia_node_t *rb_match_exact_string(rb_patricia_tree_t * tree, const char *string);
rb_patricia_node_t *rb_patricia_search_exact(rb_patricia_tree_t * patricia, rb_prefix_t * prefix);
rb_patricia_node_t *rb_patricia_search_best(rb_patricia_tree_t * patricia, rb_prefix_t * prefix);
rb_patricia_node_t *rb_patricia_search_best2(rb_patricia_tree_t * patricia,
rb_prefix_t * prefix, int inclusive);
rb_patricia_node_t *rb_patricia_lookup(rb_patricia_tree_t * patricia, rb_prefix_t * prefix);
void rb_patricia_remove(rb_patricia_tree_t * patricia, rb_patricia_node_t * node);
rb_patricia_tree_t *rb_new_patricia(int maxbits);
void rb_clear_patricia(rb_patricia_tree_t * patricia, void_fn_t func);
void rb_destroy_patricia(rb_patricia_tree_t * patricia, void_fn_t func);
void rb_patricia_process(rb_patricia_tree_t * patricia, void_fn_t func);
void rb_init_patricia(void);
#if 0
rb_prefix_t *ascii2prefix(int family, char *string);
#endif
rb_patricia_node_t *make_and_lookup(rb_patricia_tree_t * tree, const char *string);
rb_patricia_node_t *make_and_lookup_ip(rb_patricia_tree_t * tree, struct sockaddr *, int bitlen);
#define RB_PATRICIA_MAXBITS 128
#define RB_PATRICIA_NBIT(x) (0x80 >> ((x) & 0x7f))
#define RB_PATRICIA_NBYTE(x) ((x) >> 3)
#define RB_PATRICIA_DATA_GET(node, type) (type *)((node)->data)
#define RB_PATRICIA_DATA_SET(node, value) ((node)->data = (void *)(value))
#define RB_PATRICIA_WALK(Xhead, Xnode) \
do { \
rb_patricia_node_t *Xstack[RB_PATRICIA_MAXBITS+1]; \
rb_patricia_node_t **Xsp = Xstack; \
rb_patricia_node_t *Xrn = (Xhead); \
while ((Xnode = Xrn)) { \
if (Xnode->prefix)
#define RB_PATRICIA_WALK_ALL(Xhead, Xnode) \
do { \
rb_patricia_node_t *Xstack[RB_PATRICIA_MAXBITS+1]; \
rb_patricia_node_t **Xsp = Xstack; \
rb_patricia_node_t *Xrn = (Xhead); \
while ((Xnode = Xrn)) { \
if (1)
#define RB_PATRICIA_WALK_BREAK { \
if (Xsp != Xstack) { \
Xrn = *(--Xsp); \
} else { \
Xrn = (rb_patricia_node_t *) 0; \
} \
continue; }
#define RB_PATRICIA_WALK_END \
if (Xrn->l) { \
if (Xrn->r) { \
*Xsp++ = Xrn->r; \
} \
Xrn = Xrn->l; \
} else if (Xrn->r) { \
Xrn = Xrn->r; \
} else if (Xsp != Xstack) { \
Xrn = *(--Xsp); \
} else { \
Xrn = (rb_patricia_node_t *) 0; \
} \
} \
} while (0)
#endif /* _RB_PATRICIA_H */

View file

@ -0,0 +1,46 @@
/*
* ircd-ratbox: A slightly useful ircd.
* rawbuf.h: A header for rawbuf.c
*
* Copyright (C) 2007 Aaron Sethman <androsyn@ratbox.org>
* Copyright (C) 2007 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id$
*/
#ifndef RB_LIB_H
# error "Do not use rawbuf.h directly"
#endif
#ifndef INCLUDED_RAWBUF_H__
#define INCLUDED_RAWBUF_H__
typedef struct _rawbuf rawbuf_t;
typedef struct _rawbuf_head rawbuf_head_t;
void rb_init_rawbuffers(int heapsize);
void rb_free_rawbuffer(rawbuf_head_t *);
rawbuf_head_t *rb_new_rawbuffer(void);
int rb_rawbuf_get(rawbuf_head_t *, void *data, int len);
void rb_rawbuf_append(rawbuf_head_t *, void *data, int len);
int rb_rawbuf_flush(rawbuf_head_t *, rb_fde_t *F);
int rb_rawbuf_length(rawbuf_head_t *rb);
#endif

View file

@ -0,0 +1,60 @@
/*
* ircd-ratbox: A slightly useful ircd.
* sprintf_rb_.h: The irc sprintf header.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: rb_snprintf.h 24324 2007-08-31 22:05:45Z androsyn $
*/
#ifndef RB_LIB_H
# error "Do not use snprintf.h directly"
#endif
#ifndef SPRINTF_IRC
#define SPRINTF_IRC
/*=============================================================================
* Proto types
*/
/*
* rb_sprintf - optimized sprintf
*/
#ifdef __GNUC__
int rb_sprintf(char *str, const char *fmt, ...) __attribute((format(printf, 2, 3)));
int rb_snprintf(char *str, const size_t size, const char *, ...) __attribute__ ((format(printf, 3, 4)));
int rb_sprintf_append(char *str, const char *format, ...) __attribute((format(printf, 2, 3)));
int rb_snprintf_append(char *str, size_t len, const char *format, ...) __attribute__ ((format(printf, 3, 4)));
#else
int rb_sprintf(char *str, const char *format, ...);
int rb_snprintf(char *str, const size_t size, const char *, ...);
int rb_sprintf_append(char *str, const char *format, ...);
int rb_snprintf_append(char *str, const size_t size, const char *, ...);
#endif
int rb_vsnprintf(char *str, const size_t size, const char *fmt, va_list args);
int rb_vsprintf(char *str, const char *fmt, va_list args);
int rb_vsnprintf_append(char *str, const size_t size, const char *fmt, va_list args);
int rb_vsprintf_append(char *str, const char *fmt, va_list args);
#endif /* SPRINTF_IRC */

View file

@ -0,0 +1,345 @@
/*
* ircd-ratbox: A slightly useful ircd.
* tools.h: Header for the various tool functions.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: rb_tools.h 25042 2008-01-23 16:14:08Z androsyn $
*/
#ifndef RB_LIB_H
# error "Do not use tools.h directly"
#endif
#ifndef __TOOLS_H__
#define __TOOLS_H__
size_t rb_strlcpy(char *dst, const char *src, size_t siz);
size_t rb_strlcat(char *dst, const char *src, size_t siz);
size_t rb_strnlen(const char *s, size_t count);
int rb_string_to_array(char *string, char **parv, int maxpara);
/*
* double-linked-list stuff
*/
typedef struct _rb_dlink_node rb_dlink_node;
typedef struct _rb_dlink_list rb_dlink_list;
struct _rb_dlink_node
{
void *data;
rb_dlink_node *prev;
rb_dlink_node *next;
};
struct _rb_dlink_list
{
rb_dlink_node *head;
rb_dlink_node *tail;
unsigned long length;
};
rb_dlink_node *rb_make_rb_dlink_node(void);
void rb_free_rb_dlink_node(rb_dlink_node * lp);
void rb_init_rb_dlink_nodes(size_t dh_size);
/* This 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 RB_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 RB_DLINK_FOREACH_SAFE(pos, n, head) for (pos = (head), n = pos ? pos->next : NULL; pos != NULL; pos = n, n = pos ? pos->next : NULL)
#define RB_DLINK_FOREACH_PREV(pos, head) for (pos = (head); pos != NULL; pos = pos->prev)
/* Returns the list length */
#define rb_dlink_list_length(list) (list)->length
#define rb_dlinkAddAlloc(data, list) rb_dlinkAdd(data, rb_make_rb_dlink_node(), list)
#define rb_dlinkAddTailAlloc(data, list) rb_dlinkAddTail(data, rb_make_rb_dlink_node(), list)
#define rb_dlinkDestroy(node, list) do { rb_dlinkDelete(node, list); rb_free_rb_dlink_node(node); } while(0)
/*
* dlink_ routines are stolen from squid, except for rb_dlinkAddBefore,
* which is mine.
* -- adrian
*/
static inline void
rb_dlinkMoveNode(rb_dlink_node * m, rb_dlink_list * oldlist, rb_dlink_list * newlist)
{
/* Assumption: If m->next == NULL, then list->tail == m
* and: If m->prev == NULL, then list->head == m
*/
assert(m != NULL);
assert(oldlist != NULL);
assert(newlist != NULL);
if(m->next)
m->next->prev = m->prev;
else
oldlist->tail = m->prev;
if(m->prev)
m->prev->next = m->next;
else
oldlist->head = m->next;
m->prev = NULL;
m->next = newlist->head;
if(newlist->head != NULL)
newlist->head->prev = m;
else if(newlist->tail == NULL)
newlist->tail = m;
newlist->head = m;
oldlist->length--;
newlist->length++;
}
static inline void
rb_dlinkAdd(void *data, rb_dlink_node * m, rb_dlink_list * list)
{
assert(data != NULL);
assert(m != NULL);
assert(list != NULL);
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++;
}
static inline void
rb_dlinkAddBefore(rb_dlink_node * b, void *data, rb_dlink_node * m, rb_dlink_list * list)
{
assert(b != NULL);
assert(data != NULL);
assert(m != NULL);
assert(list != NULL);
/* Shortcut - if its the first one, call rb_dlinkAdd only */
if(b == list->head)
{
rb_dlinkAdd(data, m, list);
}
else
{
m->data = data;
b->prev->next = m;
m->prev = b->prev;
b->prev = m;
m->next = b;
list->length++;
}
}
static inline void
rb_dlinkMoveTail(rb_dlink_node *m, rb_dlink_list *list)
{
if(list->tail == m)
return;
/* From here assume that m->next != NULL as that can only
* be at the tail and assume that the node is on the list
*/
m->next->prev = m->prev;
if(m->prev != NULL)
m->prev->next = m->next;
else
list->head = m->next;
list->tail->next = m;
m->prev = list->tail;
m->next = NULL;
list->tail = m;
}
static inline void
rb_dlinkAddTail(void *data, rb_dlink_node * m, rb_dlink_list * list)
{
assert(m != NULL);
assert(list != NULL);
assert(data != NULL);
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. */
static inline void
rb_dlinkDelete(rb_dlink_node * m, rb_dlink_list * list)
{
assert(m != NULL);
assert(list != NULL);
/* 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
list->tail = m->prev;
if(m->prev)
m->prev->next = m->next;
else
list->head = m->next;
m->next = m->prev = NULL;
list->length--;
}
static inline rb_dlink_node *
rb_dlinkFindDelete(void *data, rb_dlink_list *list)
{
rb_dlink_node *m;
assert(list != NULL);
assert(data != NULL);
RB_DLINK_FOREACH(m, list->head)
{
if(m->data != data)
continue;
if(m->next)
m->next->prev = m->prev;
else
list->tail = m->prev;
if(m->prev)
m->prev->next = m->next;
else
list->head = m->next;
m->next = m->prev = NULL;
list->length--;
return m;
}
return NULL;
}
static inline int
rb_dlinkFindDestroy(void *data, rb_dlink_list *list)
{
void *ptr;
assert(list != NULL);
assert(data != NULL);
ptr = rb_dlinkFindDelete(data, list);
if(ptr != NULL)
{
rb_free_rb_dlink_node(ptr);
return 1;
}
return 0;
}
/*
* rb_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.
*/
static inline rb_dlink_node *
rb_dlinkFind(void *data, rb_dlink_list *list)
{
rb_dlink_node *ptr;
assert(list != NULL);
assert(data != NULL);
RB_DLINK_FOREACH(ptr, list->head)
{
if(ptr->data == data)
return (ptr);
}
return (NULL);
}
static inline void
rb_dlinkMoveList(rb_dlink_list * from, rb_dlink_list * to)
{
assert(from != NULL);
assert(to != NULL);
/* There are three cases */
/* case one, nothing in from list */
if(from->head == NULL)
return;
/* case two, nothing in to list */
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;
to->head->prev = from->tail;
to->head = from->head;
from->head = from->tail = NULL;
to->length += from->length;
from->length = 0;
}
#endif /* __TOOLS_H__ */

325
libratbox/install-sh Executable file
View file

@ -0,0 +1,325 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2004-04-01.17
# 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. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=
transform_arg=
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd=
stripcmd=
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=
dst=
dir_arg=
usage="Usage: $0 [OPTION]... SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 -d DIRECTORIES...
In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default.
In the second, create the directory path DIR.
Options:
-b=TRANSFORMBASENAME
-c copy source (using $cpprog) instead of moving (using $mvprog).
-d create directories instead of installing files.
-g GROUP $chgrp installed files to GROUP.
-m MODE $chmod installed files to MODE.
-o USER $chown installed files to USER.
-s strip installed files (using $stripprog).
-t=TRANSFORM
--help display this help and exit.
--version display version info and exit.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
"
while test -n "$1"; do
case $1 in
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
-c) instcmd=$cpprog
shift
continue;;
-d) dir_arg=true
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
--help) echo "$usage"; exit 0;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
--version) echo "$0 $scriptversion"; exit 0;;
*) # When -d is used, all remaining arguments are directories to create.
test -n "$dir_arg" && break
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
break;;
esac
done
if test -z "$1"; 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
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src ;;
esac
if test -n "$dir_arg"; then
dst=$src
src=
if test -d "$dst"; then
instcmd=:
chmodcmd=
else
instcmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dstarg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dstarg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
dst=$dst/`basename "$src"`
fi
fi
# This sed command emulates the dirname command.
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# Skip lots of stat calls in the usual case.
if test ! -d "$dstdir"; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS=$oIFS
pathcomp=
while test $# -ne 0 ; do
pathcomp=$pathcomp$1
shift
if test ! -d "$pathcomp"; then
$mkdirprog "$pathcomp" || lasterr=$?
# mkdir can fail with a `File exist' error in case several
# install-sh are creating the directory concurrently. This
# is OK.
test ! -d "$pathcomp" && { (exit ${lasterr-1}); exit; }
fi
pathcomp=$pathcomp/
done
fi
if test -n "$dir_arg"; then
$doit $instcmd "$dst" \
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
else
# If we're going to rename the final executable, determine the name now.
if test -z "$transformarg"; then
dstfile=`basename "$dst"`
else
dstfile=`basename "$dst" $transformbasename \
| sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename.
test -z "$dstfile" && dstfile=`basename "$dst"`
# 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 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
# Move or copy the file name to the temp name
$doit $instcmd "$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 $instcmd $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 "$dsttmp"; } &&
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 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.
{
if test -f "$dstdir/$dstfile"; then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|| {
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
}
}
fi || { (exit 1); exit; }
done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit
}
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

6938
libratbox/ltmain.sh Normal file

File diff suppressed because it is too large Load diff

360
libratbox/missing Executable file
View file

@ -0,0 +1,360 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2003-09-02.23
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
# 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
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
-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'
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
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Send bug reports to <bug-automake@gnu.org>."
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
aclocal*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
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)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
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)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
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*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
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)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
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 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
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 [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -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 [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
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 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
# We have makeinfo, but it failed.
exit 1
fi
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."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;
tar)
shift
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
fi
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
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-end: "$"
# End:

36
libratbox/src/Makefile.am Normal file
View file

@ -0,0 +1,36 @@
# $Id: Makefile.am 24820 2008-01-02 19:47:32Z androsyn $
AUTOMAKE_OPTIONS = foreign
INCLUDES = -I. -I../include @SSL_INCLUDES@
libratbox_la_SOURCES = \
unix.c \
win32.c \
crypt.c \
balloc.c \
commio.c \
openssl.c \
nossl.c \
event.c \
ratbox_lib.c \
rb_memory.c \
linebuf.c \
snprintf.c \
tools.c \
helper.c \
devpoll.c \
epoll.c \
poll.c \
ports.c \
sigio.c \
select.c \
kqueue.c \
rawbuf.c \
patricia.c
libratbox_la_LDFLAGS = -avoid-version -no-undefined -export-symbols export-syms.txt
libratbox_la_LIBADD = @CRYPT_LIB@ @SSL_LIBS@
lib_LTLIBRARIES = libratbox.la

537
libratbox/src/Makefile.in Normal file
View file

@ -0,0 +1,537 @@
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006 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@
# $Id: Makefile.am 24808 2008-01-02 08:17:05Z androsyn $
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@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 = src
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)/include/libratbox_config.h
CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libratbox_la_DEPENDENCIES =
am_libratbox_la_OBJECTS = unix.lo win32.lo crypt.lo balloc.lo \
commio.lo openssl.lo nossl.lo event.lo ratbox_lib.lo \
rb_memory.lo linebuf.lo snprintf.lo tools.lo helper.lo \
devpoll.lo epoll.lo poll.lo ports.lo sigio.lo select.lo \
kqueue.lo rawbuf.lo patricia.lo
libratbox_la_OBJECTS = $(am_libratbox_la_OBJECTS)
libratbox_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libratbox_la_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I. -I$(top_builddir)/include@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
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 = $(libratbox_la_SOURCES)
DIST_SOURCES = $(libratbox_la_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CP = @CP@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CRYPT_LIB = @CRYPT_LIB@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN = @LN@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
MV = @MV@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PICFLAGS = @PICFLAGS@
RANLIB = @RANLIB@
RB_PREFIX = @RB_PREFIX@
RM = @RM@
SED = @SED@
SEDOBJ = @SEDOBJ@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SSL_INCLUDES = @SSL_INCLUDES@
SSL_LIBS = @SSL_LIBS@
STRIP = @STRIP@
TOUCH = @TOUCH@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
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@
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@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign
INCLUDES = -I. -I../include @SSL_INCLUDES@
libratbox_la_SOURCES = \
unix.c \
win32.c \
crypt.c \
balloc.c \
commio.c \
openssl.c \
nossl.c \
event.c \
ratbox_lib.c \
rb_memory.c \
linebuf.c \
snprintf.c \
tools.c \
helper.c \
devpoll.c \
epoll.c \
poll.c \
ports.c \
sigio.c \
select.c \
kqueue.c \
rawbuf.c \
patricia.c
libratbox_la_LDFLAGS = -avoid-version -no-undefined -export-symbols export-syms.txt
libratbox_la_LIBADD = @CRYPT_LIB@ @SSL_LIBS@
lib_LTLIBRARIES = libratbox.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 \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
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
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
$(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libratbox.la: $(libratbox_la_OBJECTS) $(libratbox_la_DEPENDENCIES)
$(libratbox_la_LINK) -rpath $(libdir) $(libratbox_la_OBJECTS) $(libratbox_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/balloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devpoll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epoll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kqueue.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linebuf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nossl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/patricia.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ports.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ratbox_lib.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rawbuf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb_memory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/select.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snprintf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tools.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/win32.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ mv -f $(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@ mv -f $(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@ mv -f $(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; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
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; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
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; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
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 $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$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)$(libdir)"; 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:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-libLTLIBRARIES 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
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: 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-libLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool 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-libLTLIBRARIES 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-libLTLIBRARIES
# 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:

574
libratbox/src/balloc.c Normal file
View file

@ -0,0 +1,574 @@
/*
* ircd-ratbox: A slightly useful ircd.
* balloc.c: A block allocator.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2006 ircd-ratbox development team
*
* Below are the orignal headers from the old blalloc.c
*
* File: blalloc.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: balloc.c 25048 2008-01-23 18:34:02Z androsyn $
*/
/*
* 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.
* 2. mmap() via the /dev/zero trick.
* 3. HeapCreate/HeapAlloc (on win32)
* 4. malloc()
*
* 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 <libratbox_config.h>
#include <ratbox_lib.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
#endif
/* status information for an allocated block in heap */
struct rb_heap_block
{
size_t alloc_size;
rb_dlink_node node;
unsigned long free_count;
void *elems; /* Points to allocated memory */
};
typedef struct rb_heap_block rb_heap_block;
struct rb_heap_memblock
{
rb_heap_block *block;
union {
rb_dlink_node node;
char data[1]; /* stub pointer..this is ugly */
} ndata;
};
typedef struct rb_heap_memblock rb_heap_memblock;
/* information for the root node of the heap */
struct rb_bh
{
rb_dlink_node hlist;
size_t elemSize; /* Size of each element to be stored */
unsigned long elemsPerBlock; /* Number of elements per block */
rb_dlink_list block_list;
rb_dlink_list free_list;
char *desc;
};
#ifndef NOBALLOC
static int newblock(rb_bh * bh);
static void rb_bh_gc_event(void *unused);
#endif /* !NOBALLOC */
static rb_dlink_list *heap_lists;
#if defined(WIN32)
static HANDLE block_heap;
#endif
#define rb_bh_fail(x) _rb_bh_fail(x, __FILE__, __LINE__)
static void
_rb_bh_fail(const char *reason, const char *file, int line)
{
rb_lib_log("rb_heap_blockheap failure: %s (%s:%d)", reason, file, line);
abort();
}
#ifndef NOBALLOC
/*
* static inline void free_block(void *ptr, size_t size)
*
* Inputs: The block and its size
* Output: None
* Side Effects: Returns memory for the block back to the OS
*/
static inline void
free_block(void *ptr, size_t size)
{
#ifdef HAVE_MMAP
munmap(ptr, size);
#else
#ifdef WIN32
HeapFree(block_heap, 0, ptr);
#else
free(ptr);
#endif
#endif
}
#endif /* !NOBALLOC */
/*
* void rb_init_bh(void)
*
* Inputs: None
* Outputs: None
* Side Effects: Initializes the block heap
*/
void
rb_init_bh(void)
{
heap_lists = rb_malloc(sizeof(rb_dlink_list));
#ifndef NOBALLOC
#ifdef WIN32
block_heap = HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
#endif
rb_event_addish("rb_bh_gc_event", rb_bh_gc_event, NULL, 300);
#endif /* !NOBALLOC */
}
#ifndef NOBALLOC
/*
* static inline void *get_block(size_t size)
*
* Input: Size of block to allocate
* Output: Pointer to new block
* Side Effects: None
*/
static inline void *
get_block(size_t size)
{
void *ptr;
#ifdef HAVE_MMAP
#ifdef MAP_ANON
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
#else
int zero_fd;
zero_fd = open("/dev/zero", O_RDWR);
if(zero_fd < 0)
rb_bh_fail("Failed opening /dev/zero");
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, zero_fd, 0);
close(zero_fd);
#endif /* MAP_ANON */
if(ptr == MAP_FAILED)
ptr = NULL;
#else
#ifdef WIN32
ptr = HeapAlloc(block_heap, 0, size);
#else
ptr = malloc(size);
#endif
#endif
return(ptr);
}
static void
rb_bh_gc_event(void *unused)
{
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, heap_lists->head)
{
rb_bh_gc(ptr->data);
}
}
/* ************************************************************************ */
/* FUNCTION DOCUMENTATION: */
/* newblock */
/* Description: */
/* Allocates a new block for addition to a blockheap */
/* Parameters: */
/* bh (IN): Pointer to parent blockheap. */
/* Returns: */
/* 0 if successful, 1 if not */
/* ************************************************************************ */
static int
newblock(rb_bh * bh)
{
rb_heap_block *b;
unsigned long i;
rb_uintptr_t offset;
/* Setup the initial data structure. */
b = rb_malloc(sizeof(rb_heap_block));
b->alloc_size = bh->elemsPerBlock * (bh->elemSize + sizeof(rb_heap_block *));
b->elems = get_block(b->alloc_size);
if(unlikely(b->elems == NULL))
{
return (1);
}
offset = (rb_uintptr_t)b->elems;
/* Setup our blocks now */
for (i = 0; i < bh->elemsPerBlock; i++, offset += (bh->elemSize + sizeof(rb_heap_block *)))
{
rb_heap_memblock *memblock = (rb_heap_memblock *)offset;
memblock->block = b;
rb_dlinkAdd(memblock, &memblock->ndata.node, &bh->free_list);
}
rb_dlinkAdd(b, &b->node, &bh->block_list);
b->free_count = bh->elemsPerBlock;
return (0);
}
#endif /* !NOBALLOC */
/* ************************************************************************ */
/* FUNCTION DOCUMENTATION: */
/* rb_bh_create */
/* Description: */
/* 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. */
/* Parameters: */
/* elemsize (IN): Size of the basic element to be stored */
/* elemsperblock (IN): 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. */
/* Returns: */
/* Pointer to new rb_bh, or NULL if unsuccessful */
/* ************************************************************************ */
rb_bh *
rb_bh_create(size_t elemsize, int elemsperblock, const char *desc)
{
rb_bh *bh;
lrb_assert(elemsize > 0 && elemsperblock > 0);
lrb_assert(elemsize >= sizeof(rb_dlink_node));
/* Catch idiotic requests up front */
if((elemsize <= 0) || (elemsperblock <= 0))
{
rb_bh_fail("Attempting to rb_bh_create idiotic sizes");
}
if(elemsize < sizeof(rb_dlink_node))
rb_bh_fail("Attempt to rb_bh_create smaller than sizeof(rb_dlink_node)");
/* Allocate our new rb_bh */
bh = rb_malloc(sizeof(rb_bh));
#ifndef NOBALLOC
if((elemsize % sizeof(void *)) != 0)
{
/* Pad to even pointer boundary */
elemsize += sizeof(void *);
elemsize &= ~(sizeof(void *) - 1);
}
#endif /* !NOBALLOC */
bh->elemSize = elemsize;
bh->elemsPerBlock = elemsperblock;
if(desc != NULL)
bh->desc = rb_strdup(desc);
#ifndef NOBALLOC
/* Be sure our malloc was successful */
if(newblock(bh))
{
if(bh != NULL)
free(bh);
rb_lib_log("newblock() failed");
rb_outofmemory(); /* die.. out of memory */
}
#endif /* !NOBALLOC */
if(bh == NULL)
{
rb_bh_fail("bh == NULL when it shouldn't be");
}
rb_dlinkAdd(bh, &bh->hlist, heap_lists);
return (bh);
}
/* ************************************************************************ */
/* FUNCTION DOCUMENTATION: */
/* rb_bh_alloc */
/* Description: */
/* Returns a pointer to a struct within our rb_bh that's free for */
/* the taking. */
/* Parameters: */
/* bh (IN): Pointer to the Blockheap. */
/* Returns: */
/* Pointer to a structure (void *), or NULL if unsuccessful. */
/* ************************************************************************ */
void *
rb_bh_alloc(rb_bh * bh)
{
#ifndef NOBALLOC
rb_dlink_node *new_node;
rb_heap_memblock *memblock;
#endif
lrb_assert(bh != NULL);
if(unlikely(bh == NULL))
{
rb_bh_fail("Cannot allocate if bh == NULL");
}
#ifdef NOBALLOC
return(rb_malloc(bh->elemSize));
#else
if(bh->free_list.head == NULL)
{
/* Allocate new block and assign */
/* newblock returns 1 if unsuccessful, 0 if not */
if(unlikely(newblock(bh)))
{
rb_lib_log("newblock() failed");
rb_outofmemory(); /* Well that didn't work either...bail */
}
if(bh->free_list.head == NULL)
{
rb_lib_log("out of memory after newblock()...");
rb_outofmemory();
}
}
new_node = bh->free_list.head;
memblock = new_node->data;
rb_dlinkDelete(new_node, &bh->free_list);
memblock->block->free_count--;
memset((void *)memblock->ndata.data, 0, bh->elemSize);
return((void *)memblock->ndata.data);
#endif
}
/* ************************************************************************ */
/* FUNCTION DOCUMENTATION: */
/* rb_bh_free */
/* Description: */
/* Returns an element to the free pool, does not free() */
/* Parameters: */
/* bh (IN): Pointer to rb_bh containing element */
/* ptr (in): Pointer to element to be "freed" */
/* Returns: */
/* 0 if successful, 1 if element not contained within rb_bh. */
/* ************************************************************************ */
int
rb_bh_free(rb_bh * bh, void *ptr)
{
#ifndef NOBALLOC
rb_heap_memblock *memblock;
#endif
lrb_assert(bh != NULL);
lrb_assert(ptr != NULL);
if(unlikely(bh == NULL))
{
rb_lib_log("balloc.c:rb_bhFree() bh == NULL");
return (1);
}
if(unlikely(ptr == NULL))
{
rb_lib_log("balloc.rb_bhFree() ptr == NULL");
return (1);
}
#ifdef NOBALLOC
rb_free(ptr);
#else
memblock = (rb_heap_memblock *) ((uintptr_t)ptr - sizeof(rb_heap_block *));
/* XXX */
if(unlikely(!((uintptr_t)ptr >= (uintptr_t)memblock->block->elems && (uintptr_t)ptr < (uintptr_t)memblock->block->elems + (uintptr_t)memblock->block->alloc_size)))
{
rb_bh_fail("rb_bh_free() bogus pointer");
}
memblock->block->free_count++;
rb_dlinkAdd(memblock, &memblock->ndata.node, &bh->free_list);
#endif /* !NOBALLOC */
return (0);
}
/* ************************************************************************ */
/* FUNCTION DOCUMENTATION: */
/* rb_bhDestroy */
/* Description: */
/* Completely free()s a rb_bh. Use for cleanup. */
/* Parameters: */
/* bh (IN): Pointer to the rb_bh to be destroyed. */
/* Returns: */
/* 0 if successful, 1 if bh == NULL */
/* ************************************************************************ */
int
rb_bh_destroy(rb_bh * bh)
{
#ifndef NOBALLOC
rb_dlink_node *ptr, *next;
rb_heap_block *b;
#endif
if(bh == NULL)
return (1);
#ifndef NOBALLOC
RB_DLINK_FOREACH_SAFE(ptr, next, bh->block_list.head)
{
b = ptr->data;
free_block(b->elems, b->alloc_size);
rb_free(b);
}
#endif /* !NOBALLOC */
rb_dlinkDelete(&bh->hlist, heap_lists);
rb_free(bh->desc);
rb_free(bh);
return (0);
}
void
rb_bh_usage(rb_bh * bh, size_t * bused, size_t * bfree, size_t * bmemusage, const char **desc)
{
size_t used, freem, memusage;
if(bh == NULL)
{
return;
}
freem = rb_dlink_list_length(&bh->free_list);
used = (rb_dlink_list_length(&bh->block_list) * bh->elemsPerBlock) - freem;
memusage = used * (bh->elemSize + sizeof(void *));
if(bused != NULL)
*bused = used;
if(bfree != NULL)
*bfree = freem;
if(bmemusage != NULL)
*bmemusage = memusage;
if(desc != NULL)
*desc = bh->desc;
}
void rb_bh_usage_all(rb_bh_usage_cb *cb, void *data)
{
rb_dlink_node *ptr;
rb_bh *bh;
size_t used, freem, memusage, heapalloc;
static const char *unnamed = "(unnamed_heap)";
const char *desc = unnamed;
if(cb == NULL)
return;
RB_DLINK_FOREACH(ptr, heap_lists->head)
{
bh = (rb_bh *)ptr->data;
freem = rb_dlink_list_length(&bh->free_list);
used = (rb_dlink_list_length(&bh->block_list) * bh->elemsPerBlock) - freem;
memusage = used * (bh->elemSize + sizeof(void *));
heapalloc = (freem + used) * (bh->elemSize + sizeof(void *));
if(bh->desc != NULL)
desc = bh->desc;
cb(used, freem, memusage, heapalloc, desc, data);
}
return;
}
void
rb_bh_total_usage(size_t *total_alloc, size_t *total_used)
{
rb_dlink_node *ptr;
size_t total_memory = 0, used_memory = 0, used, freem;
rb_bh *bh;
RB_DLINK_FOREACH(ptr, heap_lists->head)
{
bh = (rb_bh *)ptr->data;
freem = rb_dlink_list_length(&bh->free_list);
used = (rb_dlink_list_length(&bh->block_list) * bh->elemsPerBlock) - freem;
used_memory += used * (bh->elemSize + sizeof(void *));
total_memory += (freem + used) * (bh->elemSize + sizeof(void *));
}
if(total_alloc != NULL)
*total_alloc = total_memory;
if(total_used != NULL)
*total_used = used_memory;
}
#ifndef NOBALLOC
int
rb_bh_gc(rb_bh * bh)
{
rb_heap_block *b;
rb_dlink_node *ptr, *next;
unsigned long i;
uintptr_t offset;
if(bh == NULL)
{
/* somebody is smoking some craq..(probably lee, but don't tell him that) */
return (1);
}
if((rb_dlink_list_length(&bh->free_list) < bh->elemsPerBlock) || rb_dlink_list_length(&bh->block_list) == 1)
{
/* There couldn't possibly be an entire free block. Return. */
return (0);
}
RB_DLINK_FOREACH_SAFE(ptr, next, bh->block_list.head)
{
b = ptr->data;
if(rb_dlink_list_length(&bh->block_list) == 1)
return (0);
if(b->free_count == bh->elemsPerBlock)
{
/* i'm seriously going to hell for this.. */
offset = (uintptr_t)b->elems;
for (i = 0; i < bh->elemsPerBlock; i++, offset += ((uintptr_t)bh->elemSize + sizeof(rb_heap_memblock *)))
{
rb_heap_memblock *memblock = (rb_heap_memblock *)offset;
rb_dlinkDelete(&memblock->ndata.node, &bh->free_list);
}
rb_dlinkDelete(&b->node, &bh->block_list);
free_block(b->elems, b->alloc_size);
rb_free(b);
}
}
return (0);
}
#endif /* !NOBALLOC */

2107
libratbox/src/commio.c Normal file

File diff suppressed because it is too large Load diff

1443
libratbox/src/crypt.c Normal file

File diff suppressed because it is too large Load diff

304
libratbox/src/devpoll.c Normal file
View file

@ -0,0 +1,304 @@
/*
* ircd-ratbox: A slightly useful ircd.
* s_bsd_devpoll.c: /dev/poll compatible network routines.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: devpoll.c 25038 2008-01-23 16:03:08Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
#include <fcntl.h>
#if defined(HAVE_DEVPOLL) && (HAVE_DEVPOLL_H)
#include <sys/devpoll.h>
static void devpoll_update_events(int, short, PF *);
static int dpfd;
static int maxfd;
static short *fdmask;
static void devpoll_update_events(int, short, PF *);
static void devpoll_write_update(int, int);
int
rb_setup_fd_devpoll(rb_fde_t *F)
{
return 0;
}
/*
* 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 pollfds[1]; /* Just to be careful */
int retval;
/* Build the pollfd entry */
pollfds[0].revents = 0;
pollfds[0].fd = fd;
pollfds[0].events = events;
/* Write the thing to our poll fd */
retval = write(dpfd, &pollfds[0], sizeof(struct pollfd));
if(retval != sizeof(struct pollfd))
rb_lib_log("devpoll_write_update: dpfd write failed %d: %s", errno, strerror(errno));
/* Done! */
}
static void
devpoll_update_events(int fd, short filter, PF * handler)
{
int update_required = 0;
int cur_mask = fdmask[fd];
PF *cur_handler;
fdmask[fd] = 0;
switch (filter)
{
case RB_SELECT_READ:
cur_handler = F->read_handler;
if(handler)
fdmask[fd] |= POLLRDNORM;
else
fdmask[fd] &= ~POLLRDNORM;
if(F->write_handler)
fdmask[fd] |= POLLWRNORM;
break;
case RB_SELECT_WRITE:
cur_handler = F->write_handler;
if(handler)
fdmask[fd] |= POLLWRNORM;
else
fdmask[fd] &= ~POLLWRNORM;
if(F->read_handler)
fdmask[fd] |= POLLRDNORM;
break;
default:
return;
break;
}
if(cur_handler == NULL && handler != NULL)
update_required++;
else if(cur_handler != NULL && handler == NULL)
update_required++;
if(cur_mask != fdmask[fd])
update_required++;
if(update_required)
{
/*
* Ok, we can call devpoll_write_update() here now to re-build the
* fd struct. If we end up with nothing on this fd, it won't write
* anything.
*/
if(fdmask[fd])
{
devpoll_write_update(fd, POLLREMOVE);
devpoll_write_update(fd, fdmask[fd]);
}
else
devpoll_write_update(fd, POLLREMOVE);
}
}
/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
/* Public functions */
/*
* rb_init_netio
*
* This is a needed exported function which will be called to initialise
* the network loop code.
*/
int
rb_init_netio_devpoll(void)
{
dpfd = open("/dev/poll", O_RDWR);
if(dpfd < 0)
{
return errno;
}
maxfd = getdtablesize() - 2; /* This makes more sense than HARD_FDLIMIT */
fdmask = rb_malloc(sizeof(fdmask) * maxfd + 1);
rb_open(dpfd, RB_FD_UNKNOWN, "/dev/poll file descriptor");
}
/*
* rb_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
rb_setselect_devpoll(rb_fde_t *F, unsigned int type, PF * handler,
void *client_data)
{
lrb_assert(IsFDOpen(F));
if(type & RB_SELECT_READ)
{
devpoll_update_events(fd, RB_SELECT_READ, handler);
F->read_handler = handler;
F->read_data = client_data;
}
if(type & RB_SELECT_WRITE)
{
devpoll_update_events(fd, RB_SELECT_WRITE, handler);
F->write_handler = handler;
F->write_data = client_data;
}
}
/*
* Check all connections for new connections and input data that is to be
* processed. Also check for connections with data queued and whether we can
* write it out.
*/
/*
* rb_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
* rb_setselect and fd_table[] and calls callbacks for IO ready
* events.
*/
int
rb_select_devpoll(long delay)
{
int num, i;
struct pollfd pollfds[maxfd];
struct dvpoll dopoll;
do
{
for (;;)
{
dopoll.dp_timeout = delay;
dopoll.dp_nfds = maxfd;
dopoll.dp_fds = &pollfds[0];
num = ioctl(dpfd, DP_POLL, &dopoll);
if(num >= 0)
break;
if(rb_ignore_errno(errno))
break;
rb_set_time();
return RB_ERROR;
}
rb_set_time();
if(num == 0)
continue;
for (i = 0; i < num; i++)
{
int fd = dopoll.dp_fds[i].fd;
PF *hdl = NULL;
rb_fde_t *F = rb_find_fd(fd);
if((dopoll.dp_fds[i].
revents & (POLLRDNORM | POLLIN | POLLHUP |
POLLERR))
&& (dopoll.dp_fds[i].events & (POLLRDNORM | POLLIN)))
{
if((hdl = F->read_handler) != NULL)
{
F->read_handler = NULL;
hdl(F, F->read_data);
/*
* this call used to be with a NULL pointer, BUT
* in the devpoll case we only want to update the
* poll set *if* the handler changes state (active ->
* NULL or vice versa.)
*/
devpoll_update_events(fd,
RB_SELECT_READ, F->read_handler);
}
}
if(!IsFDOpen(F))
continue; /* Read handler closed us..go on to do something more useful */
if((dopoll.dp_fds[i].
revents & (POLLWRNORM | POLLOUT | POLLHUP |
POLLERR))
&& (dopoll.dp_fds[i].events & (POLLWRNORM | POLLOUT)))
{
if((hdl = F->write_handler) != NULL)
{
F->write_handler = NULL;
hdl(F, F->write_data);
/* See above similar code in the read case */
devpoll_update_events(fd,
RB_SELECT_WRITE, F->write_handler);
}
}
}
return RB_OK;
}
while (0);
/* XXX Get here, we broke! */
return 0;
}
#else /* /dev/poll not supported */
int
rb_init_netio_devpoll(void)
{
return ENOSYS;
}
void
rb_setselect_devpoll(rb_fde_t *F, unsigned int type, PF * handler, void *client_data)
{
errno = ENOSYS;
return;
}
int
rb_select_devpoll(long delay)
{
errno = ENOSYS;
return -1;
}
int
rb_setup_fd_devpoll(rb_fde_t *F)
{
errno = ENOSYS;
return -1;
}
#endif

464
libratbox/src/epoll.c Normal file
View file

@ -0,0 +1,464 @@
/*
* ircd-ratbox: A slightly useful ircd.
* epoll.c: Linux epoll compatible network routines.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
* Copyright (C) 2002-2005 ircd-ratbox development team
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: epoll.c 25038 2008-01-23 16:03:08Z androsyn $
*/
#define _GNU_SOURCE 1
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
#include <event-int.h>
#if defined(HAVE_EPOLL_CTL) && (HAVE_SYS_EPOLL_H)
#define USING_EPOLL
#include <fcntl.h>
#include <sys/epoll.h>
#if defined(HAVE_SIGNALFD) && (HAVE_SYS_SIGNALFD_H) && (USE_TIMER_CREATE) && (HAVE_SYS_UIO_H)
#include <signal.h>
#include <sys/signalfd.h>
#include <sys/uio.h>
#define EPOLL_SCHED_EVENT 1
#endif
#define RTSIGNAL SIGRTMIN
struct epoll_info
{
int ep;
struct epoll_event *pfd;
int pfd_size;
};
static struct epoll_info *ep_info;
static int can_do_event;
//static void setup_signalfd(void);
/*
* rb_init_netio
*
* This is a needed exported function which will be called to initialise
* the network loop code.
*/
int
rb_init_netio_epoll(void)
{
can_do_event = 0; /* shut up gcc */
ep_info = rb_malloc(sizeof(struct epoll_info));
ep_info->pfd_size = getdtablesize();
ep_info->ep = epoll_create(ep_info->pfd_size);
if(ep_info->ep < 0)
{
return -1;
}
rb_open(ep_info->ep, RB_FD_UNKNOWN, "epoll file descriptor");
ep_info->pfd = rb_malloc(sizeof(struct epoll_event) * ep_info->pfd_size);
return 0;
}
int
rb_setup_fd_epoll(rb_fde_t * F)
{
return 0;
}
/*
* rb_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
rb_setselect_epoll(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
{
struct epoll_event ep_event;
int old_flags = F->pflags;
int op = -1;
lrb_assert(IsFDOpen(F));
/* Update the list, even though we're not using it .. */
if(type & RB_SELECT_READ)
{
if(handler != NULL)
F->pflags |= EPOLLIN;
else
F->pflags &= ~EPOLLIN;
F->read_handler = handler;
F->read_data = client_data;
}
if(type & RB_SELECT_WRITE)
{
if(handler != NULL)
F->pflags |= EPOLLOUT;
else
F->pflags &= ~EPOLLOUT;
F->write_handler = handler;
F->write_data = client_data;
}
if(old_flags == 0 && F->pflags == 0)
return;
else if(F->pflags <= 0)
op = EPOLL_CTL_DEL;
else if(old_flags == 0 && F->pflags > 0)
op = EPOLL_CTL_ADD;
else if(F->pflags != old_flags)
op = EPOLL_CTL_MOD;
if(op == -1)
return;
ep_event.events = F->pflags;
ep_event.data.ptr = F;
if(op == EPOLL_CTL_ADD || op == EPOLL_CTL_MOD)
ep_event.events |= EPOLLET;
if(epoll_ctl(ep_info->ep, op, F->fd, &ep_event) != 0)
{
rb_lib_log("rb_setselect_epoll(): epoll_ctl failed: %s", strerror(errno));
abort();
}
}
/*
* rb_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
* rb_setselect and fd_table[] and calls callbacks for IO ready
* events.
*/
int
rb_select_epoll(long delay)
{
int num, i, flags, old_flags, op;
struct epoll_event ep_event;
int o_errno;
void *data;
num = epoll_wait(ep_info->ep, ep_info->pfd, ep_info->pfd_size, delay);
/* save errno as rb_set_time() will likely clobber it */
o_errno = errno;
rb_set_time();
errno = o_errno;
if(num < 0 && !rb_ignore_errno(o_errno))
return RB_ERROR;
if(num <= 0)
return RB_OK;
for (i = 0; i < num; i++)
{
PF *hdl;
rb_fde_t *F = ep_info->pfd[i].data.ptr;
old_flags = F->pflags;
if(ep_info->pfd[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR))
{
hdl = F->read_handler;
data = F->read_data;
F->read_handler = NULL;
F->read_data = NULL;
if(hdl)
{
hdl(F, data);
}
}
if(!IsFDOpen(F))
continue;
if(ep_info->pfd[i].events & (EPOLLOUT | EPOLLHUP | EPOLLERR))
{
hdl = F->write_handler;
data = F->write_data;
F->write_handler = NULL;
F->write_data = NULL;
if(hdl)
{
hdl(F, data);
}
}
if(!IsFDOpen(F))
continue;
flags = 0;
if(F->read_handler != NULL)
flags |= EPOLLIN;
if(F->write_handler != NULL)
flags |= EPOLLOUT;
if(old_flags != flags)
{
if(flags == 0)
op = EPOLL_CTL_DEL;
else
op = EPOLL_CTL_MOD;
F->pflags = ep_event.events = flags;
ep_event.data.ptr = F;
if(op == EPOLL_CTL_MOD || op == EPOLL_CTL_ADD)
ep_event.events |= EPOLLET;
if(epoll_ctl(ep_info->ep, op, F->fd, &ep_event) != 0)
{
rb_lib_log("rb_select_epoll(): epoll_ctl failed: %s",
strerror(errno));
}
}
}
return RB_OK;
}
#ifdef EPOLL_SCHED_EVENT
int
rb_epoll_supports_event(void)
{
/* try to detect at runtime if everything we need actually works */
timer_t timer;
struct sigevent ev;
int fd;
sigset_t set;
if(can_do_event == 1)
return 1;
if(can_do_event == -1)
return 0;
ev.sigev_signo = SIGVTALRM;
ev.sigev_notify = SIGEV_SIGNAL;
if(timer_create(CLOCK_REALTIME, &ev, &timer) != 0)
{
can_do_event = -1;
return 0;
}
timer_delete(timer);
sigemptyset(&set);
fd = signalfd(-1, &set, 0);
if(fd < 0)
{
can_do_event = -1;
return 0;
}
close(fd);
can_do_event = 1;
return 1;
}
/* bleh..work around a glibc header bug on 32bit systems */
struct our_signalfd_siginfo {
rb_uint32_t signo;
rb_int32_t err;
rb_int32_t code;
rb_uint32_t pid;
rb_uint32_t uid;
rb_int32_t fd;
rb_uint32_t tid;
rb_uint32_t band;
rb_uint32_t overrun;
rb_uint32_t trapno;
rb_int32_t status;
rb_int32_t svint;
rb_uint64_t svptr;
rb_uint64_t utime;
rb_uint64_t stime;
rb_uint64_t addr;
rb_uint8_t pad[48];
};
#define SIGFDIOV_COUNT 16
static void
signalfd_handler(rb_fde_t *F, void *data)
{
static struct our_signalfd_siginfo fdsig[SIGFDIOV_COUNT];
static struct iovec iov[SIGFDIOV_COUNT];
struct ev_entry *ev;
int ret, x;
for(x = 0; x < SIGFDIOV_COUNT; x++)
{
iov[x].iov_base = &fdsig[x];
iov[x].iov_len = sizeof(struct our_signalfd_siginfo);
}
while(1)
{
ret = readv(rb_get_fd(F), iov, SIGFDIOV_COUNT);
if(ret == 0 || (ret < 0 && !rb_ignore_errno(errno)))
{
rb_close(F);
rb_epoll_init_event();
return;
}
if(ret < 0)
{
rb_setselect(F, RB_SELECT_READ, signalfd_handler, NULL);
return;
}
for(x = 0; x < ret / (int)sizeof(struct signalfd_siginfo); x++)
{
ev = (struct ev_entry *)fdsig[x].svptr;
if(ev == NULL)
continue;
rb_run_event(ev);
}
}
}
void
rb_epoll_init_event(void)
{
sigset_t ss;
rb_fde_t *F;
int sfd;
sigemptyset(&ss);
sigaddset(&ss, RTSIGNAL);
sigprocmask(SIG_BLOCK, &ss, 0);
sigemptyset(&ss);
sigaddset(&ss, RTSIGNAL);
sfd = signalfd(-1, &ss, 0);
if(sfd == -1) {
can_do_event = -1;
return;
}
F = rb_open(sfd, RB_FD_UNKNOWN, "signalfd");
rb_set_nb(F);
signalfd_handler(F, NULL);
}
int
rb_epoll_sched_event(struct ev_entry *event, int when)
{
timer_t *id;
struct sigevent ev;
struct itimerspec ts;
memset(&ev, 0, sizeof(&ev));
event->comm_ptr = rb_malloc(sizeof(timer_t));
id = event->comm_ptr;
ev.sigev_notify = SIGEV_SIGNAL;
ev.sigev_signo = RTSIGNAL;
ev.sigev_value.sival_ptr = event;
if (timer_create(CLOCK_REALTIME, &ev, id) < 0)
{
rb_lib_log("timer_create: %s\n", strerror(errno));
return 0;
}
memset(&ts, 0, sizeof(ts));
ts.it_value.tv_sec = when;
ts.it_value.tv_nsec = 0;
if(event->frequency != 0)
ts.it_interval = ts.it_value;
if(timer_settime(*id, 0, &ts, NULL) < 0)
{
rb_lib_log("timer_settime: %s\n", strerror(errno));
return 0;
}
return 1;
}
void
rb_epoll_unsched_event(struct ev_entry *event)
{
timer_delete(*((timer_t *)event->comm_ptr));
rb_free(event->comm_ptr);
event->comm_ptr = NULL;
}
#endif /* EPOLL_SCHED_EVENT */
#else /* epoll not supported here */
int
rb_init_netio_epoll(void)
{
return ENOSYS;
}
void
rb_setselect_epoll(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
{
errno = ENOSYS;
return;
}
int
rb_select_epoll(long delay)
{
errno = ENOSYS;
return -1;
}
int
rb_setup_fd_epoll(rb_fde_t * F)
{
errno = ENOSYS;
return -1;
}
#endif
#if !defined(USING_EPOLL) || !defined(EPOLL_SCHED_EVENT)
void rb_epoll_init_event(void)
{
return;
}
int
rb_epoll_sched_event(struct ev_entry *event, int when)
{
errno = ENOSYS;
return -1;
}
void
rb_epoll_unsched_event(struct ev_entry *event)
{
return;
}
int
rb_epoll_supports_event(void)
{
errno = ENOSYS;
return 0;
}
#endif /* !USING_EPOLL || !EPOLL_SCHED_EVENT */

352
libratbox/src/event.c Normal file
View file

@ -0,0 +1,352 @@
/*
* ircd-ratbox: A slightly useful ircd.
* event.c: Event functions.
*
* Copyright (C) 1998-2000 Regents of the University of California
* Copyright (C) 2001-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: event.c 25147 2008-03-28 17:15:47Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
#include <event-int.h>
static const char *last_event_ran = NULL;
static rb_dlink_list event_list;
static time_t event_time_min = -1;
/* The list of event processes */
#if 0
struct ev_entry
{
rb_dlink_node node;
EVH *func;
void *arg;
const char *name;
time_t frequency;
time_t when;
void *data;
};
#endif
/*
* struct ev_entry *
* rb_event_find(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 struct ev_entry *
rb_event_find(EVH * func, void *arg)
{
rb_dlink_node *ptr;
struct ev_entry *ev;
RB_DLINK_FOREACH(ptr, event_list.head)
{
ev = ptr->data;
if((ev->func == func) && (ev->arg == arg))
return ev;
}
return NULL;
}
/*
* struct ev_entry *
* rb_event_add(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.
*/
struct ev_entry *
rb_event_add(const char *name, EVH * func, void *arg, time_t when)
{
struct ev_entry *ev;
ev = rb_malloc(sizeof(struct ev_entry));
ev->func = func;
ev->name = name;
ev->arg = arg;
ev->when = rb_current_time() + when;
ev->frequency = when;
if((ev->when < event_time_min) || (event_time_min == -1))
{
event_time_min = ev->when;
}
rb_dlinkAdd(ev, &ev->node, &event_list);
rb_io_sched_event(ev, when);
return ev;
}
struct ev_entry *
rb_event_addonce(const char *name, EVH * func, void *arg, time_t when)
{
struct ev_entry *ev;
ev = rb_malloc(sizeof(struct ev_entry));
ev->func = func;
ev->name = name;
ev->arg = arg;
ev->when = rb_current_time() + when;
ev->frequency = 0;
if((ev->when < event_time_min) || (event_time_min == -1))
event_time_min = ev->when;
rb_dlinkAdd(ev, &ev->node, &event_list);
rb_io_sched_event(ev, when);
return ev;
}
/*
* void rb_event_delete(struct ev_entry *ev)
*
* Input: pointer to ev_entry for the event
* Output: None
* Side Effects: Removes the event from the event list
*/
void
rb_event_delete(struct ev_entry *ev)
{
if(ev == NULL)
return;
rb_dlinkDelete(&ev->node, &event_list);
rb_io_unsched_event(ev);
rb_free(ev);
}
/*
* void rb_event_find_delete(EVH *func, void *arg)
*
* Input: pointer to func and data
* Output: None
* Side Effects: Removes the event from the event list
*/
void
rb_event_find_delete(EVH *func, void *arg)
{
rb_event_delete(rb_event_find(func, arg));
}
/*
* struct ev_entry *
* rb_event_addish(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.
*/
struct ev_entry *
rb_event_addish(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
*/
}
return rb_event_add(name, func, arg, delta_ish);
}
void
rb_run_event(struct ev_entry *ev)
{
last_event_ran = ev->name;
ev->func(ev->arg);
if(!ev->frequency)
{
rb_io_unsched_event(ev);
rb_dlinkDelete(&ev->node, &event_list);
rb_free(ev);
return;
}
ev->when = rb_current_time() + ev->frequency;
if((ev->when < event_time_min) || (event_time_min == -1))
event_time_min = ev->when;
}
/*
* void rb_event_run(void)
*
* Input: None
* Output: None
* Side Effects: Runs pending events in the event list
*/
void
rb_event_run(void)
{
rb_dlink_node *ptr, *next;
struct ev_entry *ev;
if(rb_io_supports_event())
return;
event_time_min = -1;
RB_DLINK_FOREACH_SAFE(ptr, next, event_list.head)
{
ev = ptr->data;
if(ev->when <= rb_current_time())
{
last_event_ran = ev->name;
ev->func(ev->arg);
/* event is scheduled more than once */
if(ev->frequency)
{
ev->when = rb_current_time() + ev->frequency;
if((ev->when < event_time_min) || (event_time_min == -1))
event_time_min = ev->when;
}
else
{
rb_dlinkDelete(&ev->node, &event_list);
rb_free(ev);
}
} else {
if((ev->when < event_time_min) || (event_time_min == -1))
event_time_min = ev->when;
}
}
}
void
rb_event_io_register_all(void)
{
rb_dlink_node *ptr;
struct ev_entry *ev;
int when;
if(!rb_io_supports_event())
return;
RB_DLINK_FOREACH(ptr, event_list.head)
{
ev = ptr->data;
when = ev->when - rb_current_time();
rb_io_sched_event(ev, when);
}
}
/*
* void rb_event_init(void)
*
* Input: None
* Output: None
* Side Effects: Initializes the event system.
*/
void
rb_event_init(void)
{
last_event_ran = NULL;
}
void
rb_dump_events(void (*func) (char *, void *), void *ptr)
{
int len;
char buf[512];
rb_dlink_node *dptr;
struct ev_entry *ev;
len = sizeof(buf);
if(last_event_ran)
{
rb_snprintf(buf, len, "Last event to run: %s", last_event_ran);
func(buf, ptr);
}
rb_strlcpy(buf, "Operation Next Execution", len);
func(buf, ptr);
RB_DLINK_FOREACH(dptr, event_list.head)
{
ev = dptr->data;
rb_snprintf(buf, len, "%-28s %-4ld seconds", ev->name,
ev->when - (long) rb_current_time());
func(buf, ptr);
}
}
/*
* void rb_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
rb_set_back_events(time_t by)
{
rb_dlink_node *ptr;
struct ev_entry *ev;
RB_DLINK_FOREACH(ptr, event_list.head)
{
ev = ptr->data;
if(ev->when > by)
ev->when -= by;
else
ev->when = 0;
}
}
void
rb_event_update(struct ev_entry *ev, time_t freq)
{
if(ev == NULL)
return;
ev->frequency = freq;
/* update when its scheduled to run if its higher
* than the new frequency
*/
if((rb_current_time() + freq) < ev->when)
ev->when = rb_current_time() + freq;
return;
}
time_t
rb_event_next(void)
{
return event_time_min;
}

View file

@ -0,0 +1,150 @@
rb_bh_alloc
rb_bh_create
rb_bh_destroy
rb_bh_free
rb_bh_gc
rb_bh_total_usage
rb_bh_usage
rb_bh_usage_all
rb_init_bh
rb_accept_tcp
rb_checktimeouts
rb_close
rb_connect_sockaddr
rb_connect_tcp
rb_connect_tcp_ssl
rb_dump_fd
rb_errstr
rb_fd_ssl
rb_fdlist_init
rb_get_fd
rb_get_fde
rb_get_iotype
rb_get_random
rb_get_sockerr
rb_get_ssl_strerror
rb_get_type
rb_getmaxconnect
rb_ignore_errno
rb_inet_ntop
rb_inet_ntop_sock
rb_inet_pton
rb_inet_pton_sock
rb_init_netio
rb_init_prng
rb_listen
rb_note
rb_open
rb_pipe
rb_read
rb_recv_fd_buf
rb_select
rb_send_fd_buf
rb_set_buffers
rb_set_nb
rb_set_type
rb_setselect
rb_settimeout
rb_setup_fd
rb_setup_ssl_server
rb_socket
rb_socketpair
rb_ssl_listen
rb_ssl_start_accepted
rb_ssl_start_connected
rb_write
rb_writev
rb_crypt
rb_dump_events
rb_event_add
rb_event_addish
rb_event_addonce
rb_event_delete
rb_event_find_delete
rb_event_init
rb_event_next
rb_event_run
rb_event_update
rb_run_event
rb_helper_child
rb_helper_close
rb_helper_loop
rb_helper_read
rb_helper_restart
rb_helper_run
rb_helper_start
rb_helper_write
rb_helper_write_queue
rb_count_rb_linebuf_memory
rb_linebuf_attach
rb_linebuf_donebuf
rb_linebuf_flush
rb_linebuf_get
rb_linebuf_init
rb_linebuf_newbuf
rb_linebuf_parse
rb_linebuf_put
rb_linebuf_putbuf
rb_linebuf_putmsg
make_and_lookup
make_and_lookup_ip
rb_clear_patricia
rb_destroy_patricia
rb_init_patricia
rb_match_exact_string
rb_match_ip
rb_match_ip_exact
rb_match_string
rb_new_patricia
rb_patricia_lookup
rb_patricia_process
rb_patricia_remove
rb_patricia_search_best
rb_patricia_search_best2
rb_patricia_search_exact
rb_base64_decode
rb_base64_encode
rb_ctime
rb_current_time
rb_current_time_tv
rb_date
rb_lib_die
rb_lib_init
rb_lib_log
rb_lib_loop
rb_lib_restart
rb_lib_version
rb_set_time
rb_strtok_r
rb_free_rawbuffer
rb_init_rawbuffers
rb_new_rawbuffer
rb_rawbuf_append
rb_rawbuf_flush
rb_rawbuf_get
rb_rawbuf_length
rb_free
rb_malloc
rb_outofmemory
rb_realloc
rb_strdup
rb_strndup
rb_snprintf
rb_snprintf_append
rb_sprintf
rb_sprintf_append
rb_vsnprintf
rb_vsnprintf_append
rb_vsprintf
rb_vsprintf_append
rb_free_rb_dlink_node
rb_init_rb_dlink_nodes
rb_make_rb_dlink_node
rb_string_to_array
rb_strlcat
rb_strlcpy
rb_strnlen
rb_gettimeofday
rb_sleep
rb_spawn_process
rb_supports_ssl

295
libratbox/src/helper.c Normal file
View file

@ -0,0 +1,295 @@
/*
* ircd-ratbox: A slightly useful ircd
* helper.c: Starts and deals with ircd helpers
*
* Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: helper.c 25038 2008-01-23 16:03:08Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
struct _rb_helper
{
char *path;
buf_head_t sendq;
buf_head_t recvq;
rb_fde_t *ifd;
rb_fde_t *ofd;
pid_t pid;
int fork_count;
rb_helper_cb *read_cb;
rb_helper_cb *error_cb;
};
/* setup all the stuff a new child needs */
rb_helper *
rb_helper_child(rb_helper_cb *read_cb, rb_helper_cb *error_cb, log_cb *ilog, restart_cb *irestart, die_cb *idie,
int maxcon, size_t lb_heap_size, size_t dh_size, size_t fd_heap_size)
{
rb_helper *helper;
int maxfd, x = 0;
int ifd, ofd;
char *tifd, *tofd, *tmaxfd;
tifd = getenv("IFD");
tofd = getenv("OFD");
tmaxfd = getenv("MAXFD");
if(tifd == NULL || tofd == NULL || tmaxfd == NULL)
return NULL;
helper = rb_malloc(sizeof(rb_helper));
ifd = (int)strtol(tifd, NULL, 10);
ofd = (int)strtol(tofd, NULL, 10);
maxfd = (int)strtol(tmaxfd, NULL, 10);
#ifndef WIN32
for(x = 0; x < maxfd; x++)
{
if(x != ifd && x != ofd)
close(x);
}
x = open("/dev/null", O_RDWR);
if(ifd != 0 && ofd != 0)
dup2(x, 0);
if(ifd != 1 && ofd != 1)
dup2(x, 1);
if(ifd != 2 && ofd != 2)
dup2(x, 2);
if(x > 2) /* don't undo what we just did */
close(x);
#else
x = 0; /* shut gcc up */
#endif
rb_lib_init(ilog, irestart, idie, 0, maxfd, dh_size, fd_heap_size);
rb_linebuf_init(lb_heap_size);
rb_linebuf_newbuf(&helper->sendq);
rb_linebuf_newbuf(&helper->recvq);
helper->ifd = rb_open(ifd, RB_FD_PIPE, "incoming connection");
helper->ofd = rb_open(ofd, RB_FD_PIPE, "outgoing connection");
rb_set_nb(helper->ifd);
rb_set_nb(helper->ofd);
helper->read_cb = read_cb;
helper->error_cb = error_cb;
return helper;
}
/*
* start_fork_helper
* starts a new ircd helper
* note that this function doesn't start doing reading..thats the job of the caller
*/
rb_helper *
rb_helper_start(const char *name, const char *fullpath, rb_helper_cb *read_cb, rb_helper_cb *error_cb)
{
rb_helper *helper;
const char *parv[2];
char buf[128];
char fx[16], fy[16];
rb_fde_t *in_f[2];
rb_fde_t *out_f[2];
pid_t pid;
if(access(fullpath, X_OK) == -1)
return NULL;
helper = rb_malloc(sizeof(rb_helper));
rb_snprintf(buf, sizeof(buf), "%s helper - read", name);
if(rb_pipe(&in_f[0], &in_f[1], buf) < 0)
{
rb_free(helper);
return NULL;
}
rb_snprintf(buf, sizeof(buf), "%s helper - write", name);
if(rb_pipe(&out_f[0], &out_f[1], buf) < 0)
{
rb_free(helper);
return NULL;
}
rb_snprintf(fx, sizeof(fx), "%d", rb_get_fd(in_f[1]));
rb_snprintf(fy, sizeof(fy), "%d", rb_get_fd(out_f[0]));
rb_set_nb(in_f[0]);
rb_set_nb(in_f[1]);
rb_set_nb(out_f[0]);
rb_set_nb(out_f[1]);
setenv("IFD", fy, 1);
setenv("OFD", fx, 1);
setenv("MAXFD", "256", 1);
rb_snprintf(buf, sizeof(buf), "-ircd %s daemon", name);
parv[0] = buf;
parv[1] = NULL;
#ifdef WIN32
SetHandleInformation((HANDLE)rb_get_fd(in_f[1]), HANDLE_FLAG_INHERIT, 1);
SetHandleInformation((HANDLE)rb_get_fd(out_f[0]), HANDLE_FLAG_INHERIT, 1);
#endif
pid = rb_spawn_process(fullpath, (const char **)parv);
if(pid == -1)
{
rb_close(in_f[0]);
rb_close(in_f[1]);
rb_close(out_f[0]);
rb_close(out_f[1]);
rb_free(helper);
return NULL;
}
rb_close(in_f[1]);
rb_close(out_f[0]);
rb_linebuf_newbuf(&helper->sendq);
rb_linebuf_newbuf(&helper->recvq);
helper->ifd = in_f[0];
helper->ofd = out_f[1];
helper->read_cb = read_cb;
helper->error_cb = error_cb;
helper->fork_count = 0;
helper->pid = pid;
return helper;
}
void
rb_helper_restart(rb_helper *helper)
{
helper->error_cb(helper);
}
static void
rb_helper_write_sendq(rb_fde_t *F, void *helper_ptr)
{
rb_helper *helper = helper_ptr;
int retlen;
if(rb_linebuf_len(&helper->sendq) > 0)
{
while((retlen = rb_linebuf_flush(F, &helper->sendq)) > 0)
;;
if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno))) {
rb_helper_restart(helper);
return;
}
}
if(rb_linebuf_len(&helper->sendq) > 0)
rb_setselect(helper->ofd, RB_SELECT_WRITE, rb_helper_write_sendq, helper);
}
void
rb_helper_write_queue(rb_helper *helper, const char *format, ...)
{
va_list ap;
va_start(ap, format);
rb_linebuf_putmsg(&helper->sendq, format, &ap, NULL);
va_end(ap);
}
void
rb_helper_write_flush(rb_helper *helper)
{
rb_helper_write_sendq(helper->ofd, helper);
}
void
rb_helper_write(rb_helper *helper, const char *format, ...)
{
va_list ap;
va_start(ap, format);
rb_linebuf_putmsg(&helper->sendq, format, &ap, NULL);
va_end(ap);
rb_helper_write_flush(helper);
}
static void
rb_helper_read_cb(rb_fde_t *F, void *data)
{
rb_helper *helper = (rb_helper *)data;
static char buf[32768];
int length;
if(helper == NULL)
return;
while((length = rb_read(helper->ifd, buf, sizeof(buf))) > 0)
{
rb_linebuf_parse(&helper->recvq, buf, length, 0);
helper->read_cb(helper);
}
if(length == 0 || (length < 0 && !rb_ignore_errno(errno)))
{
rb_helper_restart(helper);
return;
}
rb_setselect(helper->ifd, RB_SELECT_READ, rb_helper_read_cb, helper);
}
void
rb_helper_run(rb_helper *helper)
{
if(helper == NULL)
return;
rb_helper_read_cb(helper->ifd, helper);
}
void
rb_helper_close(rb_helper *helper)
{
if(helper == NULL)
return;
rb_close(helper->ifd);
rb_close(helper->ofd);
rb_free(helper);
}
int
rb_helper_read(rb_helper *helper, void *buf, size_t bufsize)
{
return rb_linebuf_get(&helper->recvq, buf, bufsize, LINEBUF_COMPLETE, LINEBUF_PARSED);
}
void
rb_helper_loop(rb_helper *helper, long delay)
{
rb_helper_run(helper);
while(1)
{
rb_lib_loop(delay);
}
}

399
libratbox/src/kqueue.c Normal file
View file

@ -0,0 +1,399 @@
/*
* ircd-ratbox: A slightly useful ircd.
* kqueue.c: FreeBSD kqueue compatible network routines.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: kqueue.c 25038 2008-01-23 16:03:08Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
#include <event-int.h>
#if defined(HAVE_SYS_EVENT_H) && (HAVE_KEVENT)
#include <sys/event.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
#ifdef EVFILT_TIMER
#define KQUEUE_SCHED_EVENT
#endif
static void kq_update_events(rb_fde_t *, short, PF *);
static int kq;
static struct timespec zero_timespec;
static struct kevent *kqlst; /* kevent buffer */
static int kqmax; /* max structs to buffer */
static int kqoff; /* offset into the buffer */
int
rb_setup_fd_kqueue(rb_fde_t * F)
{
return 0;
}
static void
kq_update_events(rb_fde_t * F, short filter, PF * handler)
{
PF *cur_handler;
int kep_flags;
switch (filter)
{
case EVFILT_READ:
cur_handler = F->read_handler;
break;
case EVFILT_WRITE:
cur_handler = F->write_handler;
break;
default:
/* XXX bad! -- adrian */
return;
break;
}
if((cur_handler == NULL && handler != NULL) || (cur_handler != NULL && handler == NULL))
{
struct kevent *kep;
kep = kqlst + kqoff;
if(handler != NULL)
{
if(filter == EVFILT_WRITE)
kep_flags = (EV_ADD | EV_ONESHOT);
else
kep_flags = EV_ADD;
}
else
{
kep_flags = EV_DELETE;
}
EV_SET(kep, (uintptr_t) F->fd, filter, kep_flags, 0, 0, (void *) F);
if(++kqoff == kqmax)
{
int ret;
ret = kevent(kq, kqlst, kqoff, NULL, 0, &zero_timespec);
/* jdc -- someone needs to do error checking... */
if(ret == -1)
{
rb_lib_log("kq_update_events(): kevent(): %s", strerror(errno));
return;
}
kqoff = 0;
}
}
}
/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
/* Public functions */
/*
* rb_init_netio
*
* This is a needed exported function which will be called to initialise
* the network loop code.
*/
int
rb_init_netio_kqueue(void)
{
kq = kqueue();
if(kq < 0)
{
return errno;
}
kqmax = getdtablesize();
kqlst = rb_malloc(sizeof(struct kevent) * kqmax);
rb_open(kq, RB_FD_UNKNOWN, "kqueue fd");
zero_timespec.tv_sec = 0;
zero_timespec.tv_nsec = 0;
return 0;
}
/*
* rb_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
rb_setselect_kqueue(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
{
lrb_assert(IsFDOpen(F));
if(type & RB_SELECT_READ)
{
kq_update_events(F, EVFILT_READ, handler);
F->read_handler = handler;
F->read_data = client_data;
}
if(type & RB_SELECT_WRITE)
{
kq_update_events(F, EVFILT_WRITE, handler);
F->write_handler = handler;
F->write_data = client_data;
}
}
/*
* Check all connections for new connections and input data that is to be
* processed. Also check for connections with data queued and whether we can
* write it out.
*/
/*
* rb_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
* rb_setselect and fd_table[] and calls callbacks for IO ready
* events.
*/
int
rb_select_kqueue(long delay)
{
int num, i;
static struct kevent ke[KE_LENGTH];
struct timespec poll_time;
struct timespec *pt;
rb_fde_t *F;
if(delay < 0) {
pt = NULL;
}
else {
pt = &poll_time;
poll_time.tv_sec = delay / 1000;
poll_time.tv_nsec = (delay % 1000) * 1000000;
}
for (;;)
{
num = kevent(kq, kqlst, kqoff, ke, KE_LENGTH, pt);
kqoff = 0;
if(num >= 0)
break;
if(rb_ignore_errno(errno))
break;
rb_set_time();
return RB_ERROR;
/* NOTREACHED */
}
rb_set_time();
if(num == 0)
return RB_OK; /* No error.. */
for (i = 0; i < num; i++)
{
PF *hdl = NULL;
if(ke[i].flags & EV_ERROR)
{
errno = ke[i].data;
/* XXX error == bad! -- adrian */
continue; /* XXX! */
}
switch (ke[i].filter)
{
case EVFILT_READ:
F = ke[i].udata;
if((hdl = F->read_handler) != NULL)
{
F->read_handler = NULL;
hdl(F, F->read_data);
}
break;
case EVFILT_WRITE:
F = ke[i].udata;
if((hdl = F->write_handler) != NULL)
{
F->write_handler = NULL;
hdl(F, F->write_data);
}
break;
#if defined(EVFILT_TIMER)
case EVFILT_TIMER:
rb_run_event(ke[i].udata);
break;
#endif
default:
/* Bad! -- adrian */
break;
}
}
return RB_OK;
}
static int can_do_event = 0;
int
rb_kqueue_supports_event(void)
{
struct kevent kv;
struct timespec ts;
int xkq;
if(can_do_event == 1)
return 1;
if(can_do_event == -1)
return 0;
xkq = kqueue();
ts.tv_sec = 0;
ts.tv_nsec = 1000;
EV_SET(&kv, (uintptr_t) 0x0, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 1, 0);
if(kevent(xkq, &kv, 1, NULL, 0, NULL) < 0)
{
can_do_event = -1;
close(xkq);
return 0;
}
close(xkq);
can_do_event = 1;
return 1;
}
int
rb_kqueue_sched_event(struct ev_entry *event, int when)
{
struct kevent kev;
int kep_flags;
kep_flags = EV_ADD;
if(event->frequency == 0)
kep_flags |= EV_ONESHOT;
EV_SET(&kev, (uintptr_t) event, EVFILT_TIMER, kep_flags, 0, when * 1000, event);
if(kevent(kq, &kev, 1, NULL, 0, NULL) < 0)
return 0;
return 1;
}
void
rb_kqueue_unsched_event(struct ev_entry *event)
{
struct kevent kev;
EV_SET(&kev, (uintptr_t) event, EVFILT_TIMER, EV_DELETE, 0, 0, event);
kevent(kq, &kev, 1, NULL, 0, NULL);
}
void
rb_kqueue_init_event(void)
{
return;
}
#else /* kqueue not supported */
int
rb_init_netio_kqueue(void)
{
errno = ENOSYS;
return -1;
}
void
rb_setselect_kqueue(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
{
errno = ENOSYS;
return;
}
int
rb_select_kqueue(long delay)
{
errno = ENOSYS;
return -1;
}
int
rb_setup_fd_kqueue(rb_fde_t * F)
{
errno = ENOSYS;
return -1;
}
#endif
#if !defined(HAVE_KEVENT) || !defined(KQUEUE_SCHED_EVENT)
void
rb_kqueue_init_event(void)
{
return;
}
int
rb_kqueue_sched_event(struct ev_entry *event, int when)
{
errno = ENOSYS;
return -1;
}
void
rb_kqueue_unsched_event(struct ev_entry *event)
{
return;
}
int
rb_kqueue_supports_event(void)
{
errno = ENOSYS;
return 0;
}
#endif /* !HAVE_KEVENT || !KQUEUE_SCHED_EVENT */

872
libratbox/src/linebuf.c Normal file
View file

@ -0,0 +1,872 @@
/*
* ircd-ratbox: A slightly useful ircd.
* linebuf.c: Maintains linebuffers.
*
* Copyright (C) 2001-2002 Adrian Chadd <adrian@creative.net.au>
* Copyright (C) 2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: linebuf.c 25038 2008-01-23 16:03:08Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
#ifndef NOBALLOC
static rb_bh *rb_linebuf_heap;
#endif
static int bufline_count = 0;
#ifndef LINEBUF_HEAP_SIZE
#define LINEBUF_HEAP_SIZE 2048
#endif
/*
* rb_linebuf_init
*
* Initialise the linebuf mechanism
*/
void
rb_linebuf_init(size_t heap_size)
{
#ifndef NOBALLOC
rb_linebuf_heap = rb_bh_create(sizeof(buf_line_t), heap_size, "librb_linebuf_heap");
#endif
}
static buf_line_t *
rb_linebuf_allocate(void)
{
buf_line_t *t;
#ifndef NOBALLOC
t = rb_bh_alloc(rb_linebuf_heap);
#else
t = rb_malloc(sizeof(buf_line_t));
#endif
return (t);
}
static void
rb_linebuf_free(buf_line_t * p)
{
#ifndef NOBALLOC
rb_bh_free(rb_linebuf_heap, p);
#else
rb_free(p);
#endif
}
/*
* rb_linebuf_new_line
*
* Create a new line, and link it to the given linebuf.
* It will be initially empty.
*/
static buf_line_t *
rb_linebuf_new_line(buf_head_t * bufhead)
{
buf_line_t *bufline;
rb_dlink_node *node;
bufline = rb_linebuf_allocate();
if(bufline == NULL)
return NULL;
++bufline_count;
node = rb_make_rb_dlink_node();
/* Stick it at the end of the buf list */
rb_dlinkAddTail(bufline, node, &bufhead->list);
bufline->refcount++;
/* And finally, update the allocated size */
bufhead->alloclen++;
bufhead->numlines++;
return bufline;
}
/*
* rb_linebuf_done_line
*
* We've finished with the given line, so deallocate it
*/
static void
rb_linebuf_done_line(buf_head_t * bufhead, buf_line_t * bufline, rb_dlink_node * node)
{
/* Remove it from the linked list */
rb_dlinkDestroy(node, &bufhead->list);
/* Update the allocated size */
bufhead->alloclen--;
bufhead->len -= bufline->len;
lrb_assert(bufhead->len >= 0);
bufhead->numlines--;
bufline->refcount--;
lrb_assert(bufline->refcount >= 0);
if(bufline->refcount == 0)
{
/* and finally, deallocate the buf */
--bufline_count;
lrb_assert(bufline_count >= 0);
rb_linebuf_free(bufline);
}
}
/*
* skip to end of line or the crlfs, return the number of bytes ..
*/
static inline int
rb_linebuf_skip_crlf(char *ch, int len)
{
int orig_len = len;
/* First, skip until the first non-CRLF */
for(; len; len--, ch++)
{
if(*ch == '\r')
break;
else if(*ch == '\n')
break;
}
/* Then, skip until the last CRLF */
for(; len; len--, ch++)
{
if((*ch != '\r') && (*ch != '\n'))
break;
}
lrb_assert(orig_len > len);
return (orig_len - len);
}
/*
* rb_linebuf_newbuf
*
* Initialise the new buffer
*/
void
rb_linebuf_newbuf(buf_head_t * bufhead)
{
/* not much to do right now :) */
memset(bufhead, 0, sizeof(buf_head_t));
}
/*
* rb_linebuf_donebuf
*
* Flush all the lines associated with this buffer
*/
void
rb_linebuf_donebuf(buf_head_t * bufhead)
{
while(bufhead->list.head != NULL)
{
rb_linebuf_done_line(bufhead, (buf_line_t *) bufhead->list.head->data, bufhead->list.head);
}
}
/*
* rb_linebuf_copy_line
*
* Okay..this functions comments made absolutely no sense.
*
* Basically what we do is this. Find the first chunk of text
* and then scan for a CRLF. If we didn't find it, but we didn't
* overflow our buffer..we wait for some more data.
* If we found a CRLF, we replace them with a \0 character.
* If we overflowed, we copy the most our buffer can handle, terminate
* it with a \0 and return.
*
* The return value is the amount of data we consumed. This could
* be different than the size of the linebuffer, as when we discard
* the overflow, we don't want to process it again.
*
* This still sucks in my opinion, but it seems to work.
*
* -Aaron
*/
static int
rb_linebuf_copy_line(buf_head_t * bufhead, buf_line_t * bufline, char *data, int len)
{
int cpylen = 0; /* how many bytes we've copied */
char *ch = data; /* Pointer to where we are in the read data */
char *bufch = bufline->buf + bufline->len;
int clen = 0; /* how many bytes we've processed,
and don't ever want to see again.. */
/* If its full or terminated, ignore it */
bufline->raw = 0;
lrb_assert(bufline->len < BUF_DATA_SIZE);
if(bufline->terminated == 1)
return 0;
clen = cpylen = rb_linebuf_skip_crlf(ch, len);
if(clen == -1)
return -1;
/* This is the ~overflow case..This doesn't happen often.. */
if(cpylen > (BUF_DATA_SIZE - bufline->len - 1))
{
memcpy(bufch, ch, (BUF_DATA_SIZE - bufline->len - 1));
bufline->buf[BUF_DATA_SIZE - 1] = '\0';
bufch = bufline->buf + BUF_DATA_SIZE - 2;
while(cpylen && (*bufch == '\r' || *bufch == '\n'))
{
*bufch = '\0';
cpylen--;
bufch--;
}
bufline->terminated = 1;
bufline->len = BUF_DATA_SIZE - 1;
bufhead->len += BUF_DATA_SIZE - 1;
return clen;
}
memcpy(bufch, ch, cpylen);
bufch += cpylen;
*bufch = '\0';
bufch--;
if(*bufch != '\r' && *bufch != '\n')
{
/* No linefeed, bail for the next time */
bufhead->len += cpylen;
bufline->len += cpylen;
bufline->terminated = 0;
return clen;
}
/* Yank the CRLF off this, replace with a \0 */
while(cpylen && (*bufch == '\r' || *bufch == '\n'))
{
*bufch = '\0';
cpylen--;
bufch--;
}
bufline->terminated = 1;
bufhead->len += cpylen;
bufline->len += cpylen;
return clen;
}
/*
* rb_linebuf_copy_raw
*
* Copy as much data as possible directly into a linebuf,
* splitting at \r\n, but without altering any data.
*
*/
static int
rb_linebuf_copy_raw(buf_head_t * bufhead, buf_line_t * bufline, char *data, int len)
{
int cpylen = 0; /* how many bytes we've copied */
char *ch = data; /* Pointer to where we are in the read data */
char *bufch = bufline->buf + bufline->len;
int clen = 0; /* how many bytes we've processed,
and don't ever want to see again.. */
/* If its full or terminated, ignore it */
bufline->raw = 1;
lrb_assert(bufline->len < BUF_DATA_SIZE);
if(bufline->terminated == 1)
return 0;
clen = cpylen = rb_linebuf_skip_crlf(ch, len);
if(clen == -1)
return -1;
/* This is the overflow case..This doesn't happen often.. */
if(cpylen > (BUF_DATA_SIZE - bufline->len - 1))
{
clen = BUF_DATA_SIZE - bufline->len - 1;
memcpy(bufch, ch, clen);
bufline->buf[BUF_DATA_SIZE - 1] = '\0';
bufch = bufline->buf + BUF_DATA_SIZE - 2;
bufline->terminated = 1;
bufline->len = BUF_DATA_SIZE - 1;
bufhead->len += BUF_DATA_SIZE - 1;
return clen;
}
memcpy(bufch, ch, cpylen);
bufch += cpylen;
*bufch = '\0';
bufch--;
if(*bufch != '\r' && *bufch != '\n')
{
/* No linefeed, bail for the next time */
bufhead->len += cpylen;
bufline->len += cpylen;
bufline->terminated = 0;
return clen;
}
bufline->terminated = 1;
bufhead->len += cpylen;
bufline->len += cpylen;
return clen;
}
/*
* rb_linebuf_parse
*
* Take a given buffer and break out as many buffers as we can.
* If we find a CRLF, we terminate that buffer and create a new one.
* If we don't find a CRLF whilst parsing a buffer, we don't mark it
* 'finished', so the next loop through we can continue appending ..
*
* A few notes here, which you'll need to understand before continuing.
*
* - right now I'm only dealing with single sized buffers. Later on,
* I might consider chaining buffers together to get longer "lines"
* but seriously, I don't see the advantage right now.
*
* - This *is* designed to turn into a reference-counter-protected setup
* to dodge copious copies.
*/
int
rb_linebuf_parse(buf_head_t * bufhead, char *data, int len, int raw)
{
buf_line_t *bufline;
int cpylen;
int linecnt = 0;
/* First, if we have a partial buffer, try to squeze data into it */
if(bufhead->list.tail != NULL)
{
/* Check we're doing the partial buffer thing */
bufline = bufhead->list.tail->data;
lrb_assert(!bufline->flushing);
/* just try, the worst it could do is *reject* us .. */
if(!raw)
cpylen = rb_linebuf_copy_line(bufhead, bufline, data, len);
else
cpylen = rb_linebuf_copy_raw(bufhead, bufline, data, len);
if(cpylen == -1)
return -1;
linecnt++;
/* If we've copied the same as what we've got, quit now */
if(cpylen == len)
return linecnt; /* all the data done so soon? */
/* Skip the data and update len .. */
len -= cpylen;
lrb_assert(len >= 0);
data += cpylen;
}
/* Next, the loop */
while(len > 0)
{
/* We obviously need a new buffer, so .. */
bufline = rb_linebuf_new_line(bufhead);
/* And parse */
if(!raw)
cpylen = rb_linebuf_copy_line(bufhead, bufline, data, len);
else
cpylen = rb_linebuf_copy_raw(bufhead, bufline, data, len);
if(cpylen == -1)
return -1;
len -= cpylen;
lrb_assert(len >= 0);
data += cpylen;
linecnt++;
}
return linecnt;
}
/*
* rb_linebuf_get
*
* get the next buffer from our line. For the time being it will copy
* data into the given buffer and free the underlying linebuf.
*/
int
rb_linebuf_get(buf_head_t * bufhead, char *buf, int buflen, int partial, int raw)
{
buf_line_t *bufline;
int cpylen;
char *start, *ch;
/* make sure we have a line */
if(bufhead->list.head == NULL)
return 0; /* Obviously not.. hrm. */
bufline = bufhead->list.head->data;
/* make sure that the buffer was actually *terminated */
if(!(partial || bufline->terminated))
return 0; /* Wait for more data! */
if(buflen < bufline->len)
cpylen = buflen - 1;
else
cpylen = bufline->len;
/* Copy it */
start = bufline->buf;
/* if we left extraneous '\r\n' characters in the string,
* and we don't want to read the raw data, clean up the string.
*/
if(bufline->raw && !raw)
{
/* skip leading EOL characters */
while(cpylen && (*start == '\r' || *start == '\n'))
{
start++;
cpylen--;
}
/* skip trailing EOL characters */
ch = &start[cpylen - 1];
while(cpylen && (*ch == '\r' || *ch == '\n'))
{
ch--;
cpylen--;
}
}
memcpy(buf, start, cpylen);
/* convert CR/LF to NULL */
if(!raw)
buf[cpylen] = '\0';
lrb_assert(cpylen >= 0);
/* Deallocate the line */
rb_linebuf_done_line(bufhead, bufline, bufhead->list.head);
/* return how much we copied */
return cpylen;
}
/*
* rb_linebuf_attach
*
* attach the lines in a buf_head_t to another buf_head_t
* without copying the data (using refcounts).
*/
void
rb_linebuf_attach(buf_head_t * bufhead, buf_head_t * new)
{
rb_dlink_node *ptr;
buf_line_t *line;
RB_DLINK_FOREACH(ptr, new->list.head)
{
line = ptr->data;
rb_dlinkAddTailAlloc(line, &bufhead->list);
/* Update the allocated size */
bufhead->alloclen++;
bufhead->len += line->len;
bufhead->numlines++;
line->refcount++;
}
}
/*
* rb_linebuf_putmsg
*
* Similar to rb_linebuf_put, but designed for use by send.c.
*
* prefixfmt is used as a format for the varargs, and is inserted first.
* Then format/va_args is appended to the buffer.
*/
void
rb_linebuf_putmsg(buf_head_t * bufhead, const char *format, va_list * va_args, const char *prefixfmt, ...)
{
buf_line_t *bufline;
int len = 0;
va_list prefix_args;
/* make sure the previous line is terminated */
#ifndef NDEBUG
if(bufhead->list.tail)
{
bufline = bufhead->list.tail->data;
lrb_assert(bufline->terminated);
}
#endif
/* Create a new line */
bufline = rb_linebuf_new_line(bufhead);
if(prefixfmt != NULL)
{
va_start(prefix_args, prefixfmt);
len = rb_vsnprintf(bufline->buf, BUF_DATA_SIZE, prefixfmt, prefix_args);
va_end(prefix_args);
}
if(va_args != NULL)
{
len += rb_vsnprintf((bufline->buf + len), (BUF_DATA_SIZE - len), format, *va_args);
}
bufline->terminated = 1;
/* Truncate the data if required */
if(unlikely(len > 510))
{
len = 510;
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
}
else if(unlikely(len == 0))
{
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
bufline->buf[len] = '\0';
}
else
{
/* Chop trailing CRLF's .. */
while((bufline->buf[len] == '\r') || (bufline->buf[len] == '\n') || (bufline->buf[len] == '\0'))
{
len--;
}
bufline->buf[++len] = '\r';
bufline->buf[++len] = '\n';
bufline->buf[++len] = '\0';
}
bufline->len = len;
bufhead->len += len;
}
void
rb_linebuf_putbuf(buf_head_t *bufhead, const char *buffer)
{
buf_line_t *bufline;
int len = 0;
/* make sure the previous line is terminated */
#ifndef NDEBUG
if(bufhead->list.tail)
{
bufline = bufhead->list.tail->data;
lrb_assert(bufline->terminated);
}
#endif
/* Create a new line */
bufline = rb_linebuf_new_line(bufhead);
if(unlikely(buffer != NULL))
len = rb_strlcpy(bufline->buf, buffer, BUF_DATA_SIZE);
bufline->terminated = 1;
/* Truncate the data if required */
if(unlikely(len > 510))
{
len = 510;
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
}
else if(unlikely(len == 0))
{
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
bufline->buf[len] = '\0';
}
else
{
/* Chop trailing CRLF's .. */
while((bufline->buf[len] == '\r') || (bufline->buf[len] == '\n') || (bufline->buf[len] == '\0'))
{
len--;
}
bufline->buf[++len] = '\r';
bufline->buf[++len] = '\n';
bufline->buf[++len] = '\0';
}
bufline->len = len;
bufhead->len += len;
}
void
rb_linebuf_put(buf_head_t * bufhead, const char *format, ...)
{
buf_line_t *bufline;
int len = 0;
va_list args;
/* make sure the previous line is terminated */
#ifndef NDEBUG
if(bufhead->list.tail)
{
bufline = bufhead->list.tail->data;
lrb_assert(bufline->terminated);
}
#endif
/* Create a new line */
bufline = rb_linebuf_new_line(bufhead);
if(unlikely(format != NULL))
{
va_start(args, format);
len = rb_vsnprintf(bufline->buf, BUF_DATA_SIZE, format, args);
va_end(args);
}
bufline->terminated = 1;
/* Truncate the data if required */
if(unlikely(len > 510))
{
len = 510;
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
}
else if(unlikely(len == 0))
{
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
bufline->buf[len] = '\0';
}
else
{
/* Chop trailing CRLF's .. */
while((bufline->buf[len] == '\r') || (bufline->buf[len] == '\n') || (bufline->buf[len] == '\0'))
{
len--;
}
bufline->buf[++len] = '\r';
bufline->buf[++len] = '\n';
bufline->buf[++len] = '\0';
}
bufline->len = len;
bufhead->len += len;
}
/*
* rb_linebuf_flush
*
* Flush data to the buffer. It tries to write as much data as possible
* to the given socket. Any return values are passed straight through.
* If there is no data in the socket, EWOULDBLOCK is set as an errno
* rather than returning 0 (which would map to an EOF..)
*
* Notes: XXX We *should* have a clue here when a non-full buffer is arrived.
* and tag it so that we don't re-schedule another write until
* we have a CRLF.
*/
int
rb_linebuf_flush(rb_fde_t *F, buf_head_t * bufhead)
{
buf_line_t *bufline;
int retval;
/*
* autoconf checks for this..but really just want to use it if we have a
* native version even if libircd provides a fake version...
*/
#ifdef HAVE_WRITEV
if(!rb_fd_ssl(F))
{
rb_dlink_node *ptr;
int x = 0, y;
int xret;
static struct rb_iovec vec[RB_UIO_MAXIOV];
memset(vec, 0, sizeof(vec));
/* Check we actually have a first buffer */
if(bufhead->list.head == NULL)
{
/* nope, so we return none .. */
errno = EWOULDBLOCK;
return -1;
}
ptr = bufhead->list.head;
bufline = ptr->data;
if(!bufline->terminated)
{
errno = EWOULDBLOCK;
return -1;
}
if(bufline->flushing)
{
vec[x].iov_base = bufline->buf + bufhead->writeofs;
vec[x++].iov_len = bufline->len - bufhead->writeofs;
ptr = ptr->next;
}
do
{
if(ptr == NULL)
break;
bufline = ptr->data;
if(!bufline->terminated)
break;
vec[x].iov_base = bufline->buf;
vec[x].iov_len = bufline->len;
ptr = ptr->next;
} while(++x < RB_UIO_MAXIOV);
if(x == 0)
{
errno = EWOULDBLOCK;
return -1;
}
xret = retval = rb_writev(F, vec, x);
if(retval <= 0)
return retval;
ptr = bufhead->list.head;
for(y = 0; y < x; y++)
{
bufline = ptr->data;
if(bufline->flushing)
{
if(xret >= bufline->len - bufhead->writeofs)
{
xret = xret - (bufline->len - bufhead->writeofs);
ptr = ptr->next;
rb_linebuf_done_line(bufhead, bufline, bufhead->list.head);
continue;
}
}
if(xret >= bufline->len)
{
xret = xret - bufline->len;
ptr = ptr->next;
rb_linebuf_done_line(bufhead, bufline, bufhead->list.head);
}
else
{
bufline->flushing = 1;
bufhead->writeofs = xret;
break;
}
}
return retval;
}
#endif
/* this is the non-writev case */
/* Check we actually have a first buffer */
if(bufhead->list.head == NULL)
{
/* nope, so we return none .. */
errno = EWOULDBLOCK;
return -1;
}
bufline = bufhead->list.head->data;
/* And that its actually full .. */
if(!bufline->terminated)
{
errno = EWOULDBLOCK;
return -1;
}
/* Check we're flushing the first buffer */
if(!bufline->flushing)
{
bufline->flushing = 1;
bufhead->writeofs = 0;
}
/* Now, try writing data */
retval = rb_write(F, bufline->buf + bufhead->writeofs, bufline->len - bufhead->writeofs);
if(retval <= 0)
return retval;
/* we've got data, so update the write offset */
bufhead->writeofs += retval;
/* if we've written everything *and* the CRLF, deallocate and update
bufhead */
if(bufhead->writeofs == bufline->len)
{
bufhead->writeofs = 0;
lrb_assert(bufhead->len >= 0);
rb_linebuf_done_line(bufhead, bufline, bufhead->list.head);
}
/* Return line length */
return retval;
}
/*
* count linebufs for stats z
*/
void
rb_count_rb_linebuf_memory(size_t * count, size_t * rb_linebuf_memory_used)
{
#ifndef NOBALLOC
rb_bh_usage(rb_linebuf_heap, count, NULL, rb_linebuf_memory_used, NULL);
#else
*count = 0;
*rb_linebuf_memory_used = 0;
#endif
}

106
libratbox/src/nossl.c Normal file
View file

@ -0,0 +1,106 @@
/*
* libratbox: a library used by ircd-ratbox and other things
* nossl.c: ssl stub code
*
* Copyright (C) 2007-2008 ircd-ratbox development team
* Copyright (C) 2007-2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: commio.c 24808 2008-01-02 08:17:05Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#ifndef HAVE_OPENSSL
#include <commio-int.h>
#include <commio-ssl.h>
int
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile)
{
errno = ENOSYS;
return 0;
}
int
rb_init_ssl(void)
{
errno = ENOSYS;
return -1;
}
int
rb_ssl_listen(rb_fde_t *F, int backlog)
{
errno = ENOSYS;
return -1;
}
int rb_init_prng(const char *path, prng_seed_t seed_type)
{
return -1;
}
int
rb_get_random(void *buf, size_t length)
{
return -1;
}
const char *
rb_get_ssl_strerror(rb_fde_t *F)
{
static const char *nosupport = "SSL/TLS not supported";
return nosupport;
}
void
rb_ssl_start_accepted(rb_fde_t *new_F, ACCB *cb, void *data, int timeout)
{
return;
}
void
rb_ssl_start_connected(rb_fde_t *F, CNCB *callback, void *data, int timeout)
{
return;
}
void
rb_connect_tcp_ssl(rb_fde_t *F, struct sockaddr *dest,
struct sockaddr *clocal, int socklen, CNCB *callback, void *data, int timeout)
{
return;
}
int
rb_supports_ssl(void)
{
return 0;
}
void
rb_ssl_shutdown(rb_fde_t * F)
{
return;
}
#endif /* !HAVE_OPENSSL */

581
libratbox/src/openssl.c Normal file
View file

@ -0,0 +1,581 @@
/*
* libratbox: a library used by ircd-ratbox and other things
* openssl.c: openssl related code
*
* Copyright (C) 2007-2008 ircd-ratbox development team
* Copyright (C) 2007-2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: commio.c 24808 2008-01-02 08:17:05Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#ifdef HAVE_OPENSSL
#include <commio-int.h>
#include <commio-ssl.h>
#include <openssl/ssl.h>
#include <openssl/dh.h>
#include <openssl/err.h>
#include <openssl/rand.h>
static SSL_CTX *ssl_server_ctx;
static SSL_CTX *ssl_client_ctx;
static unsigned long get_last_err(void)
{
unsigned long t_err, err = 0;
err = ERR_get_error();
if(err == 0)
return 0;
while((t_err = ERR_get_error()) > 0)
err = t_err;
return err;
}
void
rb_ssl_shutdown(rb_fde_t * F)
{
int i;
if(F == NULL || F->ssl == NULL)
return;
SSL_set_shutdown((SSL *) F->ssl, SSL_RECEIVED_SHUTDOWN);
for (i = 0; i < 4; i++)
{
if(SSL_shutdown((SSL *) F->ssl))
break;
}
get_last_err();
SSL_free((SSL *) F->ssl);
}
static void
rb_ssl_timeout(rb_fde_t * fd, void *notused)
{
rb_close(fd);
}
static void
rb_ssl_tryaccept(rb_fde_t * F, void *data)
{
int ssl_err;
lrb_assert(F->accept != NULL);
if(!SSL_is_init_finished((SSL *) F->ssl))
{
if((ssl_err = SSL_accept((SSL *) F->ssl)) <= 0)
{
switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err))
{
case SSL_ERROR_SYSCALL:
if(rb_ignore_errno(errno))
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
{
F->ssl_errno = get_last_err();
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE,
rb_ssl_tryaccept, NULL);
return;
}
default:
F->ssl_errno = get_last_err();
F->accept->callback(F, RB_ERROR_SSL, NULL, 0, F->accept->data);
break;
}
return;
}
}
rb_settimeout(F, 0, NULL, NULL);
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL);
F->accept->callback(F, RB_OK, (struct sockaddr *) &F->accept->S, F->accept->addrlen,
F->accept->data);
rb_free(F->accept);
F->accept = NULL;
}
void
rb_ssl_start_accepted(rb_fde_t * new_F, ACCB * cb, void *data, int timeout)
{
int ssl_err;
new_F->type |= RB_FD_SSL;
new_F->ssl = SSL_new(ssl_server_ctx);
new_F->accept = rb_malloc(sizeof(struct acceptdata));
new_F->accept->callback = cb;
new_F->accept->data = data;
rb_settimeout(new_F, timeout, rb_ssl_timeout, NULL);
new_F->accept->addrlen = 0;
SSL_set_fd((SSL *) new_F->ssl, rb_get_fd(new_F));
if((ssl_err = SSL_accept((SSL *) new_F->ssl)) <= 0)
{
switch (ssl_err = SSL_get_error((SSL *) new_F->ssl, ssl_err))
{
case SSL_ERROR_SYSCALL:
if(rb_ignore_errno(errno))
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
{
new_F->ssl_errno = get_last_err();
rb_setselect(new_F, RB_SELECT_READ | RB_SELECT_WRITE,
rb_ssl_tryaccept, NULL);
return;
}
default:
new_F->ssl_errno = get_last_err();
new_F->accept->callback(new_F, RB_ERROR_SSL, NULL, 0, new_F->accept->data);
return;
}
}
else
{
rb_ssl_tryaccept(new_F, NULL);
}
}
void
rb_ssl_accept_setup(rb_fde_t * F, int new_fd, struct sockaddr *st, int addrlen)
{
rb_fde_t *new_F;
int ssl_err;
new_F = rb_find_fd(new_fd);
new_F->type |= RB_FD_SSL;
new_F->ssl = SSL_new(ssl_server_ctx);
new_F->accept = rb_malloc(sizeof(struct acceptdata));
new_F->accept->callback = F->accept->callback;
new_F->accept->data = F->accept->data;
rb_settimeout(new_F, 10, rb_ssl_timeout, NULL);
memcpy(&new_F->accept->S, st, addrlen);
new_F->accept->addrlen = addrlen;
SSL_set_fd((SSL *) new_F->ssl, new_fd);
if((ssl_err = SSL_accept((SSL *) new_F->ssl)) <= 0)
{
switch (ssl_err = SSL_get_error((SSL *) new_F->ssl, ssl_err))
{
case SSL_ERROR_SYSCALL:
if(rb_ignore_errno(errno))
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
{
F->ssl_errno = get_last_err();
rb_setselect(new_F, RB_SELECT_READ | RB_SELECT_WRITE,
rb_ssl_tryaccept, NULL);
return;
}
default:
F->ssl_errno = get_last_err();
F->accept->callback(F, RB_ERROR_SSL, NULL, 0, F->accept->data);
return;
}
}
else
{
rb_ssl_tryaccept(new_F, NULL);
}
}
static ssize_t
rb_ssl_read_or_write(int r_or_w, rb_fde_t * F, void *rbuf, const void *wbuf, size_t count)
{
ssize_t ret;
unsigned long err;
SSL *ssl = F->ssl;
if(r_or_w == 0)
ret = (ssize_t)SSL_read(ssl, rbuf, (int) count);
else
ret = (ssize_t)SSL_write(ssl, wbuf, (int) count);
if(ret < 0)
{
switch (SSL_get_error(ssl, ret))
{
case SSL_ERROR_WANT_READ:
errno = EAGAIN;
return RB_RW_SSL_NEED_READ;
case SSL_ERROR_WANT_WRITE:
errno = EAGAIN;
return RB_RW_SSL_NEED_WRITE;
case SSL_ERROR_ZERO_RETURN:
return 0;
case SSL_ERROR_SYSCALL:
err = get_last_err();
if(err == 0)
{
F->ssl_errno = 0;
return RB_RW_IO_ERROR;
}
break;
default:
err = get_last_err();
break;
}
F->ssl_errno = err;
if(err > 0)
{
errno = EIO; /* not great but... */
return RB_RW_SSL_ERROR;
}
return RB_RW_IO_ERROR;
}
return ret;
}
ssize_t
rb_ssl_read(rb_fde_t * F, void *buf, size_t count)
{
return rb_ssl_read_or_write(0, F, buf, NULL, count);
}
ssize_t
rb_ssl_write(rb_fde_t * F, const void *buf, size_t count)
{
return rb_ssl_read_or_write(1, F, NULL, buf, count);
}
int
rb_init_ssl(void)
{
int ret = 1;
SSL_load_error_strings();
SSL_library_init();
ssl_server_ctx = SSL_CTX_new(SSLv23_server_method());
if(ssl_server_ctx == NULL)
{
rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s",
ERR_error_string(ERR_get_error(), NULL));
ret = 0;
}
/* Disable SSLv2, make the client use our settings */
SSL_CTX_set_options(ssl_server_ctx, SSL_OP_NO_SSLv2 | SSL_OP_CIPHER_SERVER_PREFERENCE);
ssl_client_ctx = SSL_CTX_new(TLSv1_client_method());
if(ssl_client_ctx == NULL)
{
rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL client context: %s",
ERR_error_string(ERR_get_error(), NULL));
ret = 0;
}
return ret;
}
int
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile)
{
FILE *param;
DH *dh;
unsigned long err;
if(cert == NULL)
{
rb_lib_log("rb_setup_ssl_server: No certificate file");
return 0;
}
if(!SSL_CTX_use_certificate_file(ssl_server_ctx, cert, SSL_FILETYPE_PEM))
{
err = ERR_get_error();
rb_lib_log("rb_setup_ssl_server: Error loading certificate file [%s]: %s", cert,
ERR_error_string(err, NULL));
return 0;
}
if(keyfile == NULL)
{
rb_lib_log("rb_setup_ssl_server: No key file");
return 0;
}
if(!SSL_CTX_use_PrivateKey_file(ssl_server_ctx, keyfile, SSL_FILETYPE_PEM))
{
err = ERR_get_error();
rb_lib_log("rb_setup_ssl_server: Error loading keyfile [%s]: %s", keyfile,
ERR_error_string(err, NULL));
return 0;
}
if(dhfile != NULL)
{
/* DH parameters aren't necessary, but they are nice..if they didn't pass one..that is their problem */
param = fopen(dhfile, "r");
if(param != NULL)
{
dh = PEM_read_DHparams(param, NULL, NULL, NULL);
if(dh == NULL)
{
err = ERR_get_error();
rb_lib_log
("rb_setup_ssl_server: Error loading DH params file [%s]: %s",
param, ERR_error_string(err, NULL));
fclose(param);
return 0;
}
SSL_CTX_set_tmp_dh(ssl_server_ctx, dh);
fclose(param);
}
}
return 1;
}
int
rb_ssl_listen(rb_fde_t * F, int backlog)
{
F->type = RB_FD_SOCKET | RB_FD_LISTEN | RB_FD_SSL;
return listen(F->fd, backlog);
}
struct ssl_connect
{
CNCB *callback;
void *data;
int timeout;
};
static void
rb_ssl_connect_realcb(rb_fde_t * F, int status, struct ssl_connect *sconn)
{
F->connect->callback = sconn->callback;
F->connect->data = sconn->data;
rb_free(sconn);
rb_connect_callback(F, status);
}
static void
rb_ssl_tryconn_timeout_cb(rb_fde_t * F, void *data)
{
rb_ssl_connect_realcb(F, RB_ERR_TIMEOUT, data);
}
static void
rb_ssl_tryconn_cb(rb_fde_t * F, void *data)
{
struct ssl_connect *sconn = data;
int ssl_err;
if(!SSL_is_init_finished((SSL *) F->ssl))
{
if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0)
{
switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err))
{
case SSL_ERROR_SYSCALL:
if(rb_ignore_errno(errno))
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
{
F->ssl_errno = get_last_err();
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE,
rb_ssl_tryconn_cb, sconn);
return;
}
default:
F->ssl_errno = get_last_err();
rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
return;
}
}
else
{
rb_ssl_connect_realcb(F, RB_OK, sconn);
}
}
}
static void
rb_ssl_tryconn(rb_fde_t * F, int status, void *data)
{
struct ssl_connect *sconn = data;
int ssl_err;
if(status != RB_OK)
{
rb_ssl_connect_realcb(F, status, sconn);
return;
}
F->type |= RB_FD_SSL;
F->ssl = SSL_new(ssl_client_ctx);
SSL_set_fd((SSL *) F->ssl, F->fd);
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0)
{
switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err))
{
case SSL_ERROR_SYSCALL:
if(rb_ignore_errno(errno))
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
{
F->ssl_errno = get_last_err();
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE,
rb_ssl_tryconn_cb, sconn);
return;
}
default:
F->ssl_errno = get_last_err();
rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
return;
}
}
else
{
rb_ssl_connect_realcb(F, RB_OK, sconn);
}
}
void
rb_connect_tcp_ssl(rb_fde_t * F, struct sockaddr *dest,
struct sockaddr *clocal, int socklen, CNCB * callback, void *data, int timeout)
{
struct ssl_connect *sconn;
if(F == NULL)
return;
sconn = rb_malloc(sizeof(struct ssl_connect));
sconn->data = data;
sconn->callback = callback;
sconn->timeout = timeout;
rb_connect_tcp(F, dest, clocal, socklen, rb_ssl_tryconn, sconn, timeout);
}
void
rb_ssl_start_connected(rb_fde_t * F, CNCB * callback, void *data, int timeout)
{
struct ssl_connect *sconn;
int ssl_err;
if(F == NULL)
return;
sconn = rb_malloc(sizeof(struct ssl_connect));
sconn->data = data;
sconn->callback = callback;
sconn->timeout = timeout;
F->connect = rb_malloc(sizeof(struct conndata));
F->connect->callback = callback;
F->connect->data = data;
F->type |= RB_FD_SSL;
F->ssl = SSL_new(ssl_client_ctx);
SSL_set_fd((SSL *) F->ssl, F->fd);
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0)
{
switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err))
{
case SSL_ERROR_SYSCALL:
if(rb_ignore_errno(errno))
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
{
F->ssl_errno = get_last_err();
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE,
rb_ssl_tryconn_cb, sconn);
return;
}
default:
F->ssl_errno = get_last_err();
rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
return;
}
}
else
{
rb_ssl_connect_realcb(F, RB_OK, sconn);
}
}
int
rb_init_prng(const char *path, prng_seed_t seed_type)
{
if(seed_type == RB_PRNG_DEFAULT)
{
#ifdef WIN32
RAND_screen();
#endif
return RAND_status();
}
if(path == NULL)
return RAND_status();
switch (seed_type)
{
case RB_PRNG_EGD:
if(RAND_egd(path) == -1)
return -1;
break;
case RB_PRNG_FILE:
if(RAND_load_file(path, -1) == -1)
return -1;
break;
#ifdef WIN32
case RB_PRNGWIN32:
RAND_screen();
break;
#endif
default:
return -1;
}
return RAND_status();
}
int
rb_get_random(void *buf, size_t length)
{
if(RAND_status())
{
if(RAND_bytes(buf, length) > 0)
return 1;
}
else
{
if(RAND_pseudo_bytes(buf, length) >= 0)
return 1;
}
return 0;
}
const char *
rb_get_ssl_strerror(rb_fde_t * F)
{
return ERR_error_string(F->ssl_errno, NULL);
}
int
rb_supports_ssl(void)
{
return 1;
}
#endif /* HAVE_OPESSL */

1121
libratbox/src/patricia.c Normal file

File diff suppressed because it is too large Load diff

262
libratbox/src/poll.c Normal file
View file

@ -0,0 +1,262 @@
/*
* ircd-ratbox: A slightly useful ircd.
* s_bsd_poll.c: POSIX poll() compatible network routines.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: poll.c 25038 2008-01-23 16:03:08Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
#if defined(HAVE_POLL) && (HAVE_SYS_POLL_H)
#include <sys/poll.h>
/* I hate linux -- adrian */
#ifndef POLLRDNORM
#define POLLRDNORM POLLIN
#endif
#ifndef POLLWRNORM
#define POLLWRNORM POLLOUT
#endif
struct _pollfd_list
{
struct pollfd *pollfds;
int maxindex; /* highest FD number */
int allocated; /* number of pollfds allocated */
};
typedef struct _pollfd_list pollfd_list_t;
static pollfd_list_t pollfd_list;
int
rb_setup_fd_poll(rb_fde_t * F)
{
return 0;
}
/*
* rb_init_netio
*
* This is a needed exported function which will be called to initialise
* the network loop code.
*/
int
rb_init_netio_poll(void)
{
int fd;
pollfd_list.pollfds = rb_malloc(rb_getmaxconnect() * (sizeof(struct pollfd)));
pollfd_list.allocated = rb_getmaxconnect();
for (fd = 0; fd < rb_getmaxconnect(); fd++)
{
pollfd_list.pollfds[fd].fd = -1;
}
pollfd_list.maxindex = 0;
return 0;
}
static void
resize_pollarray(int fd)
{
if(unlikely(fd >= pollfd_list.allocated))
{
int x, old_value = pollfd_list.allocated;
pollfd_list.allocated += 1024;
pollfd_list.pollfds =
rb_realloc(pollfd_list.pollfds,
pollfd_list.allocated * (sizeof(struct pollfd)));
memset(&pollfd_list.pollfds[old_value + 1], 0, sizeof(struct pollfd) * 1024);
for (x = old_value + 1; x < pollfd_list.allocated; x++)
{
pollfd_list.pollfds[x].fd = -1;
}
}
}
/*
* rb_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
rb_setselect_poll(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
{
if(F == NULL)
return;
if(type & RB_SELECT_READ)
{
F->read_handler = handler;
F->read_data = client_data;
if(handler != NULL)
F->pflags |= POLLRDNORM;
else
F->pflags &= ~POLLRDNORM;
}
if(type & RB_SELECT_WRITE)
{
F->write_handler = handler;
F->write_data = client_data;
if(handler != NULL)
F->pflags |= POLLWRNORM;
else
F->pflags &= ~POLLWRNORM;
}
resize_pollarray(F->fd);
if(F->pflags <= 0)
{
pollfd_list.pollfds[F->fd].events = 0;
pollfd_list.pollfds[F->fd].fd = -1;
if(F->fd == pollfd_list.maxindex)
{
while (pollfd_list.maxindex >= 0
&& pollfd_list.pollfds[pollfd_list.maxindex].fd == -1)
pollfd_list.maxindex--;
}
}
else
{
pollfd_list.pollfds[F->fd].events = F->pflags;
pollfd_list.pollfds[F->fd].fd = F->fd;
if(F->fd > pollfd_list.maxindex)
pollfd_list.maxindex = F->fd;
}
}
/* int rb_select(unsigned long delay)
* Input: The maximum time to delay.
* Output: Returns -1 on error, 0 on success.
* Side-effects: Deregisters future interest in IO and calls the handlers
* if an event occurs for an FD.
* Comments: Check all connections for new connections and input data
* that is to be processed. Also check for connections with data queued
* and whether we can write it out.
* 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
* rb_setselect and fd_table[] and calls callbacks for IO ready
* events.
*/
int
rb_select_poll(long delay)
{
int num;
int fd;
int ci;
PF *hdl;
void *data;
struct pollfd *pfd;
int revents;
num = poll(pollfd_list.pollfds, pollfd_list.maxindex + 1, delay);
rb_set_time();
if(num < 0)
{
if(!rb_ignore_errno(errno))
return RB_OK;
else
return RB_ERROR;
}
if(num == 0)
return RB_OK;
/* XXX we *could* optimise by falling out after doing num fds ... */
for (ci = 0; ci < pollfd_list.maxindex + 1; ci++)
{
rb_fde_t *F;
pfd = &pollfd_list.pollfds[ci];
revents = pfd->revents;
fd = pfd->fd;
if(revents == 0 || fd == -1)
continue;
F = rb_find_fd(fd);
if(F == NULL)
continue;
if(revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
{
hdl = F->read_handler;
data = F->read_data;
F->read_handler = NULL;
F->read_data = NULL;
if(hdl)
hdl(F, data);
}
if(IsFDOpen(F) && (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)))
{
hdl = F->write_handler;
data = F->write_data;
F->write_handler = NULL;
F->write_data = NULL;
if(hdl)
hdl(F, data);
}
if(F->read_handler == NULL)
rb_setselect_poll(F, RB_SELECT_READ, NULL, NULL);
if(F->write_handler == NULL)
rb_setselect_poll(F, RB_SELECT_WRITE, NULL, NULL);
}
return 0;
}
#else /* poll not supported */
int
rb_init_netio_poll(void)
{
errno = ENOSYS;
return -1;
}
void
rb_setselect_poll(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
{
errno = ENOSYS;
return;
}
int
rb_select_poll(long delay)
{
errno = ENOSYS;
return -1;
}
int
rb_setup_fd_poll(rb_fde_t * F)
{
errno = ENOSYS;
return -1;
}
#endif

193
libratbox/src/ports.c Normal file
View file

@ -0,0 +1,193 @@
/*
* ircd-ratbox: A slightly useful ircd.
* ports.c: Solaris ports compatible network routines.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
* Copyright (C) 2002-2004 ircd-ratbox development team
* Copyright (C) 2005 Edward Brocklesby.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: ports.c 25038 2008-01-23 16:03:08Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
#if defined(HAVE_PORT_H) && (HAVE_PORT_CREATE)
#include <port.h>
#define PE_LENGTH 128
static void pe_update_events(rb_fde_t *, short, PF *);
static int pe;
static struct timespec zero_timespec;
static port_event_t *pelst; /* port buffer */
static int pemax; /* max structs to buffer */
int
rb_setup_fd_ports(int fd)
{
return 0;
}
static void
pe_update_events(rb_fde_t * F, short filter, PF * handler)
{
PF *cur_handler = NULL;
if (filter == POLLRDNORM)
cur_handler = F->read_handler;
else if (filter == POLLWRNORM)
cur_handler = F->write_handler;
if (!cur_handler && handler)
port_associate(pe, PORT_SOURCE_FD, F->fd, filter, F);
else if (cur_handler && !handler)
port_dissociate(pe, PORT_SOURCE_FD, F->fd);
}
/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
/* Public functions */
/*
* rb_init_netio
*
* This is a needed exported function which will be called to initialise
* the network loop code.
*/
int
rb_init_netio_ports(void)
{
if((pe = port_create()) < 0) {
return errno;
}
pemax = getdtablesize();
pelst = rb_malloc(sizeof(port_event_t) * pemax);
zero_timespec.tv_sec = 0;
zero_timespec.tv_nsec = 0;
}
/*
* rb_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
rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler,
void *client_data)
{
lrb_assert(IsFDOpen(F));
/* Update the list, even though we're not using it .. */
if(type & RB_SELECT_READ) {
pe_update_events(F, POLLRDNORM, handler);
F->read_handler = handler;
F->read_data = client_data;
}
if(type & RB_SELECT_WRITE) {
pe_update_events(F, POLLWRNORM, handler);
F->write_handler = handler;
F->write_data = client_data;
}
}
/*
* rb_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
* rb_setselect and fd_table[] and calls callbacks for IO ready
* events.
*/
int
rb_select_ports(long delay)
{
int i, fd;
uint nget = 1;
struct timespec poll_time;
struct timer_data *tdata;
poll_time.tv_sec = delay / 1000;
poll_time.tv_nsec = (delay % 1000) * 1000000;
i = port_getn(pe, pelst, pemax, &nget, &poll_time);
rb_set_time();
if (i == -1)
return RB_OK;
for (i = 0; i < nget; i++) {
switch(pelst[i].portev_source) {
case PORT_SOURCE_FD:
fd = pelst[i].portev_object;
PF *hdl = NULL;
rb_fde_t *F = rb_find_fd(fd);
if ((pelst[i].portev_events & POLLRDNORM) && (hdl = F->read_handler)) {
F->read_handler = NULL;
hdl(F, F->read_data);
}
if ((pelst[i].portev_events & POLLWRNORM) && (hdl = F->write_handler)) {
F->write_handler = NULL;
hdl(F, F->write_data);
}
break;
}
}
return RB_OK;
}
#else /* ports not supported */
int
rb_init_netio_ports(void)
{
return ENOSYS;
}
void
rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler, void *client_data)
{
errno = ENOSYS;
return;
}
int
rb_select_ports(long delay)
{
errno = ENOSYS;
return -1;
}
int
rb_setup_fd_ports(rb_fde_t *F)
{
errno = ENOSYS;
return -1;
}
#endif

406
libratbox/src/ratbox_lib.c Normal file
View file

@ -0,0 +1,406 @@
/*
* ircd-ratbox: A slightly useful ircd.
* ratbox_lib.c: libircd initialization functions at the like
*
* Copyright (C) 2005,2006 ircd-ratbox development team
* Copyright (C) 2005,2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: ratbox_lib.c 25038 2008-01-23 16:03:08Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
static log_cb *rb_log;
static restart_cb *rb_restart;
static die_cb *rb_die;
static struct timeval rb_time;
static char errbuf[512];
/* this doesn't do locales...oh well i guess */
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"
};
static const char *s_month[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
"Aug", "Sep", "Oct", "Nov", "Dec"
};
static const char *s_weekdays[] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
char *
rb_ctime(const time_t t, char *buf, size_t len)
{
char *p;
struct tm *tp;
static char timex[128];
size_t tlen;
#if defined(HAVE_GMTIME_R)
struct tm tmr;
tp = gmtime_r(&t, &tmr);
#else
tp = gmtime(&t);
#endif
if(unlikely(tp == NULL))
{
strcpy(buf, "");
return(buf);
}
if(buf == NULL)
{
p = timex;
tlen = sizeof(timex);
} else {
p = buf;
tlen = len;
}
rb_snprintf(p, tlen, "%s %s %d %02u:%02u:%02u %d",
s_weekdays[tp->tm_wday], s_month[tp->tm_mon],
tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec,
tp->tm_year + 1900);
return(p);
}
/* I hate this..but its sort of ircd standard now.. */
char *
rb_date(const time_t t, char *buf, size_t len)
{
struct tm *gm;
#if defined(HAVE_GMTIME_R)
struct tm gmbuf;
gm = gmtime_r(&t, &gmbuf);
#else
gm = gmtime(&t);
#endif
if(unlikely(gm == NULL))
{
rb_strlcpy(buf, "", len);
return(buf);
}
rb_snprintf(buf, len, "%s %s %d %d -- %02u:%02u:%02u +00:00",
weekdays[gm->tm_wday], months[gm->tm_mon], gm->tm_mday,
gm->tm_year + 1900, gm->tm_hour, gm->tm_min, gm->tm_sec);
return(buf);
}
time_t
rb_current_time(void)
{
return rb_time.tv_sec;
}
const struct timeval *
rb_current_time_tv(void)
{
return &rb_time;
}
void
rb_lib_log(const char *format, ...)
{
va_list args;
if(rb_log == NULL)
return;
va_start(args, format);
rb_vsnprintf(errbuf, sizeof(errbuf), format, args);
va_end(args);
rb_log(errbuf);
}
void
rb_lib_die(const char *format, ...)
{
va_list args;
if(rb_die == NULL)
abort();
va_start(args, format);
rb_vsnprintf(errbuf, sizeof(errbuf), format, args);
va_end(args);
rb_die(errbuf);
}
void
rb_lib_restart(const char *format, ...)
{
va_list args;
if(rb_restart == NULL)
abort();
va_start(args, format);
rb_vsnprintf(errbuf, sizeof(errbuf), format, args);
va_end(args);
rb_restart(errbuf);
}
void
rb_set_time(void)
{
struct timeval newtime;
if(unlikely(rb_gettimeofday(&newtime, NULL) == -1))
{
rb_lib_log("Clock Failure (%s)", strerror(errno));
rb_lib_restart("Clock Failure");
}
if(newtime.tv_sec < rb_time.tv_sec)
rb_set_back_events(rb_time.tv_sec - newtime.tv_sec);
memcpy(&rb_time, &newtime, sizeof(struct timeval));
}
const char *
rb_lib_version(void)
{
static const char *id = "$Rev: 25038 $";
return id;
}
void
rb_lib_init(log_cb *ilog, restart_cb *irestart, die_cb *idie, int closeall, int maxcon, size_t dh_size, size_t fd_heap_size)
{
rb_set_time();
rb_log = ilog;
rb_restart = irestart;
rb_die = idie;
rb_event_init();
rb_init_bh();
rb_fdlist_init(closeall, maxcon, fd_heap_size);
rb_init_netio();
rb_init_rb_dlink_nodes(dh_size);
if(rb_io_supports_event())
{
rb_io_init_event();
}
}
void
rb_lib_loop(long delay)
{
time_t next;
rb_set_time();
if(rb_io_supports_event())
{
if(delay == 0)
delay = -1;
while(1)
rb_select(-1);
}
while(1)
{
if(delay == 0)
{
if((next = rb_event_next()) > 0)
{
next -= rb_current_time();
if(next <= 0)
next = 1000;
else
next *= 1000;
}
else
next = -1;
rb_select(next);
} else
rb_select(delay);
rb_event_run();
}
}
#ifndef HAVE_STRTOK_R
char *
rb_strtok_r (char *s, const char *delim, char **save)
{
char *token;
if (s == NULL)
s = *save;
/* Scan leading delimiters. */
s += strspn(s, delim);
if (*s == '\0')
{
*save = s;
return NULL;
}
token = s;
s = strpbrk(token, delim);
if (s == NULL)
*save = (token + strlen(token));
else
{
*s = '\0';
*save = s + 1;
}
return token;
}
#else
char
*rb_strtok_r(char *s, const char *delim, char **save)
{
return strtok_r(s, delim, save);
}
#endif
static const char base64_table[] =
{ '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',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
};
static const char base64_pad = '=';
static const short base64_reverse_table[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 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, -1, -1, -1, -1, -1,
-1, 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, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
unsigned char *
rb_base64_encode(const unsigned char *str, int length)
{
const unsigned char *current = str;
unsigned char *p;
unsigned char *result;
if ((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) {
return NULL;
}
result = rb_malloc(((length + 2) / 3) * 5);
p = result;
while (length > 2)
{
*p++ = base64_table[current[0] >> 2];
*p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
*p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
*p++ = base64_table[current[2] & 0x3f];
current += 3;
length -= 3;
}
if (length != 0) {
*p++ = base64_table[current[0] >> 2];
if (length > 1) {
*p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
*p++ = base64_table[(current[1] & 0x0f) << 2];
*p++ = base64_pad;
} else {
*p++ = base64_table[(current[0] & 0x03) << 4];
*p++ = base64_pad;
*p++ = base64_pad;
}
}
*p = '\0';
return result;
}
unsigned char *
rb_base64_decode(const unsigned char *str, int length, int *ret)
{
const unsigned char *current = str;
int ch, i = 0, j = 0, k;
unsigned char *result;
result = rb_malloc(length + 1);
while ((ch = *current++) != '\0' && length-- > 0) {
if (ch == base64_pad) break;
ch = base64_reverse_table[ch];
if (ch < 0) continue;
switch(i % 4) {
case 0:
result[j] = ch << 2;
break;
case 1:
result[j++] |= ch >> 4;
result[j] = (ch & 0x0f) << 4;
break;
case 2:
result[j++] |= ch >>2;
result[j] = (ch & 0x03) << 6;
break;
case 3:
result[j++] |= ch;
break;
}
i++;
}
k = j;
if (ch == base64_pad) {
switch(i % 4) {
case 1:
free(result);
return NULL;
case 2:
k++;
case 3:
result[k++] = 0;
}
}
result[j] = '\0';
*ret = j;
return result;
}

302
libratbox/src/rawbuf.c Normal file
View file

@ -0,0 +1,302 @@
/*
* ircd-ratbox: A slight useful ircd
* rawbuf.c: raw buffer (non-line oriented buffering)
*
* Copyright (C) 2007 Aaron Sethman <androsyn@ratbox.org>
* Copyright (C) 2007 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id$
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
#define RAWBUF_SIZE 1024
struct _rawbuf
{
rb_dlink_node node;
rb_uint8_t data[RAWBUF_SIZE];
int len;
rb_uint8_t flushing;
};
struct _rawbuf_head
{
rb_dlink_list list;
int len;
int written;
};
static rb_bh *rawbuf_heap;
static rawbuf_t *
rb_rawbuf_alloc(void)
{
rawbuf_t *t;
t = rb_bh_alloc(rawbuf_heap);
return t;
}
static rawbuf_t *
rb_rawbuf_newbuf(rawbuf_head_t * rb)
{
rawbuf_t *buf;
buf = rb_rawbuf_alloc();
rb_dlinkAddTail(buf, &buf->node, &rb->list);
return buf;
}
static void
rb_rawbuf_done(rawbuf_head_t * rb, rawbuf_t * buf)
{
rawbuf_t *ptr = buf;
rb_dlinkDelete(&buf->node, &rb->list);
rb_bh_free(rawbuf_heap, ptr);
}
static int
rb_rawbuf_flush_writev(rawbuf_head_t * rb, rb_fde_t *F)
{
rb_dlink_node *ptr, *next;
rawbuf_t *buf;
int x = 0, y = 0;
int xret, retval;
struct rb_iovec vec[RB_UIO_MAXIOV];
memset(vec, 0, sizeof(vec));
if(rb->list.head == NULL)
{
errno = EAGAIN;
return -1;
}
RB_DLINK_FOREACH(ptr, rb->list.head)
{
if(x >= RB_UIO_MAXIOV)
break;
buf = ptr->data;
if(buf->flushing)
{
vec[x].iov_base = buf->data + rb->written;
vec[x++].iov_len = buf->len - rb->written;
continue;
}
vec[x].iov_base = buf->data;
vec[x++].iov_len = buf->len;
}
if(x == 0)
{
errno = EAGAIN;
return -1;
}
xret = retval = rb_writev(F, vec, x);
if(retval <= 0)
return retval;
RB_DLINK_FOREACH_SAFE(ptr, next, rb->list.head)
{
buf = ptr->data;
if(y++ >= x)
break;
if(buf->flushing)
{
if(xret >= buf->len - rb->written)
{
xret -= buf->len - rb->written;
rb->len -= buf->len - rb->written;
rb_rawbuf_done(rb, buf);
continue;
}
}
if(xret >= buf->len)
{
xret -= buf->len;
rb->len -= buf->len;
rb_rawbuf_done(rb, buf);
}
else
{
buf->flushing = 1;
rb->written = xret;
rb->len -= xret;
break;
}
}
return retval;
}
int
rb_rawbuf_flush(rawbuf_head_t * rb, rb_fde_t *F)
{
rawbuf_t *buf;
int retval;
if(rb->list.head == NULL)
{
errno = EAGAIN;
return -1;
}
if(!rb_fd_ssl(F))
return rb_rawbuf_flush_writev(rb, F);
buf = rb->list.head->data;
if(!buf->flushing)
{
buf->flushing = 1;
rb->written = 0;
}
retval = rb_write(F, buf->data + rb->written, buf->len - rb->written);
if(retval <= 0)
return retval;
rb->written += retval;
if(rb->written == buf->len)
{
rb->written = 0;
rb_dlinkDelete(&buf->node, &rb->list);
rb_bh_free(rawbuf_heap, buf);
}
rb->len -= retval;
lrb_assert(rb->len >= 0);
return retval;
}
void
rb_rawbuf_append(rawbuf_head_t * rb, void *data, int len)
{
rawbuf_t *buf = NULL;
int clen;
void *ptr;
if(rb->list.tail != NULL)
buf = rb->list.tail->data;
if(buf != NULL && buf->len < RAWBUF_SIZE && !buf->flushing)
{
buf = (rawbuf_t *) rb->list.tail->data;
clen = RAWBUF_SIZE - buf->len;
ptr = (void *) (buf->data + buf->len);
if(len < clen)
clen = len;
memcpy(ptr, data, clen);
buf->len += clen;
rb->len += clen;
len -= clen;
if(len == 0)
return;
data += clen;
}
while (len > 0)
{
buf = rb_rawbuf_newbuf(rb);
if(len >= RAWBUF_SIZE)
clen = RAWBUF_SIZE;
else
clen = len;
memcpy(buf->data, data, clen);
buf->len += clen;
len -= clen;
data += clen;
rb->len += clen;
}
}
int
rb_rawbuf_get(rawbuf_head_t * rb, void *data, int len)
{
rawbuf_t *buf;
int cpylen;
void *ptr;
if(rb->list.head == NULL)
return 0;
buf = rb->list.head->data;
if(buf->flushing)
ptr = (void *) (buf->data + rb->written);
else
ptr = buf->data;
if(len > buf->len)
cpylen = buf->len;
else
cpylen = len;
memcpy(data, ptr, cpylen);
if(cpylen == buf->len)
{
rb->written = 0;
rb_rawbuf_done(rb, buf);
rb->len -= len;
return cpylen;
}
buf->flushing = 1;
buf->len -= cpylen;
rb->len -= cpylen;
rb->written += cpylen;
return cpylen;
}
int
rb_rawbuf_length(rawbuf_head_t * rb)
{
if(rb_dlink_list_length(&rb->list) == 0 && rb->len != 0)
lrb_assert(1 == 0);
return rb->len;
}
rawbuf_head_t *
rb_new_rawbuffer(void)
{
return rb_malloc(sizeof(rawbuf_head_t));
}
void
rb_free_rawbuffer(rawbuf_head_t * rb)
{
rb_dlink_node *ptr, *next;
RB_DLINK_FOREACH_SAFE(ptr, next, rb->list.head)
{
rb_rawbuf_done(rb, ptr->data);
}
rb_free(rb);
}
void
rb_init_rawbuffers(int heap_size)
{
if(rawbuf_heap == NULL)
rawbuf_heap = rb_bh_create(sizeof(rawbuf_t), heap_size, "librb_rawbuf_heap");
}

42
libratbox/src/rb_memory.c Normal file
View file

@ -0,0 +1,42 @@
/*
* ircd-ratbox: A slightly useful ircd.
* memory.c: Memory utilities.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: rb_memory.c 25038 2008-01-23 16:03:08Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
void
rb_outofmemory(void)
{
static int was_here = 0;
if(was_here)
abort();
was_here = 1;
rb_lib_log("Out of memory: restarting server...");
rb_lib_restart("Out of Memory");
}

264
libratbox/src/select.c Normal file
View file

@ -0,0 +1,264 @@
/*
* ircd-ratbox: A slightly useful ircd.
* select.c: select() compatible network routines.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: select.c 25038 2008-01-23 16:03:08Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
#if defined(HAVE_SELECT)
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
/*
* 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;
static fd_set select_writefds;
/*
* You know, I'd rather have these local to rb_select but for some
* reason my gcc decides that I can't modify them at all..
* -- adrian
*/
static fd_set tmpreadfds;
static fd_set tmpwritefds;
static int rb_maxfd = -1;
static void select_update_selectfds(rb_fde_t *F, short event, PF * handler);
/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
/* Private functions */
/*
* set and clear entries in the select array ..
*/
static void
select_update_selectfds(rb_fde_t *F, short event, PF * handler)
{
/* Update the read / write set */
if(event & RB_SELECT_READ)
{
if(handler)
{
FD_SET(F->fd, &select_readfds);
F->pflags |= RB_SELECT_READ;
}
else
{
FD_CLR(F->fd, &select_readfds);
F->pflags &= ~RB_SELECT_READ;
}
}
if(event & RB_SELECT_WRITE)
{
if(handler)
{
FD_SET(F->fd, &select_writefds);
F->pflags |= RB_SELECT_WRITE;
}
else
{
FD_CLR(F->fd, &select_writefds);
F->pflags &= ~RB_SELECT_WRITE;
}
}
if(F->pflags & (RB_SELECT_READ|RB_SELECT_WRITE))
{
if(F->fd > rb_maxfd)
{
rb_maxfd = F->fd;
}
}
else if(F->fd <= rb_maxfd)
{
while(rb_maxfd >= 0 && !FD_ISSET(rb_maxfd, &select_readfds) && !FD_ISSET(rb_maxfd, &select_writefds))
rb_maxfd--;
}
}
/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
/* Public functions */
int
rb_setup_fd_select(rb_fde_t *F)
{
return 0;
}
/*
* rb_init_netio
*
* This is a needed exported function which will be called to initialise
* the network loop code.
*/
int
rb_init_netio_select(void)
{
FD_ZERO(&select_readfds);
FD_ZERO(&select_writefds);
return 0;
}
/*
* rb_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
rb_setselect_select(rb_fde_t *F, unsigned int type, PF * handler,
void *client_data)
{
lrb_assert(IsFDOpen(F));
if(type & RB_SELECT_READ)
{
F->read_handler = handler;
F->read_data = client_data;
select_update_selectfds(F, RB_SELECT_READ, handler);
}
if(type & RB_SELECT_WRITE)
{
F->write_handler = handler;
F->write_data = client_data;
select_update_selectfds(F, RB_SELECT_WRITE, handler);
}
}
/*
* Check all connections for new connections and input data that is to be
* processed. Also check for connections with data queued and whether we can
* write it out.
*/
/*
* rb_select
*
* Do IO events
*/
int
rb_select_select(long delay)
{
int num;
int fd;
PF *hdl;
rb_fde_t *F;
struct timeval to;
/* 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));
for (;;)
{
to.tv_sec = 0;
to.tv_usec = delay * 1000;
num = select(rb_maxfd + 1, &tmpreadfds, &tmpwritefds, NULL, &to);
if(num >= 0)
break;
if(rb_ignore_errno(errno))
continue;
rb_set_time();
/* error! */
return -1;
/* NOTREACHED */
}
rb_set_time();
if(num == 0)
return 0;
/* XXX we *could* optimise by falling out after doing num fds ... */
for (fd = 0; fd < rb_maxfd + 1; fd++)
{
F = rb_find_fd(fd);
if(F == NULL)
continue;
if(FD_ISSET(fd, &tmpreadfds))
{
hdl = F->read_handler;
F->read_handler = NULL;
if(hdl)
hdl(F, F->read_data);
}
if(!IsFDOpen(F))
continue; /* Read handler closed us..go on */
if(FD_ISSET(fd, &tmpwritefds))
{
hdl = F->write_handler;
F->write_handler = NULL;
if(hdl)
hdl(F, F->write_data);
}
if(F->read_handler == NULL)
select_update_selectfds(F, RB_SELECT_READ, NULL);
if(F->write_handler == NULL)
select_update_selectfds(F, RB_SELECT_WRITE, NULL);
}
return 0;
}
#else /* select not supported..what sort of garbage is this? */
int
rb_init_netio_select(void)
{
return ENOSYS;
}
void
rb_setselect_select(rb_fde_t *F, unsigned int type, PF * handler, void *client_data)
{
errno = ENOSYS;
return;
}
int
rb_select_select(long delay)
{
errno = ENOSYS;
return -1;
}
int
rb_setup_fd_select(rb_fde_t *F)
{
errno = ENOSYS;
return -1;
}
#endif

509
libratbox/src/sigio.c Normal file
View file

@ -0,0 +1,509 @@
/*
* ircd-ratbox: A slightly useful ircd.
* sigio.c: Linux Realtime SIGIO compatible network routines.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
* Copyright (C) 2002 Aaron Sethman <androsyn@ratbox.org>
* Copyright (C) 2002 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: sigio.c 25038 2008-01-23 16:03:08Z androsyn $
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1 /* Needed for F_SETSIG */
#endif
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
#include <event-int.h>
#include <fcntl.h> /* Yes this needs to be before the ifdef */
#if defined(HAVE_SYS_POLL_H) && (HAVE_POLL) && (F_SETSIG)
#define USING_SIGIO
#endif
#ifdef USING_SIGIO
#include <signal.h>
#include <sys/poll.h>
#if defined(USE_TIMER_CREATE)
#define SIGIO_SCHED_EVENT 1
#endif
#define RTSIGIO SIGRTMIN
#define RTSIGTIM (SIGRTMIN+1)
struct _pollfd_list
{
struct pollfd *pollfds;
int maxindex; /* highest FD number */
int allocated;
};
typedef struct _pollfd_list pollfd_list_t;
pollfd_list_t pollfd_list;
static int can_do_event = 0;
static int sigio_is_screwed = 0; /* We overflowed our sigio queue */
static sigset_t our_sigset;
/*
* rb_init_netio
*
* This is a needed exported function which will be called to initialise
* the network loop code.
*/
int
rb_init_netio_sigio(void)
{
int fd;
pollfd_list.pollfds = rb_malloc(rb_getmaxconnect() * (sizeof(struct pollfd)));
pollfd_list.allocated = rb_getmaxconnect();
for (fd = 0; fd < rb_getmaxconnect(); fd++)
{
pollfd_list.pollfds[fd].fd = -1;
}
pollfd_list.maxindex = 0;
sigio_is_screwed = 1; /* Start off with poll first.. */
sigemptyset(&our_sigset);
sigaddset(&our_sigset, RTSIGIO);
sigaddset(&our_sigset, SIGIO);
#ifdef SIGIO_SCHED_EVENT
sigaddset(&our_sigset, RTSIGTIM);
#endif
sigprocmask(SIG_BLOCK, &our_sigset, NULL);
return 0;
}
static inline void
resize_pollarray(int fd)
{
if(unlikely(fd >= pollfd_list.allocated))
{
int x, old_value = pollfd_list.allocated;
pollfd_list.allocated += 1024;
pollfd_list.pollfds =
rb_realloc(pollfd_list.pollfds,
pollfd_list.allocated * (sizeof(struct pollfd)));
memset(&pollfd_list.pollfds[old_value + 1], 0, sizeof(struct pollfd) * 1024);
for (x = old_value + 1; x < pollfd_list.allocated; x++)
{
pollfd_list.pollfds[x].fd = -1;
}
}
}
/*
* void setup_sigio_fd(int fd)
*
* Input: File descriptor
* Output: None
* Side Effect: Sets the FD up for SIGIO
*/
int
rb_setup_fd_sigio(rb_fde_t * F)
{
int flags = 0;
int fd = F->fd;
flags = fcntl(fd, F_GETFL, 0);
if(flags == -1)
return 0;
/* if set async, clear it so we can reset it in the kernel :/ */
if(flags & O_ASYNC)
{
flags &= ~O_ASYNC;
fcntl(fd, F_SETFL, flags);
}
flags |= O_ASYNC | O_NONBLOCK;
if(fcntl(fd, F_SETFL, flags) == -1)
return 0;
if(fcntl(fd, F_SETSIG, RTSIGIO) == -1)
return 0;
if(fcntl(fd, F_SETOWN, getpid()) == -1)
return 0;
return 1;
}
/*
* rb_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
rb_setselect_sigio(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
{
if(F == NULL)
return;
if(type & RB_SELECT_READ)
{
F->read_handler = handler;
F->read_data = client_data;
if(handler != NULL)
F->pflags |= POLLRDNORM;
else
F->pflags &= ~POLLRDNORM;
}
if(type & RB_SELECT_WRITE)
{
F->write_handler = handler;
F->write_data = client_data;
if(handler != NULL)
F->pflags |= POLLWRNORM;
else
F->pflags &= ~POLLWRNORM;
}
resize_pollarray(F->fd);
if(F->pflags <= 0)
{
pollfd_list.pollfds[F->fd].events = 0;
pollfd_list.pollfds[F->fd].fd = -1;
if(F->fd == pollfd_list.maxindex)
{
while (pollfd_list.maxindex >= 0
&& pollfd_list.pollfds[pollfd_list.maxindex].fd == -1)
pollfd_list.maxindex--;
}
}
else
{
pollfd_list.pollfds[F->fd].events = F->pflags;
pollfd_list.pollfds[F->fd].fd = F->fd;
if(F->fd > pollfd_list.maxindex)
pollfd_list.maxindex = F->fd;
}
}
/* int rb_select(long delay)
* Input: The maximum time to delay.
* Output: Returns -1 on error, 0 on success.
* Side-effects: Deregisters future interest in IO and calls the handlers
* if an event occurs for an FD.
* Comments: Check all connections for new connections and input data
* that is to be processed. Also check for connections with data queued
* and whether we can write it out.
* 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
* rb_setselect and fd_table[] and calls callbacks for IO ready
* events.
*/
int
rb_select_sigio(long delay)
{
int num = 0;
int revents = 0;
int sig;
int fd;
int ci;
PF *hdl;
rb_fde_t *F;
void *data;
struct siginfo si;
struct timespec timeout;
if(rb_sigio_supports_event() || delay >= 0)
{
timeout.tv_sec = (delay / 1000);
timeout.tv_nsec = (delay % 1000) * 1000000;
}
for (;;)
{
if(!sigio_is_screwed)
{
if(can_do_event || delay < 0)
{
sig = sigwaitinfo(&our_sigset, &si);
}
else
sig = sigtimedwait(&our_sigset, &si, &timeout);
if(sig > 0)
{
if(sig == SIGIO)
{
rb_lib_log
("Kernel RT Signal queue overflowed. Is ulimit -i too small(or perhaps /proc/sys/kernel/rtsig-max on old kernels)");
sigio_is_screwed = 1;
break;
}
#ifdef SIGIO_SCHED_EVENT
if(sig == RTSIGTIM && can_do_event)
{
struct ev_entry *ev = (struct ev_entry *) si.si_ptr;
if(ev == NULL)
continue;
rb_run_event(ev);
continue;
}
#endif
fd = si.si_fd;
pollfd_list.pollfds[fd].revents |= si.si_band;
revents = pollfd_list.pollfds[fd].revents;
num++;
F = rb_find_fd(fd);
if(F == NULL)
continue;
if(revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
{
hdl = F->read_handler;
data = F->read_data;
F->read_handler = NULL;
F->read_data = NULL;
if(hdl)
hdl(F, data);
}
if(revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
{
hdl = F->write_handler;
data = F->write_data;
F->write_handler = NULL;
F->write_data = NULL;
if(hdl)
hdl(F, data);
}
}
else
break;
}
else
break;
}
if(!sigio_is_screwed) /* We don't need to proceed */
{
rb_set_time();
return 0;
}
signal(RTSIGIO, SIG_IGN);
signal(RTSIGIO, SIG_DFL);
sigio_is_screwed = 0;
num = poll(pollfd_list.pollfds, pollfd_list.maxindex + 1, delay);
rb_set_time();
if(num < 0)
{
if(!rb_ignore_errno(errno))
return RB_OK;
else
return RB_ERROR;
}
if(num == 0)
return RB_OK;
/* XXX we *could* optimise by falling out after doing num fds ... */
for (ci = 0; ci < pollfd_list.maxindex + 1; ci++)
{
if(((revents = pollfd_list.pollfds[ci].revents) == 0)
|| (pollfd_list.pollfds[ci].fd) == -1)
continue;
fd = pollfd_list.pollfds[ci].fd;
F = rb_find_fd(fd);
if(F == NULL)
continue;
if(revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
{
hdl = F->read_handler;
data = F->read_data;
F->read_handler = NULL;
F->read_data = NULL;
if(hdl)
hdl(F, data);
}
if(IsFDOpen(F) && (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)))
{
hdl = F->write_handler;
data = F->write_data;
F->write_handler = NULL;
F->write_data = NULL;
if(hdl)
hdl(F, data);
}
if(F->read_handler == NULL)
rb_setselect_sigio(F, RB_SELECT_READ, NULL, NULL);
if(F->write_handler == NULL)
rb_setselect_sigio(F, RB_SELECT_WRITE, NULL, NULL);
}
return 0;
}
#if defined(SIGIO_SCHED_EVENT)
void
rb_sigio_init_event(void)
{
rb_sigio_supports_event();
}
int
rb_sigio_supports_event(void)
{
timer_t timer;
struct sigevent ev;
if(can_do_event == 1)
return 1;
if(can_do_event == -1)
return 0;
ev.sigev_signo = SIGVTALRM;
ev.sigev_notify = SIGEV_SIGNAL;
if(timer_create(CLOCK_REALTIME, &ev, &timer) != 0)
{
can_do_event = -1;
return 0;
}
timer_delete(timer);
can_do_event = 1;
return 1;
}
int
rb_sigio_sched_event(struct ev_entry *event, int when)
{
timer_t *id;
struct sigevent ev;
struct itimerspec ts;
if(can_do_event <= 0)
return 0;
memset(&ev, 0, sizeof(&ev));
event->comm_ptr = rb_malloc(sizeof(timer_t));
id = event->comm_ptr;
ev.sigev_notify = SIGEV_SIGNAL;
ev.sigev_signo = RTSIGTIM;
ev.sigev_value.sival_ptr = event;
if(timer_create(CLOCK_REALTIME, &ev, id) < 0)
{
rb_lib_log("timer_create: %s\n", strerror(errno));
return 0;
}
memset(&ts, 0, sizeof(ts));
ts.it_value.tv_sec = when;
ts.it_value.tv_nsec = 0;
if(event->frequency != 0)
ts.it_interval = ts.it_value;
if(timer_settime(*id, 0, &ts, NULL) < 0)
{
rb_lib_log("timer_settime: %s\n", strerror(errno));
return 0;
}
return 1;
}
void
rb_sigio_unsched_event(struct ev_entry *event)
{
if(can_do_event <= 0)
return;
timer_delete(*((timer_t *) event->comm_ptr));
rb_free(event->comm_ptr);
event->comm_ptr = NULL;
}
#endif /* SIGIO_SCHED_EVENT */
#else
int
rb_init_netio_sigio(void)
{
return ENOSYS;
}
void
rb_setselect_sigio(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
{
errno = ENOSYS;
return;
}
int
rb_select_sigio(long delay)
{
errno = ENOSYS;
return -1;
}
int
rb_setup_fd_sigio(rb_fde_t * F)
{
errno = ENOSYS;
return -1;
}
#endif
#if !defined(USING_SIGIO) || !defined(SIGIO_SCHED_EVENT)
void
rb_sigio_init_event(void)
{
return;
}
int
rb_sigio_sched_event(struct ev_entry *event, int when)
{
errno = ENOSYS;
return -1;
}
void
rb_sigio_unsched_event(struct ev_entry *event)
{
return;
}
int
rb_sigio_supports_event(void)
{
errno = ENOSYS;
return 0;
}
#endif /* !USING_SIGIO || !SIGIO_SCHED_EVENT */

633
libratbox/src/snprintf.c Normal file
View file

@ -0,0 +1,633 @@
/*
* Modified and hacked into libratbox by Aaron Sethman <androsyn@ratbox.org>
* The original headers are below..
* Note that this implementation does not process floating point numbers so
* you will likely need to fall back to using sprintf yourself to do those...
* $Id: snprintf.c 25038 2008-01-23 16:03:08Z androsyn $
*/
/*
* linux/lib/vsprintf.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
/*
* Wirzenius wrote this portably, Torvalds fucked it up :-)
*/
/*
* Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
* - changed to provide snprintf and vsnprintf functions
* So Feb 1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de>
* - scnprintf and vscnprintf
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
static int skip_atoi(const char **s)
{
int i=0;
while (isdigit(**s))
i = i*10 + *((*s)++) - '0';
return i;
}
/* Decimal conversion is by far the most typical, and is used
* for /proc and /sys data. This directly impacts e.g. top performance
* with many processes running. We optimize it for speed
* using code from
* http://www.cs.uiowa.edu/~jones/bcd/decimal.html
* (with permission from the author, Douglas W. Jones). */
/* Formats correctly any integer in [0,99999].
* Outputs from one to five digits depending on input.
* On i386 gcc 4.1.2 -O2: ~250 bytes of code. */
static char* put_dec_trunc(char *buf, unsigned q)
{
unsigned d3, d2, d1, d0;
d1 = (q>>4) & 0xf;
d2 = (q>>8) & 0xf;
d3 = (q>>12);
d0 = 6*(d3 + d2 + d1) + (q & 0xf);
q = (d0 * 0xcd) >> 11;
d0 = d0 - 10*q;
*buf++ = d0 + '0'; /* least significant digit */
d1 = q + 9*d3 + 5*d2 + d1;
if (d1 != 0) {
q = (d1 * 0xcd) >> 11;
d1 = d1 - 10*q;
*buf++ = d1 + '0'; /* next digit */
d2 = q + 2*d2;
if ((d2 != 0) || (d3 != 0)) {
q = (d2 * 0xd) >> 7;
d2 = d2 - 10*q;
*buf++ = d2 + '0'; /* next digit */
d3 = q + 4*d3;
if (d3 != 0) {
q = (d3 * 0xcd) >> 11;
d3 = d3 - 10*q;
*buf++ = d3 + '0'; /* next digit */
if (q != 0)
*buf++ = q + '0'; /* most sign. digit */
}
}
}
return buf;
}
/* Same with if's removed. Always emits five digits */
static char* put_dec_full(char *buf, unsigned q)
{
/* BTW, if q is in [0,9999], 8-bit ints will be enough, */
/* but anyway, gcc produces better code with full-sized ints */
unsigned d3, d2, d1, d0;
d1 = (q>>4) & 0xf;
d2 = (q>>8) & 0xf;
d3 = (q>>12);
/* Possible ways to approx. divide by 10 */
/* gcc -O2 replaces multiply with shifts and adds */
// (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386)
// (x * 0x67) >> 10: 1100111
// (x * 0x34) >> 9: 110100 - same
// (x * 0x1a) >> 8: 11010 - same
// (x * 0x0d) >> 7: 1101 - same, shortest code (on i386)
d0 = 6*(d3 + d2 + d1) + (q & 0xf);
q = (d0 * 0xcd) >> 11;
d0 = d0 - 10*q;
*buf++ = d0 + '0';
d1 = q + 9*d3 + 5*d2 + d1;
q = (d1 * 0xcd) >> 11;
d1 = d1 - 10*q;
*buf++ = d1 + '0';
d2 = q + 2*d2;
q = (d2 * 0xd) >> 7;
d2 = d2 - 10*q;
*buf++ = d2 + '0';
d3 = q + 4*d3;
q = (d3 * 0xcd) >> 11; /* - shorter code */
/* q = (d3 * 0x67) >> 10; - would also work */
d3 = d3 - 10*q;
*buf++ = d3 + '0';
*buf++ = q + '0';
return buf;
}
static char* put_dec(char *buf, unsigned long long int num)
{
while (1) {
unsigned rem;
if (num < 100000)
return put_dec_trunc(buf, num);
rem = num % 100000;
num = num / 100000;
buf = put_dec_full(buf, rem);
}
}
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
#define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
static char *number(char *buf, char *end, unsigned long long int num, int base, int size, int precision, int type)
{
char sign,tmp[66];
const char *digits;
/* we are called with base 8, 10 or 16, only, thus don't need "g..." */
static const char small_digits[] = "0123456789abcdefx"; /* "ghijklmnopqrstuvwxyz"; */
static const char large_digits[] = "0123456789ABCDEFX"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
int need_pfx = ((type & SPECIAL) && base != 10);
int i;
digits = (type & LARGE) ? large_digits : small_digits;
if (type & LEFT)
type &= ~ZEROPAD;
if (base < 2 || base > 36)
return NULL;
sign = 0;
if (type & SIGN) {
if ((signed long long int) num < 0) {
sign = '-';
num = - (signed long long int) num;
size--;
} else if (type & PLUS) {
sign = '+';
size--;
} else if (type & SPACE) {
sign = ' ';
size--;
}
}
if (need_pfx) {
size--;
if (base == 16)
size--;
}
/* generate full string in tmp[], in reverse order */
i = 0;
if (num == 0)
tmp[i++] = '0';
/* Generic code, for any base:
else do {
tmp[i++] = digits[do_div(num,base)];
} while (num != 0);
*/
else if (base != 10) { /* 8 or 16 */
int mask = base - 1;
int shift = 3;
if (base == 16) shift = 4;
do {
tmp[i++] = digits[((unsigned char)num) & mask];
num >>= shift;
} while (num);
} else { /* base 10 */
i = put_dec(tmp, num) - tmp;
}
/* printing 100 using %2d gives "100", not "00" */
if (i > precision)
precision = i;
/* leading space padding */
size -= precision;
if (!(type & (ZEROPAD+LEFT))) {
while(--size >= 0) {
if (buf < end)
*buf = ' ';
++buf;
}
}
/* sign */
if (sign) {
if (buf < end)
*buf = sign;
++buf;
}
/* "0x" / "0" prefix */
if (need_pfx) {
if (buf < end)
*buf = '0';
++buf;
if (base == 16) {
if (buf < end)
*buf = digits[16]; /* for arbitrary base: digits[33]; */
++buf;
}
}
/* zero or space padding */
if (!(type & LEFT)) {
char c = (type & ZEROPAD) ? '0' : ' ';
while (--size >= 0) {
if (buf < end)
*buf = c;
++buf;
}
}
/* hmm even more zero padding? */
while (i <= --precision) {
if (buf < end)
*buf = '0';
++buf;
}
/* actual digits of result */
while (--i >= 0) {
if (buf < end)
*buf = tmp[i];
++buf;
}
/* trailing space padding */
while (--size >= 0) {
if (buf < end)
*buf = ' ';
++buf;
}
return buf;
}
/**
* vsnprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @size: The size of the buffer, including the trailing null space
* @fmt: The format string to use
* @args: Arguments for the format string
*
* The return value is the number of characters which would
* be generated for the given input, excluding the trailing
* '\0', as per ISO C99. If you want to have the exact
* number of characters written into @buf as return value
* (not including the trailing '\0'), use vscnprintf(). If the
* return is greater than or equal to @size, the resulting
* string is truncated.
*
* Call this function if you are already dealing with a va_list.
* You probably want snprintf() instead.
*/
int rb_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
{
int len;
unsigned long long int num;
int i, base;
char *str, *end, c;
const char *s;
int flags; /* flags to number() */
int field_width; /* width of output field */
int precision; /* min. # of digits for integers; max
number of chars for from string */
int qualifier; /* 'h', 'l', or 'L' for integer fields */
/* 'z' support added 23/7/1999 S.H. */
/* 'z' changed to 'Z' --davidm 1/25/99 */
/* 't' added for ptrdiff_t */
/* Reject out-of-range values early. Large positive sizes are
used for unknown buffer sizes. */
if (unlikely((int) size < 0)) {
return 0;
}
str = buf;
end = buf + size;
/* Make sure end is always >= buf */
if (end < buf) {
end = ((void *)-1);
size = end - buf;
}
for (; *fmt ; ++fmt) {
if (*fmt != '%') {
if (str < end)
*str = *fmt;
++str;
continue;
}
/* process flags */
flags = 0;
repeat:
++fmt; /* this also skips first '%' */
switch (*fmt) {
case '-': flags |= LEFT; goto repeat;
case '+': flags |= PLUS; goto repeat;
case ' ': flags |= SPACE; goto repeat;
case '#': flags |= SPECIAL; goto repeat;
case '0': flags |= ZEROPAD; goto repeat;
}
/* get field width */
field_width = -1;
if (isdigit(*fmt))
field_width = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
field_width = va_arg(args, int);
if (field_width < 0) {
field_width = -field_width;
flags |= LEFT;
}
}
/* get the precision */
precision = -1;
if (*fmt == '.') {
++fmt;
if (isdigit(*fmt))
precision = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
precision = va_arg(args, int);
}
if (precision < 0)
precision = 0;
}
/* get the conversion qualifier */
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
*fmt =='Z' || *fmt == 'z' || *fmt == 't') {
qualifier = *fmt;
++fmt;
if (qualifier == 'l' && *fmt == 'l') {
qualifier = 'L';
++fmt;
}
}
/* default base */
base = 10;
switch (*fmt) {
case 'c':
if (!(flags & LEFT)) {
while (--field_width > 0) {
if (str < end)
*str = ' ';
++str;
}
}
c = (unsigned char) va_arg(args, int);
if (str < end)
*str = c;
++str;
while (--field_width > 0) {
if (str < end)
*str = ' ';
++str;
}
continue;
case 's':
s = va_arg(args, char *);
if (s == NULL) {
abort(); /* prefer blowing up vs corrupt data */
}
len = rb_strnlen(s, precision);
if (!(flags & LEFT)) {
while (len < field_width--) {
if (str < end)
*str = ' ';
++str;
}
}
for (i = 0; i < len; ++i) {
if (str < end)
*str = *s;
++str; ++s;
}
while (len < field_width--) {
if (str < end)
*str = ' ';
++str;
}
continue;
case 'p':
if (field_width == -1) {
field_width = 2*sizeof(void *);
flags |= ZEROPAD;
}
str = number(str, end,
(unsigned long) va_arg(args, void *),
16, field_width, precision, flags);
continue;
case 'n':
/* FIXME:
* What does C99 say about the overflow case here? */
if (qualifier == 'l') {
long * ip = va_arg(args, long *);
*ip = (str - buf);
} else if (qualifier == 'Z' || qualifier == 'z') {
size_t * ip = va_arg(args, size_t *);
*ip = (str - buf);
} else {
int * ip = va_arg(args, int *);
*ip = (str - buf);
}
continue;
case '%':
if (str < end)
*str = '%';
++str;
continue;
/* integer number formats - set up the flags and "break" */
case 'o':
base = 8;
break;
case 'X':
flags |= LARGE;
case 'x':
base = 16;
break;
case 'd':
case 'i':
flags |= SIGN;
case 'u':
break;
default:
if (str < end)
*str = '%';
++str;
if (*fmt) {
if (str < end)
*str = *fmt;
++str;
} else {
--fmt;
}
continue;
}
if (qualifier == 'L')
num = va_arg(args, long long int);
else if (qualifier == 'l') {
num = va_arg(args, unsigned long);
if (flags & SIGN)
num = (signed long) num;
} else if (qualifier == 'Z' || qualifier == 'z') {
num = va_arg(args, size_t);
} else if (qualifier == 't') {
num = va_arg(args, ptrdiff_t);
} else if (qualifier == 'h') {
num = (unsigned short) va_arg(args, int);
if (flags & SIGN)
num = (signed short) num;
} else {
num = va_arg(args, unsigned int);
if (flags & SIGN)
num = (signed int) num;
}
str = number(str, end, num, base,
field_width, precision, flags);
}
if (size > 0) {
if (str < end)
*str = '\0';
else
end[-1] = '\0';
}
/* the trailing null byte doesn't count towards the total */
return str-buf;
}
/**
* snprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @size: The size of the buffer, including the trailing null space
* @fmt: The format string to use
* @...: Arguments for the format string
*
* The return value is the number of characters which would be
* generated for the given input, excluding the trailing null,
* as per ISO C99. If the return is greater than or equal to
* @size, the resulting string is truncated.
*/
int rb_snprintf(char * buf, size_t size, const char *fmt, ...)
{
va_list args;
int i;
va_start(args, fmt);
i=rb_vsnprintf(buf,size,fmt,args);
va_end(args);
return i;
}
/**
* vsprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @fmt: The format string to use
* @args: Arguments for the format string
*
* The function returns the number of characters written
* into @buf. Use vsnprintf() or vscnprintf() in order to avoid
* buffer overflows.
*
* Call this function if you are already dealing with a va_list.
* You probably want sprintf() instead.
*/
int rb_vsprintf(char *buf, const char *fmt, va_list args)
{
return rb_vsnprintf(buf, INT_MAX, fmt, args);
}
/**
* sprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @fmt: The format string to use
* @...: Arguments for the format string
*
* The function returns the number of characters written
* into @buf. Use snprintf() or scnprintf() in order to avoid
* buffer overflows.
*/
int rb_sprintf(char * buf, const char *fmt, ...)
{
va_list args;
int i;
va_start(args, fmt);
i=rb_vsnprintf(buf, INT_MAX, fmt, args);
va_end(args);
return i;
}
/*
* rb_vsprintf_append()
* appends sprintf formatted string to the end of the buffer
*/
int
rb_vsprintf_append(char *str, const char *format, va_list ap)
{
size_t x = strlen(str);
return(rb_vsprintf(str+x, format, ap) + x);
}
/*
* rb_sprintf_append()
* appends sprintf formatted string to the end of the buffer
*/
int
rb_sprintf_append(char *str, const char *format, ...)
{
int x;
va_list ap;
va_start(ap, format);
x = rb_vsprintf_append(str, format, ap);
va_end(ap);
return(x);
}
/*
* rb_vsnprintf_append()
* appends sprintf formatted string to the end of the buffer but not
* exceeding len
*/
int
rb_vsnprintf_append(char *str, size_t len, const char *format, va_list ap)
{
size_t x = strlen(str);
return(rb_vsnprintf(str+x, len - x, format, ap) + x);
}
/*
* rb_snprintf_append()
* appends snprintf formatted string to the end of the buffer but not
* exceeding len
*/
int
rb_snprintf_append(char *str, size_t len, const char *format, ...)
{
int x;
va_list ap;
va_start(ap, format);
x = rb_vsnprintf_append(str, len, format, ap);
va_end(ap);
return(x);
}

203
libratbox/src/tools.c Normal file
View file

@ -0,0 +1,203 @@
/*
* ircd-ratbox: A slightly useful ircd.
* tools.c: Various functions needed here and there.
*
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: tools.c 25040 2008-01-23 16:11:34Z androsyn $
*
* Here is the original header:
*
* Useful stuff, ripped from places ..
* adrian chadd <adrian@creative.net.au>
*
* The TOOLS_C define builds versions of the functions in tools.h
* so that they end up in the resulting object files. If its not
* defined, tools.h will build inlined versions of the functions
* on supported compilers
*/
#define _GNU_SOURCE 1
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <rb_tools.h>
/*
* init_rb_dlink_nodes
*
*/
static rb_bh *dnode_heap;
void
rb_init_rb_dlink_nodes(size_t dh_size)
{
dnode_heap = rb_bh_create(sizeof(rb_dlink_node), dh_size, "librb_dnode_heap");
if(dnode_heap == NULL)
rb_outofmemory();
}
/*
* make_rb_dlink_node
*
* inputs - NONE
* output - pointer to new rb_dlink_node
* side effects - NONE
*/
rb_dlink_node *
rb_make_rb_dlink_node(void)
{
return(rb_bh_alloc(dnode_heap));
}
/*
* free_rb_dlink_node
*
* inputs - pointer to rb_dlink_node
* output - NONE
* side effects - free given rb_dlink_node
*/
void
rb_free_rb_dlink_node(rb_dlink_node * ptr)
{
assert(ptr != NULL);
rb_bh_free(dnode_heap, ptr);
}
/* rb_string_to_array()
* Changes a given buffer into an array of parameters.
* Taken from ircd-ratbox.
*
* inputs - string to parse, array to put in
* outputs - number of parameters
*/
int
rb_string_to_array(char *string, char **parv, int maxpara)
{
char *p, *xbuf = string;
int x = 0;
parv[x] = NULL;
if(string == NULL || string[0] == '\0')
return x;
while (*xbuf == ' ') /* skip leading spaces */
xbuf++;
if(*xbuf == '\0') /* ignore all-space args */
return x;
do
{
if(*xbuf == ':') /* Last parameter */
{
xbuf++;
parv[x++] = xbuf;
parv[x] = NULL;
return x;
}
else
{
parv[x++] = xbuf;
parv[x] = NULL;
if((p = strchr(xbuf, ' ')) != NULL)
{
*p++ = '\0';
xbuf = p;
}
else
return x;
}
while (*xbuf == ' ')
xbuf++;
if(*xbuf == '\0')
return x;
}
while (x < maxpara - 1);
if(*p == ':')
p++;
parv[x++] = p;
parv[x] = NULL;
return x;
}
#ifndef HAVE_STRLCAT
size_t
rb_strlcat(char *dest, const char *src, size_t count)
{
size_t dsize = strlen(dest);
size_t len = strlen(src);
size_t res = dsize + len;
dest += dsize;
count -= dsize;
if (len >= count)
len = count-1;
memcpy(dest, src, len);
dest[len] = 0;
return res;
}
#else
size_t
rb_strlcat(char *dest, const char *src, size_t count)
{
return strlcat(dest, src, count);
}
#endif
#ifndef HAVE_STRLCPY
size_t
rb_strlcpy(char *dest, const char *src, size_t size)
{
size_t ret = strlen(src);
if (size) {
size_t len = (ret >= size) ? size-1 : ret;
memcpy(dest, src, len);
dest[len] = '\0';
}
return ret;
}
#else
size_t
rb_strlcpy(char *dest, const char *src, size_t size)
{
return strlcpy(dest, src, size);
}
#endif
#ifndef HAVE_STRNLEN
size_t
rb_strnlen(const char *s, size_t count)
{
const char *sc;
for (sc = s; count-- && *sc != '\0'; ++sc)
;;
return sc - s;
}
#else
size_t
rb_strnlen(const char *s, size_t count)
{
return strnlen(s, count);
}
#endif

102
libratbox/src/unix.c Normal file
View file

@ -0,0 +1,102 @@
/*
* ircd-ratbox: A slightly useful ircd.
* unix.c: various unix type functions
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 2005 ircd-ratbox development team
* Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: unix.c 25038 2008-01-23 16:03:08Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#ifndef WINDOWS
#if defined(HAVE_SPAWN_H) && defined(HAVE_POSIX_SPAWN)
#include <spawn.h>
extern char **environ;
pid_t
rb_spawn_process(const char *path, const char **argv)
{
pid_t pid;
const void *arghack = argv;
posix_spawnattr_t spattr;
posix_spawnattr_init(&spattr);
#ifdef POSIX_SPAWN_USEVFORK
posix_spawnattr_setflags(&spattr, POSIX_SPAWN_USEVFORK);
#endif
if(posix_spawn(&pid, path, NULL, &spattr, arghack, environ))
{
return -1;
}
return pid;
}
#else
pid_t
rb_spawn_process(const char *path, const char **argv)
{
pid_t pid;
if(!(pid = vfork()))
{
execv(path, (const void *)argv); /* make gcc shut up */
_exit(1); /* if we're still here, we're screwed */
}
return(pid);
}
#endif
#ifndef HAVE_GETTIMEOFDAY
int
rb_gettimeofday(struct timeval *tv, void *tz)
{
if(tv == NULL)
{
errno = EFAULT;
return -1;
}
tv->tv_usec = 0;
if(time(&tv->tv_sec) == -1)
return -1;
return 0;
}
#else
int
rb_gettimeofday(struct timeval *tv, void *tz)
{
return(gettimeofday(tv, tz));
}
#endif
void
rb_sleep(unsigned int seconds, unsigned int useconds)
{
#ifdef HAVE_NANOSLEEP
struct timespec tv;
tv.tv_nsec = (useconds * 1000);
tv.tv_sec = seconds;
nanosleep(&tv, NULL);
#else
struct timeval tv;
tv.tv_sec = seconds;
tv.tv_usec = useconds;
select(0, NULL, NULL, NULL, &tv);
#endif
}
#endif /* !WINDOWS */

519
libratbox/src/win32.c Normal file
View file

@ -0,0 +1,519 @@
/*
* ircd-ratbox: A slightly useful ircd.
* win32.c: select() compatible network routines.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
* Copyright (C) 2005-2006 Aaron Sethman <androsyn@ratbox.org>
* Copyright (C) 2002-2006 ircd-ratbox 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: win32.c 25038 2008-01-23 16:03:08Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
#ifdef WIN32
static HWND hwnd;
#define WM_SOCKET WM_USER
/*
* having gettimeofday is nice...
*/
typedef union
{
unsigned __int64 ft_i64;
FILETIME ft_val;
} FT_t;
#ifdef __GNUC__
#define Const64(x) x##LL
#else
#define Const64(x) x##i64
#endif
/* Number of 100 nanosecond units from 1/1/1601 to 1/1/1970 */
#define EPOCH_BIAS Const64(116444736000000000)
pid_t
getpid()
{
return GetCurrentProcessId();
}
int
rb_gettimeofday(struct timeval *tp, void *not_used)
{
FT_t ft;
/* this returns time in 100-nanosecond units (i.e. tens of usecs) */
GetSystemTimeAsFileTime(&ft.ft_val);
/* seconds since epoch */
tp->tv_sec = (long) ((ft.ft_i64 - EPOCH_BIAS) / Const64(10000000));
/* microseconds remaining */
tp->tv_usec = (long) ((ft.ft_i64 / Const64(10)) % Const64(1000000));
return 0;
}
pid_t
rb_spawn_process(const char *path, const char **argv)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
char cmd[MAX_PATH];
memset(&pi, 0, sizeof(pi));
memset(&si, 0, sizeof(si));
rb_strlcpy(cmd, path, sizeof(cmd));
if(CreateProcess(cmd, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) == FALSE)
return -1;
return (pi.dwProcessId);
}
pid_t
waitpid(int pid, int *status, int flags)
{
DWORD timeout = (flags & WNOHANG) ? 0 : INFINITE;
HANDLE hProcess;
DWORD waitcode;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
if(hProcess)
{
waitcode = WaitForSingleObject(hProcess, timeout);
if(waitcode == WAIT_TIMEOUT)
{
CloseHandle(hProcess);
return 0;
}
else if(waitcode == WAIT_OBJECT_0)
{
if(GetExitCodeProcess(hProcess, &waitcode))
{
*status = (int) ((waitcode & 0xff) << 8);
CloseHandle(hProcess);
return pid;
}
}
CloseHandle(hProcess);
}
else
errno = ECHILD;
return -1;
}
int
setenv(const char *name, const char *value, int overwrite)
{
char *buf;
int len;
if(!overwrite)
{
if((buf = getenv(name)) != NULL)
{
if(strlen(buf) > 0)
{
return 0;
}
}
}
if(name == NULL || value == NULL)
return -1;
len = strlen(name) + strlen(value) + 5;
buf = rb_malloc(len);
rb_snprintf(buf, len, "%s=%s", name, value);
len = putenv(buf);
rb_free(buf);
return (len);
}
int
kill(int pid, int sig)
{
HANDLE hProcess;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
int ret = -1;
if(hProcess)
{
switch (sig)
{
case 0:
ret = 0;
break;
default:
if(TerminateProcess(hProcess, sig))
ret = 0;
break;
}
CloseHandle(hProcess);
}
else
errno = EINVAL;
return ret;
}
int
rb_pass_fd_to_process(int fd, pid_t process, rb_fde_t *F)
{
WSAPROTOCOL_INFO info;
WSADuplicateSocket((SOCKET)fd, process, &info);
rb_write(F, &info, sizeof(info));
return 0;
}
static LRESULT CALLBACK
rb_process_events(HWND nhwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
rb_fde_t *F;
PF *hdl;
void *data;
switch (umsg)
{
case WM_SOCKET:
{
F = rb_find_fd(wparam);
if(F != NULL && IsFDOpen(F))
{
switch (WSAGETSELECTEVENT(lparam))
{
case FD_ACCEPT:
case FD_CLOSE:
case FD_READ:
{
if((hdl = F->read_handler) != NULL)
{
F->read_handler = NULL;
data = F->read_data;
F->read_data = NULL;
hdl(F, data);
}
break;
}
case FD_CONNECT:
case FD_WRITE:
{
if((hdl = F->write_handler) != NULL)
{
F->write_handler = NULL;
data = F->write_data;
F->write_data = NULL;
hdl(F, data);
}
}
}
}
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
default:
return DefWindowProc(nhwnd, umsg, wparam, lparam);
}
return 0;
}
int
rb_init_netio_win32(void)
{
/* this muchly sucks, but i'm too lazy to do overlapped i/o, maybe someday... -androsyn */
WNDCLASS wc;
static const char *classname = "ircd-ratbox-class";
wc.style = 0;
wc.lpfnWndProc = (WNDPROC) rb_process_events;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = classname;
wc.hInstance = GetModuleHandle(NULL);
if(!RegisterClass(&wc))
rb_lib_die("cannot register window class");
hwnd = CreateWindow(classname, classname, WS_POPUP, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
(HWND) NULL, (HMENU) NULL, wc.hInstance, NULL);
if(!hwnd)
rb_lib_die("could not create window");
return 0;
}
void
rb_sleep(unsigned int seconds, unsigned int useconds)
{
struct timeval tv;
tv.tv_sec = seconds;
tv.tv_usec = useconds;
select(0, NULL, NULL, NULL, &tv);
}
int
rb_setup_fd_win32(rb_fde_t * F)
{
if(F == NULL)
return 0;
SetHandleInformation((HANDLE) F->fd, HANDLE_FLAG_INHERIT, 0);
switch (F->type)
{
case RB_FD_SOCKET:
{
u_long nonb = 1;
if(ioctlsocket((SOCKET) F->fd, FIONBIO, &nonb) == -1)
{
rb_get_errno();
return 0;
}
return 1;
}
default:
return 1;
}
}
void
rb_setselect_win32(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
{
int old_flags = F->pflags;
lrb_assert(IsFDOpen(F));
/* Update the list, even though we're not using it .. */
if(type & RB_SELECT_READ)
{
if(handler != NULL)
F->pflags |= FD_CLOSE | FD_READ | FD_ACCEPT;
else
F->pflags &= ~(FD_CLOSE | FD_READ | FD_ACCEPT);
F->read_handler = handler;
F->read_data = client_data;
}
if(type & RB_SELECT_WRITE)
{
if(handler != NULL)
F->pflags |= FD_WRITE | FD_CONNECT;
else
F->pflags &= ~(FD_WRITE | FD_CONNECT);
F->write_handler = handler;
F->write_data = client_data;
}
if(old_flags == 0 && F->pflags == 0)
return;
if(F->pflags != old_flags)
{
WSAAsyncSelect(F->fd, hwnd, WM_SOCKET, F->pflags);
}
}
static int has_set_timer = 0;
int
rb_select_win32(long delay)
{
MSG msg;
if(has_set_timer == 0)
{
/* XXX should probably have this handle all the events
* instead of busy looping
*/
SetTimer(hwnd, 0, delay, NULL);
has_set_timer = 1;
}
if(GetMessage(&msg, NULL, 0, 0) == FALSE)
{
rb_lib_die("GetMessage failed..byebye");
}
rb_set_time();
DispatchMessage(&msg);
return RB_OK;
}
#ifdef strerror
#undef strerror
#endif
const char *
wsock_strerror(int error)
{
switch (error)
{
case 0:
return "Success";
case WSAEINTR:
return "Interrupted system call";
case WSAEBADF:
return "Bad file number";
case WSAEACCES:
return "Permission denied";
case WSAEFAULT:
return "Bad address";
case WSAEINVAL:
return "Invalid argument";
case WSAEMFILE:
return "Too many open sockets";
case WSAEWOULDBLOCK:
return "Operation would block";
case WSAEINPROGRESS:
return "Operation now in progress";
case WSAEALREADY:
return "Operation already in progress";
case WSAENOTSOCK:
return "Socket operation on non-socket";
case WSAEDESTADDRREQ:
return "Destination address required";
case WSAEMSGSIZE:
return "Message too long";
case WSAEPROTOTYPE:
return "Protocol wrong type for socket";
case WSAENOPROTOOPT:
return "Bad protocol option";
case WSAEPROTONOSUPPORT:
return "Protocol not supported";
case WSAESOCKTNOSUPPORT:
return "Socket type not supported";
case WSAEOPNOTSUPP:
return "Operation not supported on socket";
case WSAEPFNOSUPPORT:
return "Protocol family not supported";
case WSAEAFNOSUPPORT:
return "Address family not supported";
case WSAEADDRINUSE:
return "Address already in use";
case WSAEADDRNOTAVAIL:
return "Can't assign requested address";
case WSAENETDOWN:
return "Network is down";
case WSAENETUNREACH:
return "Network is unreachable";
case WSAENETRESET:
return "Net connection reset";
case WSAECONNABORTED:
return "Software caused connection abort";
case WSAECONNRESET:
return "Connection reset by peer";
case WSAENOBUFS:
return "No buffer space available";
case WSAEISCONN:
return "Socket is already connected";
case WSAENOTCONN:
return "Socket is not connected";
case WSAESHUTDOWN:
return "Can't send after socket shutdown";
case WSAETOOMANYREFS:
return "Too many references, can't splice";
case WSAETIMEDOUT:
return "Connection timed out";
case WSAECONNREFUSED:
return "Connection refused";
case WSAELOOP:
return "Too many levels of symbolic links";
case WSAENAMETOOLONG:
return "File name too long";
case WSAEHOSTDOWN:
return "Host is down";
case WSAEHOSTUNREACH:
return "No route to host";
case WSAENOTEMPTY:
return "Directory not empty";
case WSAEPROCLIM:
return "Too many processes";
case WSAEUSERS:
return "Too many users";
case WSAEDQUOT:
return "Disc quota exceeded";
case WSAESTALE:
return "Stale NFS file handle";
case WSAEREMOTE:
return "Too many levels of remote in path";
case WSASYSNOTREADY:
return "Network system is unavailable";
case WSAVERNOTSUPPORTED:
return "Winsock version out of range";
case WSANOTINITIALISED:
return "WSAStartup not yet called";
case WSAEDISCON:
return "Graceful shutdown in progress";
case WSAHOST_NOT_FOUND:
return "Host not found";
case WSANO_DATA:
return "No host data of that type was found";
default:
return strerror(error);
}
};
#else /* win32 not supported */
int
rb_init_netio_win32(void)
{
errno = ENOSYS;
return -1;
}
void
rb_setselect_win32(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
{
errno = ENOSYS;
return;
}
int
rb_select_win32(long delay)
{
errno = ENOSYS;
return -1;
}
int
rb_setup_fd_win32(rb_fde_t * F)
{
errno = ENOSYS;
return -1;
}
#endif /* WIN32 */