Pull in libratbox from ircd-ratbox-3.0.0beta1 and integrate into the build system.
This commit is contained in:
parent
b37edd511a
commit
b57f37fb6a
|
@ -46,7 +46,7 @@ CFLAGS = @CFLAGS@
|
||||||
# the system one.
|
# the system one.
|
||||||
#CFLAGS= -DNDEBUG -g -O2 -D"FD_SETSIZE=1024"
|
#CFLAGS= -DNDEBUG -g -O2 -D"FD_SETSIZE=1024"
|
||||||
SHELL=/bin/sh
|
SHELL=/bin/sh
|
||||||
SUBDIRS=modules extensions libcharybdis src tools servlink doc help
|
SUBDIRS=libratbox modules extensions libcharybdis src tools servlink doc help
|
||||||
CLEANDIRS = ${SUBDIRS}
|
CLEANDIRS = ${SUBDIRS}
|
||||||
RSA_FILES=rsa_respond/README rsa_respond/respond.c rsa_respond/Makefile
|
RSA_FILES=rsa_respond/README rsa_respond/respond.c rsa_respond/Makefile
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@ AC_LANG(C)
|
||||||
dnl Make sure autoconf doesn't interfere with cflags -jmallett
|
dnl Make sure autoconf doesn't interfere with cflags -jmallett
|
||||||
CFLAGS="$OLD_CFLAGS"
|
CFLAGS="$OLD_CFLAGS"
|
||||||
|
|
||||||
|
AC_CONFIG_SUBDIRS(libratbox)
|
||||||
|
|
||||||
dnl Check for various compilers. -jmallett
|
dnl Check for various compilers. -jmallett
|
||||||
dnl But if $CC turns out to be gcc, sure as hell it's, well, gcc. -joshk
|
dnl But if $CC turns out to be gcc, sure as hell it's, well, gcc. -joshk
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
-i8 -bli0 -ut -nsai -l100 -npcs
|
|
@ -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.
|
|
@ -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.
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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.
|
|
@ -0,0 +1,3 @@
|
||||||
|
AUTOMAKE_OPTIONS = foreign
|
||||||
|
|
||||||
|
SUBDIRS = src
|
|
@ -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:
|
|
@ -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.
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
1. Make i/o loop engines interchangable at run time.
|
||||||
|
2. Finish TODO list
|
|
@ -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
|
||||||
|
])
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||||
|
|
|
@ -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:
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
|
@ -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__ */
|
|
@ -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:
|
File diff suppressed because it is too large
Load Diff
|
@ -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:
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||||
|
|
|
@ -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 */
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
|
@ -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
|
||||||
|
}
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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 */
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
Loading…
Reference in New Issue