Pull in libratbox from ircd-ratbox-3.0.0beta1 and integrate into the build system.
This commit is contained in:
parent
1f112a04f4
commit
db13786793
62 changed files with 66509 additions and 1 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
1
libratbox/.indent.pro
vendored
Normal file
1
libratbox/.indent.pro
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
-i8 -bli0 -ut -nsai -l100 -npcs
|
340
libratbox/COPYING
Normal file
340
libratbox/COPYING
Normal file
|
@ -0,0 +1,340 @@
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
18
libratbox/CREDITS
Normal file
18
libratbox/CREDITS
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
$Id: CREDITS 23020 2006-09-01 18:20:19Z androsyn $
|
||||||
|
|
||||||
|
ircd-ratbox is an evolution where ircd-hybrid left off around version 7-rc1.
|
||||||
|
Currently the ircd-ratbox team consists of the following developers:
|
||||||
|
|
||||||
|
AndroSyn, Aaron Sethman <androsyn -at- ratbox.org>
|
||||||
|
anfl, Lee Hardy <lee -at- leeh.co.uk>
|
||||||
|
|
||||||
|
Special thanks for support, code and ideas to:
|
||||||
|
|
||||||
|
Hwy, W. Campbell <wcampbel -at- botbay.net>
|
||||||
|
jilles, Jilles Tjoelker <jilles -at- stack.nl>
|
||||||
|
larne, Edward Brocklesby <ejb -at- sdf.lonestar.org>
|
||||||
|
|
||||||
|
Of course our work is based on the work of many, many others over the past
|
||||||
|
10 or so years since irc has existed, including the work done by the Hybrid
|
||||||
|
team, our thanks goes to them.
|
||||||
|
|
3153
libratbox/ChangeLog
Normal file
3153
libratbox/ChangeLog
Normal file
File diff suppressed because it is too large
Load diff
182
libratbox/INSTALL
Normal file
182
libratbox/INSTALL
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
Basic Installation
|
||||||
|
==================
|
||||||
|
|
||||||
|
These are generic installation instructions.
|
||||||
|
|
||||||
|
The `configure' shell script attempts to guess correct values for
|
||||||
|
various system-dependent variables used during compilation. It uses
|
||||||
|
those values to create a `Makefile' in each directory of the package.
|
||||||
|
It may also create one or more `.h' files containing system-dependent
|
||||||
|
definitions. Finally, it creates a shell script `config.status' that
|
||||||
|
you can run in the future to recreate the current configuration, a file
|
||||||
|
`config.cache' that saves the results of its tests to speed up
|
||||||
|
reconfiguring, and a file `config.log' containing compiler output
|
||||||
|
(useful mainly for debugging `configure').
|
||||||
|
|
||||||
|
If you need to do unusual things to compile the package, please try
|
||||||
|
to figure out how `configure' could check whether to do them, and mail
|
||||||
|
diffs or instructions to the address given in the `README' so they can
|
||||||
|
be considered for the next release. If at some point `config.cache'
|
||||||
|
contains results you don't want to keep, you may remove or edit it.
|
||||||
|
|
||||||
|
The file `configure.in' is used to create `configure' by a program
|
||||||
|
called `autoconf'. You only need `configure.in' if you want to change
|
||||||
|
it or regenerate `configure' using a newer version of `autoconf'.
|
||||||
|
|
||||||
|
The simplest way to compile this package is:
|
||||||
|
|
||||||
|
1. `cd' to the directory containing the package's source code and type
|
||||||
|
`./configure' to configure the package for your system. If you're
|
||||||
|
using `csh' on an old version of System V, you might need to type
|
||||||
|
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||||
|
`configure' itself.
|
||||||
|
|
||||||
|
Running `configure' takes awhile. While running, it prints some
|
||||||
|
messages telling which features it is checking for.
|
||||||
|
|
||||||
|
2. Type `make' to compile the package.
|
||||||
|
|
||||||
|
3. Optionally, type `make check' to run any self-tests that come with
|
||||||
|
the package.
|
||||||
|
|
||||||
|
4. Type `make install' to install the programs and any data files and
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
5. You can remove the program binaries and object files from the
|
||||||
|
source code directory by typing `make clean'. To also remove the
|
||||||
|
files that `configure' created (so you can compile the package for
|
||||||
|
a different kind of computer), type `make distclean'. There is
|
||||||
|
also a `make maintainer-clean' target, but that is intended mainly
|
||||||
|
for the package's developers. If you use it, you may have to get
|
||||||
|
all sorts of other programs in order to regenerate files that came
|
||||||
|
with the distribution.
|
||||||
|
|
||||||
|
Compilers and Options
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Some systems require unusual options for compilation or linking that
|
||||||
|
the `configure' script does not know about. You can give `configure'
|
||||||
|
initial values for variables by setting them in the environment. Using
|
||||||
|
a Bourne-compatible shell, you can do that on the command line like
|
||||||
|
this:
|
||||||
|
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||||
|
|
||||||
|
Or on systems that have the `env' program, you can do it like this:
|
||||||
|
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||||
|
|
||||||
|
Compiling For Multiple Architectures
|
||||||
|
====================================
|
||||||
|
|
||||||
|
You can compile the package for more than one kind of computer at the
|
||||||
|
same time, by placing the object files for each architecture in their
|
||||||
|
own directory. To do this, you must use a version of `make' that
|
||||||
|
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||||
|
directory where you want the object files and executables to go and run
|
||||||
|
the `configure' script. `configure' automatically checks for the
|
||||||
|
source code in the directory that `configure' is in and in `..'.
|
||||||
|
|
||||||
|
If you have to use a `make' that does not supports the `VPATH'
|
||||||
|
variable, you have to compile the package for one architecture at a time
|
||||||
|
in the source code directory. After you have installed the package for
|
||||||
|
one architecture, use `make distclean' before reconfiguring for another
|
||||||
|
architecture.
|
||||||
|
|
||||||
|
Installation Names
|
||||||
|
==================
|
||||||
|
|
||||||
|
By default, `make install' will install the package's files in
|
||||||
|
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||||
|
installation prefix other than `/usr/local' by giving `configure' the
|
||||||
|
option `--prefix=PATH'.
|
||||||
|
|
||||||
|
You can specify separate installation prefixes for
|
||||||
|
architecture-specific files and architecture-independent files. If you
|
||||||
|
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||||
|
PATH as the prefix for installing programs and libraries.
|
||||||
|
Documentation and other data files will still use the regular prefix.
|
||||||
|
|
||||||
|
In addition, if you use an unusual directory layout you can give
|
||||||
|
options like `--bindir=PATH' to specify different values for particular
|
||||||
|
kinds of files. Run `configure --help' for a list of the directories
|
||||||
|
you can set and what kinds of files go in them.
|
||||||
|
|
||||||
|
If the package supports it, you can cause programs to be installed
|
||||||
|
with an extra prefix or suffix on their names by giving `configure' the
|
||||||
|
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||||
|
|
||||||
|
Optional Features
|
||||||
|
=================
|
||||||
|
|
||||||
|
Some packages pay attention to `--enable-FEATURE' options to
|
||||||
|
`configure', where FEATURE indicates an optional part of the package.
|
||||||
|
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||||
|
is something like `gnu-as' or `x' (for the X Window System). The
|
||||||
|
`README' should mention any `--enable-' and `--with-' options that the
|
||||||
|
package recognizes.
|
||||||
|
|
||||||
|
For packages that use the X Window System, `configure' can usually
|
||||||
|
find the X include and library files automatically, but if it doesn't,
|
||||||
|
you can use the `configure' options `--x-includes=DIR' and
|
||||||
|
`--x-libraries=DIR' to specify their locations.
|
||||||
|
|
||||||
|
Specifying the System Type
|
||||||
|
==========================
|
||||||
|
|
||||||
|
There may be some features `configure' can not figure out
|
||||||
|
automatically, but needs to determine by the type of host the package
|
||||||
|
will run on. Usually `configure' can figure that out, but if it prints
|
||||||
|
a message saying it can not guess the host type, give it the
|
||||||
|
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||||
|
type, such as `sun4', or a canonical name with three fields:
|
||||||
|
CPU-COMPANY-SYSTEM
|
||||||
|
|
||||||
|
See the file `config.sub' for the possible values of each field. If
|
||||||
|
`config.sub' isn't included in this package, then this package doesn't
|
||||||
|
need to know the host type.
|
||||||
|
|
||||||
|
If you are building compiler tools for cross-compiling, you can also
|
||||||
|
use the `--target=TYPE' option to select the type of system they will
|
||||||
|
produce code for and the `--build=TYPE' option to select the type of
|
||||||
|
system on which you are compiling the package.
|
||||||
|
|
||||||
|
Sharing Defaults
|
||||||
|
================
|
||||||
|
|
||||||
|
If you want to set default values for `configure' scripts to share,
|
||||||
|
you can create a site shell script called `config.site' that gives
|
||||||
|
default values for variables like `CC', `cache_file', and `prefix'.
|
||||||
|
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||||
|
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||||
|
`CONFIG_SITE' environment variable to the location of the site script.
|
||||||
|
A warning: not all `configure' scripts look for a site script.
|
||||||
|
|
||||||
|
Operation Controls
|
||||||
|
==================
|
||||||
|
|
||||||
|
`configure' recognizes the following options to control how it
|
||||||
|
operates.
|
||||||
|
|
||||||
|
`--cache-file=FILE'
|
||||||
|
Use and save the results of the tests in FILE instead of
|
||||||
|
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||||
|
debugging `configure'.
|
||||||
|
|
||||||
|
`--help'
|
||||||
|
Print a summary of the options to `configure', and exit.
|
||||||
|
|
||||||
|
`--quiet'
|
||||||
|
`--silent'
|
||||||
|
`-q'
|
||||||
|
Do not print messages saying which checks are being made. To
|
||||||
|
suppress all normal output, redirect it to `/dev/null' (any error
|
||||||
|
messages will still be shown).
|
||||||
|
|
||||||
|
`--srcdir=DIR'
|
||||||
|
Look for the package's source code in directory DIR. Usually
|
||||||
|
`configure' can determine that directory automatically.
|
||||||
|
|
||||||
|
`--version'
|
||||||
|
Print the version of Autoconf used to generate the `configure'
|
||||||
|
script, and exit.
|
||||||
|
|
||||||
|
`configure' also accepts some other, not widely useful, options.
|
3
libratbox/Makefile.am
Normal file
3
libratbox/Makefile.am
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
AUTOMAKE_OPTIONS = foreign
|
||||||
|
|
||||||
|
SUBDIRS = src
|
643
libratbox/Makefile.in
Normal file
643
libratbox/Makefile.in
Normal file
|
@ -0,0 +1,643 @@
|
||||||
|
# Makefile.in generated by automake 1.10 from Makefile.am.
|
||||||
|
# @configure_input@
|
||||||
|
|
||||||
|
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||||
|
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||||
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||||
|
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
@SET_MAKE@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
pkgdatadir = $(datadir)/@PACKAGE@
|
||||||
|
pkglibdir = $(libdir)/@PACKAGE@
|
||||||
|
pkgincludedir = $(includedir)/@PACKAGE@
|
||||||
|
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||||
|
install_sh_DATA = $(install_sh) -c -m 644
|
||||||
|
install_sh_PROGRAM = $(install_sh) -c
|
||||||
|
install_sh_SCRIPT = $(install_sh) -c
|
||||||
|
INSTALL_HEADER = $(INSTALL_DATA)
|
||||||
|
transform = $(program_transform_name)
|
||||||
|
NORMAL_INSTALL = :
|
||||||
|
PRE_INSTALL = :
|
||||||
|
POST_INSTALL = :
|
||||||
|
NORMAL_UNINSTALL = :
|
||||||
|
PRE_UNINSTALL = :
|
||||||
|
POST_UNINSTALL = :
|
||||||
|
build_triplet = @build@
|
||||||
|
host_triplet = @host@
|
||||||
|
subdir = .
|
||||||
|
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
|
||||||
|
$(srcdir)/Makefile.in $(top_srcdir)/configure \
|
||||||
|
$(top_srcdir)/include/libratbox_config.h.in COPYING ChangeLog \
|
||||||
|
INSTALL TODO config.guess config.sub depcomp install-sh \
|
||||||
|
ltmain.sh missing
|
||||||
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
|
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
|
||||||
|
$(top_srcdir)/configure.ac
|
||||||
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
|
$(ACLOCAL_M4)
|
||||||
|
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||||
|
configure.lineno config.status.lineno
|
||||||
|
mkinstalldirs = $(install_sh) -d
|
||||||
|
CONFIG_HEADER = $(top_builddir)/include/libratbox_config.h
|
||||||
|
CONFIG_CLEAN_FILES =
|
||||||
|
SOURCES =
|
||||||
|
DIST_SOURCES =
|
||||||
|
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
|
||||||
|
html-recursive info-recursive install-data-recursive \
|
||||||
|
install-dvi-recursive install-exec-recursive \
|
||||||
|
install-html-recursive install-info-recursive \
|
||||||
|
install-pdf-recursive install-ps-recursive install-recursive \
|
||||||
|
installcheck-recursive installdirs-recursive pdf-recursive \
|
||||||
|
ps-recursive uninstall-recursive
|
||||||
|
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
|
||||||
|
distclean-recursive maintainer-clean-recursive
|
||||||
|
ETAGS = etags
|
||||||
|
CTAGS = ctags
|
||||||
|
DIST_SUBDIRS = $(SUBDIRS)
|
||||||
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
distdir = $(PACKAGE)-$(VERSION)
|
||||||
|
top_distdir = $(distdir)
|
||||||
|
am__remove_distdir = \
|
||||||
|
{ test ! -d $(distdir) \
|
||||||
|
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
|
||||||
|
&& rm -fr $(distdir); }; }
|
||||||
|
DIST_ARCHIVES = $(distdir).tar.gz
|
||||||
|
GZIP_ENV = --best
|
||||||
|
distuninstallcheck_listfiles = find . -type f -print
|
||||||
|
distcleancheck_listfiles = find . -type f -print
|
||||||
|
ACLOCAL = @ACLOCAL@
|
||||||
|
ALLOCA = @ALLOCA@
|
||||||
|
AMTAR = @AMTAR@
|
||||||
|
AR = @AR@
|
||||||
|
AS = @AS@
|
||||||
|
AUTOCONF = @AUTOCONF@
|
||||||
|
AUTOHEADER = @AUTOHEADER@
|
||||||
|
AUTOMAKE = @AUTOMAKE@
|
||||||
|
AWK = @AWK@
|
||||||
|
CC = @CC@
|
||||||
|
CCDEPMODE = @CCDEPMODE@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CP = @CP@
|
||||||
|
CPP = @CPP@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CRYPT_LIB = @CRYPT_LIB@
|
||||||
|
CXX = @CXX@
|
||||||
|
CXXCPP = @CXXCPP@
|
||||||
|
CXXDEPMODE = @CXXDEPMODE@
|
||||||
|
CXXFLAGS = @CXXFLAGS@
|
||||||
|
CYGPATH_W = @CYGPATH_W@
|
||||||
|
DEFS = @DEFS@
|
||||||
|
DEPDIR = @DEPDIR@
|
||||||
|
ECHO = @ECHO@
|
||||||
|
ECHO_C = @ECHO_C@
|
||||||
|
ECHO_N = @ECHO_N@
|
||||||
|
ECHO_T = @ECHO_T@
|
||||||
|
EGREP = @EGREP@
|
||||||
|
EXEEXT = @EXEEXT@
|
||||||
|
F77 = @F77@
|
||||||
|
FFLAGS = @FFLAGS@
|
||||||
|
GREP = @GREP@
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
|
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||||
|
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||||
|
LD = @LD@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBOBJS = @LIBOBJS@
|
||||||
|
LIBS = @LIBS@
|
||||||
|
LIBTOOL = @LIBTOOL@
|
||||||
|
LN = @LN@
|
||||||
|
LN_S = @LN_S@
|
||||||
|
LTLIBOBJS = @LTLIBOBJS@
|
||||||
|
MAINT = @MAINT@
|
||||||
|
MAKEINFO = @MAKEINFO@
|
||||||
|
MKDIR_P = @MKDIR_P@
|
||||||
|
MV = @MV@
|
||||||
|
OBJEXT = @OBJEXT@
|
||||||
|
PACKAGE = @PACKAGE@
|
||||||
|
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||||
|
PACKAGE_NAME = @PACKAGE_NAME@
|
||||||
|
PACKAGE_STRING = @PACKAGE_STRING@
|
||||||
|
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||||
|
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||||
|
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||||
|
PICFLAGS = @PICFLAGS@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
RB_PREFIX = @RB_PREFIX@
|
||||||
|
RM = @RM@
|
||||||
|
SED = @SED@
|
||||||
|
SEDOBJ = @SEDOBJ@
|
||||||
|
SET_MAKE = @SET_MAKE@
|
||||||
|
SHELL = @SHELL@
|
||||||
|
SSL_INCLUDES = @SSL_INCLUDES@
|
||||||
|
SSL_LIBS = @SSL_LIBS@
|
||||||
|
STRIP = @STRIP@
|
||||||
|
TOUCH = @TOUCH@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
abs_builddir = @abs_builddir@
|
||||||
|
abs_srcdir = @abs_srcdir@
|
||||||
|
abs_top_builddir = @abs_top_builddir@
|
||||||
|
abs_top_srcdir = @abs_top_srcdir@
|
||||||
|
ac_ct_CC = @ac_ct_CC@
|
||||||
|
ac_ct_CXX = @ac_ct_CXX@
|
||||||
|
ac_ct_F77 = @ac_ct_F77@
|
||||||
|
am__include = @am__include@
|
||||||
|
am__leading_dot = @am__leading_dot@
|
||||||
|
am__quote = @am__quote@
|
||||||
|
am__tar = @am__tar@
|
||||||
|
am__untar = @am__untar@
|
||||||
|
bindir = @bindir@
|
||||||
|
build = @build@
|
||||||
|
build_alias = @build_alias@
|
||||||
|
build_cpu = @build_cpu@
|
||||||
|
build_os = @build_os@
|
||||||
|
build_vendor = @build_vendor@
|
||||||
|
builddir = @builddir@
|
||||||
|
datadir = @datadir@
|
||||||
|
datarootdir = @datarootdir@
|
||||||
|
docdir = @docdir@
|
||||||
|
dvidir = @dvidir@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
host = @host@
|
||||||
|
host_alias = @host_alias@
|
||||||
|
host_cpu = @host_cpu@
|
||||||
|
host_os = @host_os@
|
||||||
|
host_vendor = @host_vendor@
|
||||||
|
htmldir = @htmldir@
|
||||||
|
includedir = @includedir@
|
||||||
|
infodir = @infodir@
|
||||||
|
install_sh = @install_sh@
|
||||||
|
libdir = @libdir@
|
||||||
|
libexecdir = @libexecdir@
|
||||||
|
localedir = @localedir@
|
||||||
|
localstatedir = @localstatedir@
|
||||||
|
mandir = @mandir@
|
||||||
|
mkdir_p = @mkdir_p@
|
||||||
|
oldincludedir = @oldincludedir@
|
||||||
|
pdfdir = @pdfdir@
|
||||||
|
prefix = @prefix@
|
||||||
|
program_transform_name = @program_transform_name@
|
||||||
|
psdir = @psdir@
|
||||||
|
sbindir = @sbindir@
|
||||||
|
sharedstatedir = @sharedstatedir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
subdirs = @subdirs@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
target_alias = @target_alias@
|
||||||
|
top_builddir = @top_builddir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
AUTOMAKE_OPTIONS = foreign
|
||||||
|
SUBDIRS = src
|
||||||
|
all: all-recursive
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
am--refresh:
|
||||||
|
@:
|
||||||
|
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||||
|
@for dep in $?; do \
|
||||||
|
case '$(am__configure_deps)' in \
|
||||||
|
*$$dep*) \
|
||||||
|
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \
|
||||||
|
cd $(srcdir) && $(AUTOMAKE) --foreign \
|
||||||
|
&& exit 0; \
|
||||||
|
exit 1;; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
|
||||||
|
cd $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --foreign Makefile
|
||||||
|
.PRECIOUS: Makefile
|
||||||
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
|
@case '$?' in \
|
||||||
|
*config.status*) \
|
||||||
|
echo ' $(SHELL) ./config.status'; \
|
||||||
|
$(SHELL) ./config.status;; \
|
||||||
|
*) \
|
||||||
|
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
|
||||||
|
esac;
|
||||||
|
|
||||||
|
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||||
|
$(SHELL) ./config.status --recheck
|
||||||
|
|
||||||
|
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||||
|
cd $(srcdir) && $(AUTOCONF)
|
||||||
|
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||||
|
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
|
||||||
|
|
||||||
|
include/libratbox_config.h: include/stamp-h1
|
||||||
|
@if test ! -f $@; then \
|
||||||
|
rm -f include/stamp-h1; \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) include/stamp-h1; \
|
||||||
|
else :; fi
|
||||||
|
|
||||||
|
include/stamp-h1: $(top_srcdir)/include/libratbox_config.h.in $(top_builddir)/config.status
|
||||||
|
@rm -f include/stamp-h1
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status include/libratbox_config.h
|
||||||
|
$(top_srcdir)/include/libratbox_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||||
|
cd $(top_srcdir) && $(AUTOHEADER)
|
||||||
|
rm -f include/stamp-h1
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
distclean-hdr:
|
||||||
|
-rm -f include/libratbox_config.h include/stamp-h1
|
||||||
|
|
||||||
|
mostlyclean-libtool:
|
||||||
|
-rm -f *.lo
|
||||||
|
|
||||||
|
clean-libtool:
|
||||||
|
-rm -rf .libs _libs
|
||||||
|
|
||||||
|
distclean-libtool:
|
||||||
|
-rm -f libtool
|
||||||
|
|
||||||
|
# This directory's subdirectories are mostly independent; you can cd
|
||||||
|
# into them and run `make' without going through this Makefile.
|
||||||
|
# To change the values of `make' variables: instead of editing Makefiles,
|
||||||
|
# (1) if the variable is set in `config.status', edit `config.status'
|
||||||
|
# (which will cause the Makefiles to be regenerated when you run `make');
|
||||||
|
# (2) otherwise, pass the desired values on the `make' command line.
|
||||||
|
$(RECURSIVE_TARGETS):
|
||||||
|
@failcom='exit 1'; \
|
||||||
|
for f in x $$MAKEFLAGS; do \
|
||||||
|
case $$f in \
|
||||||
|
*=* | --[!k]*);; \
|
||||||
|
*k*) failcom='fail=yes';; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
dot_seen=no; \
|
||||||
|
target=`echo $@ | sed s/-recursive//`; \
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
echo "Making $$target in $$subdir"; \
|
||||||
|
if test "$$subdir" = "."; then \
|
||||||
|
dot_seen=yes; \
|
||||||
|
local_target="$$target-am"; \
|
||||||
|
else \
|
||||||
|
local_target="$$target"; \
|
||||||
|
fi; \
|
||||||
|
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||||
|
|| eval $$failcom; \
|
||||||
|
done; \
|
||||||
|
if test "$$dot_seen" = "no"; then \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||||
|
fi; test -z "$$fail"
|
||||||
|
|
||||||
|
$(RECURSIVE_CLEAN_TARGETS):
|
||||||
|
@failcom='exit 1'; \
|
||||||
|
for f in x $$MAKEFLAGS; do \
|
||||||
|
case $$f in \
|
||||||
|
*=* | --[!k]*);; \
|
||||||
|
*k*) failcom='fail=yes';; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
dot_seen=no; \
|
||||||
|
case "$@" in \
|
||||||
|
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||||
|
*) list='$(SUBDIRS)' ;; \
|
||||||
|
esac; \
|
||||||
|
rev=''; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = "."; then :; else \
|
||||||
|
rev="$$subdir $$rev"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
rev="$$rev ."; \
|
||||||
|
target=`echo $@ | sed s/-recursive//`; \
|
||||||
|
for subdir in $$rev; do \
|
||||||
|
echo "Making $$target in $$subdir"; \
|
||||||
|
if test "$$subdir" = "."; then \
|
||||||
|
local_target="$$target-am"; \
|
||||||
|
else \
|
||||||
|
local_target="$$target"; \
|
||||||
|
fi; \
|
||||||
|
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||||
|
|| eval $$failcom; \
|
||||||
|
done && test -z "$$fail"
|
||||||
|
tags-recursive:
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
|
||||||
|
done
|
||||||
|
ctags-recursive:
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
|
||||||
|
done
|
||||||
|
|
||||||
|
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
mkid -fID $$unique
|
||||||
|
tags: TAGS
|
||||||
|
|
||||||
|
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
tags=; \
|
||||||
|
here=`pwd`; \
|
||||||
|
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
|
||||||
|
include_option=--etags-include; \
|
||||||
|
empty_fix=.; \
|
||||||
|
else \
|
||||||
|
include_option=--include; \
|
||||||
|
empty_fix=; \
|
||||||
|
fi; \
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = .; then :; else \
|
||||||
|
test ! -f $$subdir/TAGS || \
|
||||||
|
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
|
||||||
|
test -n "$$unique" || unique=$$empty_fix; \
|
||||||
|
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||||
|
$$tags $$unique; \
|
||||||
|
fi
|
||||||
|
ctags: CTAGS
|
||||||
|
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
tags=; \
|
||||||
|
here=`pwd`; \
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|
||||||
|
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||||
|
$$tags $$unique
|
||||||
|
|
||||||
|
GTAGS:
|
||||||
|
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||||
|
&& cd $(top_srcdir) \
|
||||||
|
&& gtags -i $(GTAGS_ARGS) $$here
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
|
|
||||||
|
distdir: $(DISTFILES)
|
||||||
|
$(am__remove_distdir)
|
||||||
|
test -d $(distdir) || mkdir $(distdir)
|
||||||
|
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||||
|
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||||
|
list='$(DISTFILES)'; \
|
||||||
|
dist_files=`for file in $$list; do echo $$file; done | \
|
||||||
|
sed -e "s|^$$srcdirstrip/||;t" \
|
||||||
|
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||||
|
case $$dist_files in \
|
||||||
|
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||||
|
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||||
|
sort -u` ;; \
|
||||||
|
esac; \
|
||||||
|
for file in $$dist_files; do \
|
||||||
|
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||||
|
if test -d $$d/$$file; then \
|
||||||
|
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||||
|
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||||
|
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||||
|
fi; \
|
||||||
|
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||||
|
else \
|
||||||
|
test -f $(distdir)/$$file \
|
||||||
|
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||||
|
|| exit 1; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = .; then :; else \
|
||||||
|
test -d "$(distdir)/$$subdir" \
|
||||||
|
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|
||||||
|
|| exit 1; \
|
||||||
|
distdir=`$(am__cd) $(distdir) && pwd`; \
|
||||||
|
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
|
||||||
|
(cd $$subdir && \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) \
|
||||||
|
top_distdir="$$top_distdir" \
|
||||||
|
distdir="$$distdir/$$subdir" \
|
||||||
|
am__remove_distdir=: \
|
||||||
|
am__skip_length_check=: \
|
||||||
|
distdir) \
|
||||||
|
|| exit 1; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
|
||||||
|
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
|
||||||
|
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
|
||||||
|
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|
||||||
|
|| chmod -R a+r $(distdir)
|
||||||
|
dist-gzip: distdir
|
||||||
|
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
dist-bzip2: distdir
|
||||||
|
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
dist-tarZ: distdir
|
||||||
|
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
dist-shar: distdir
|
||||||
|
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
dist-zip: distdir
|
||||||
|
-rm -f $(distdir).zip
|
||||||
|
zip -rq $(distdir).zip $(distdir)
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
dist dist-all: distdir
|
||||||
|
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
# This target untars the dist file and tries a VPATH configuration. Then
|
||||||
|
# it guarantees that the distribution is self-contained by making another
|
||||||
|
# tarfile.
|
||||||
|
distcheck: dist
|
||||||
|
case '$(DIST_ARCHIVES)' in \
|
||||||
|
*.tar.gz*) \
|
||||||
|
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
|
||||||
|
*.tar.bz2*) \
|
||||||
|
bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
|
||||||
|
*.tar.Z*) \
|
||||||
|
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
|
||||||
|
*.shar.gz*) \
|
||||||
|
GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
|
||||||
|
*.zip*) \
|
||||||
|
unzip $(distdir).zip ;;\
|
||||||
|
esac
|
||||||
|
chmod -R a-w $(distdir); chmod a+w $(distdir)
|
||||||
|
mkdir $(distdir)/_build
|
||||||
|
mkdir $(distdir)/_inst
|
||||||
|
chmod a-w $(distdir)
|
||||||
|
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
|
||||||
|
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
|
||||||
|
&& cd $(distdir)/_build \
|
||||||
|
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
|
||||||
|
$(DISTCHECK_CONFIGURE_FLAGS) \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
|
||||||
|
distuninstallcheck \
|
||||||
|
&& chmod -R a-w "$$dc_install_base" \
|
||||||
|
&& ({ \
|
||||||
|
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
|
||||||
|
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
|
||||||
|
} || { rm -rf "$$dc_destdir"; exit 1; }) \
|
||||||
|
&& rm -rf "$$dc_destdir" \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) dist \
|
||||||
|
&& rm -rf $(DIST_ARCHIVES) \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
|
||||||
|
$(am__remove_distdir)
|
||||||
|
@(echo "$(distdir) archives ready for distribution: "; \
|
||||||
|
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
|
||||||
|
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
|
||||||
|
distuninstallcheck:
|
||||||
|
@cd $(distuninstallcheck_dir) \
|
||||||
|
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|
||||||
|
|| { echo "ERROR: files left after uninstall:" ; \
|
||||||
|
if test -n "$(DESTDIR)"; then \
|
||||||
|
echo " (check DESTDIR support)"; \
|
||||||
|
fi ; \
|
||||||
|
$(distuninstallcheck_listfiles) ; \
|
||||||
|
exit 1; } >&2
|
||||||
|
distcleancheck: distclean
|
||||||
|
@if test '$(srcdir)' = . ; then \
|
||||||
|
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
|
||||||
|
exit 1 ; \
|
||||||
|
fi
|
||||||
|
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|
||||||
|
|| { echo "ERROR: files left in build directory after distclean:" ; \
|
||||||
|
$(distcleancheck_listfiles) ; \
|
||||||
|
exit 1; } >&2
|
||||||
|
check-am: all-am
|
||||||
|
check: check-recursive
|
||||||
|
all-am: Makefile
|
||||||
|
installdirs: installdirs-recursive
|
||||||
|
installdirs-am:
|
||||||
|
install: install-recursive
|
||||||
|
install-exec: install-exec-recursive
|
||||||
|
install-data: install-data-recursive
|
||||||
|
uninstall: uninstall-recursive
|
||||||
|
|
||||||
|
install-am: all-am
|
||||||
|
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
|
|
||||||
|
installcheck: installcheck-recursive
|
||||||
|
install-strip:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
`test -z '$(STRIP)' || \
|
||||||
|
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||||
|
mostlyclean-generic:
|
||||||
|
|
||||||
|
clean-generic:
|
||||||
|
|
||||||
|
distclean-generic:
|
||||||
|
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||||
|
|
||||||
|
maintainer-clean-generic:
|
||||||
|
@echo "This command is intended for maintainers to use"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
clean: clean-recursive
|
||||||
|
|
||||||
|
clean-am: clean-generic clean-libtool mostlyclean-am
|
||||||
|
|
||||||
|
distclean: distclean-recursive
|
||||||
|
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||||
|
-rm -f Makefile
|
||||||
|
distclean-am: clean-am distclean-generic distclean-hdr \
|
||||||
|
distclean-libtool distclean-tags
|
||||||
|
|
||||||
|
dvi: dvi-recursive
|
||||||
|
|
||||||
|
dvi-am:
|
||||||
|
|
||||||
|
html: html-recursive
|
||||||
|
|
||||||
|
info: info-recursive
|
||||||
|
|
||||||
|
info-am:
|
||||||
|
|
||||||
|
install-data-am:
|
||||||
|
|
||||||
|
install-dvi: install-dvi-recursive
|
||||||
|
|
||||||
|
install-exec-am:
|
||||||
|
|
||||||
|
install-html: install-html-recursive
|
||||||
|
|
||||||
|
install-info: install-info-recursive
|
||||||
|
|
||||||
|
install-man:
|
||||||
|
|
||||||
|
install-pdf: install-pdf-recursive
|
||||||
|
|
||||||
|
install-ps: install-ps-recursive
|
||||||
|
|
||||||
|
installcheck-am:
|
||||||
|
|
||||||
|
maintainer-clean: maintainer-clean-recursive
|
||||||
|
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||||
|
-rm -rf $(top_srcdir)/autom4te.cache
|
||||||
|
-rm -f Makefile
|
||||||
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||||
|
|
||||||
|
mostlyclean: mostlyclean-recursive
|
||||||
|
|
||||||
|
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
||||||
|
|
||||||
|
pdf: pdf-recursive
|
||||||
|
|
||||||
|
pdf-am:
|
||||||
|
|
||||||
|
ps: ps-recursive
|
||||||
|
|
||||||
|
ps-am:
|
||||||
|
|
||||||
|
uninstall-am:
|
||||||
|
|
||||||
|
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
|
||||||
|
install-strip
|
||||||
|
|
||||||
|
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
|
||||||
|
all all-am am--refresh check check-am clean clean-generic \
|
||||||
|
clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
|
||||||
|
dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \
|
||||||
|
distclean-generic distclean-hdr distclean-libtool \
|
||||||
|
distclean-tags distcleancheck distdir distuninstallcheck dvi \
|
||||||
|
dvi-am html html-am info info-am install install-am \
|
||||||
|
install-data install-data-am install-dvi install-dvi-am \
|
||||||
|
install-exec install-exec-am install-html install-html-am \
|
||||||
|
install-info install-info-am install-man install-pdf \
|
||||||
|
install-pdf-am install-ps install-ps-am install-strip \
|
||||||
|
installcheck installcheck-am installdirs installdirs-am \
|
||||||
|
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||||
|
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||||
|
tags tags-recursive uninstall uninstall-am
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
11
libratbox/README
Normal file
11
libratbox/README
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
This is libircd from ircd-ratbox. A few notes about this library:
|
||||||
|
|
||||||
|
1. Most of this code isn't anywhere near threadsafe at this point. Don't
|
||||||
|
hold your breath on this either.
|
||||||
|
2. The linebuf code is designed to deal with pretty much 512 bytes per line
|
||||||
|
and that is it. Anything beyond that length unless in raw mode, gets
|
||||||
|
discard. For some non-irc purposes, this can be a problem, but for
|
||||||
|
ircd stuff its fine.
|
||||||
|
3. The helper code when transmitting data between helpers, the same 512 byte
|
||||||
|
limit applies there as we recycle the linebuf code for this.
|
||||||
|
|
2
libratbox/TODO
Normal file
2
libratbox/TODO
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
1. Make i/o loop engines interchangable at run time.
|
||||||
|
2. Finish TODO list
|
191
libratbox/acinclude.m4
Normal file
191
libratbox/acinclude.m4
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
# $Id: acinclude.m4 23020 2006-09-01 18:20:19Z androsyn $ - aclocal.m4 - Autoconf fun...
|
||||||
|
AC_DEFUN([AC_DEFINE_DIR], [
|
||||||
|
test "x$prefix" = xNONE && prefix="$ac_default_prefix"
|
||||||
|
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
|
||||||
|
ac_define_dir=`eval echo [$]$2`
|
||||||
|
ac_define_dir=`eval echo [$]ac_define_dir`
|
||||||
|
$1="$ac_define_dir"
|
||||||
|
AC_SUBST($1)
|
||||||
|
ifelse($3, ,
|
||||||
|
AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
|
||||||
|
AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([AC_SUBST_DIR], [
|
||||||
|
ifelse($2,,,$1="[$]$2")
|
||||||
|
$1=`(
|
||||||
|
test "x$prefix" = xNONE && prefix="$ac_default_prefix"
|
||||||
|
test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
|
||||||
|
eval echo \""[$]$1"\"
|
||||||
|
)`
|
||||||
|
AC_SUBST($1)
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# RB_TYPE_INTMAX_T
|
||||||
|
# -----------------
|
||||||
|
AC_DEFUN([RB_TYPE_INTMAX_T],
|
||||||
|
[
|
||||||
|
AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
|
||||||
|
AC_CHECK_TYPE([intmax_t],
|
||||||
|
[AC_DEFINE([HAVE_INTMAX_T], 1,
|
||||||
|
[Define to 1 if the system has the type `intmax_t'.]) ac_cv_c_intmax_t=yes],
|
||||||
|
[test $ac_cv_type_long_long_int = yes \
|
||||||
|
&& ac_type='long long int' \
|
||||||
|
|| ac_type='long int'
|
||||||
|
AC_DEFINE_UNQUOTED([intmax_t], [$ac_type],
|
||||||
|
[Define to the widest signed integer type
|
||||||
|
if <stdint.h> and <inttypes.h> do not define.]) ac_cv_c_intmax_t="$ac_type"])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# RB_TYPE_UINTMAX_T
|
||||||
|
# -----------------
|
||||||
|
AC_DEFUN([RB_TYPE_UINTMAX_T],
|
||||||
|
[
|
||||||
|
AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
|
||||||
|
AC_CHECK_TYPE([uintmax_t],
|
||||||
|
[AC_DEFINE([HAVE_UINTMAX_T], 1,
|
||||||
|
[Define to 1 if the system has the type `uintmax_t'.]) ac_cv_c_uintmax_t=yes],
|
||||||
|
[test $ac_cv_type_unsigned_long_long_int = yes \
|
||||||
|
&& ac_type='unsigned long long int' \
|
||||||
|
|| ac_type='unsigned long int'
|
||||||
|
AC_DEFINE_UNQUOTED([uintmax_t], [$ac_type],
|
||||||
|
[Define to the widest unsigned integer type
|
||||||
|
if <stdint.h> and <inttypes.h> do not define.]) ac_cv_c_uintmax_t="$ac_type"])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# RB_TYPE_INTPTR_T
|
||||||
|
# -----------------
|
||||||
|
AC_DEFUN([RB_TYPE_INTPTR_T],
|
||||||
|
[
|
||||||
|
AC_CHECK_TYPE([intptr_t],
|
||||||
|
[AC_DEFINE([HAVE_INTPTR_T], 1,
|
||||||
|
[Define to 1 if the system has the type `intptr_t'.]) ac_cv_c_intptr_t=yes],
|
||||||
|
[for ac_type in 'int' 'long int' 'long long int'; do
|
||||||
|
AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_BOOL_COMPILE_TRY(
|
||||||
|
[AC_INCLUDES_DEFAULT],
|
||||||
|
[[sizeof (void *) <= sizeof ($ac_type)]])],
|
||||||
|
[AC_DEFINE_UNQUOTED([intptr_t], [$ac_type],
|
||||||
|
[Define to the type of a signed integer type wide enough to
|
||||||
|
hold a pointer, if such a type exists, and if the system
|
||||||
|
does not define it.]) ac_cv_c_intptr_t="$ac_type"
|
||||||
|
ac_type=])
|
||||||
|
test -z "$ac_type" && break
|
||||||
|
done])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# RB_TYPE_UINTPTR_T
|
||||||
|
# -----------------
|
||||||
|
AC_DEFUN([RB_TYPE_UINTPTR_T],
|
||||||
|
[
|
||||||
|
AC_CHECK_TYPE([uintptr_t],
|
||||||
|
[AC_DEFINE([HAVE_UINTPTR_T], 1,
|
||||||
|
[Define to 1 if the system has the type `uintptr_t'.]) ac_cv_c_uintptr_t=yes],
|
||||||
|
[for ac_type in 'unsigned int' 'unsigned long int' \
|
||||||
|
'unsigned long long int'; do
|
||||||
|
AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_BOOL_COMPILE_TRY(
|
||||||
|
[AC_INCLUDES_DEFAULT],
|
||||||
|
[[sizeof (void *) <= sizeof ($ac_type)]])],
|
||||||
|
[AC_DEFINE_UNQUOTED([uintptr_t], [$ac_type],
|
||||||
|
[Define to the type of an unsigned integer type wide enough to
|
||||||
|
hold a pointer, if such a type exists, and if the system
|
||||||
|
does not define it.]) ac_cv_c_uintptr_t="$ac_type"
|
||||||
|
ac_type=])
|
||||||
|
test -z "$ac_type" && break
|
||||||
|
done])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl IPv6 support macros..pretty much swiped from wget
|
||||||
|
|
||||||
|
dnl RB_PROTO_INET6
|
||||||
|
|
||||||
|
AC_DEFUN([RB_PROTO_INET6],[
|
||||||
|
AC_CACHE_CHECK([for INET6 protocol support], [rb_cv_proto_inet6],[
|
||||||
|
AC_TRY_CPP([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#ifndef PF_INET6
|
||||||
|
#error Missing PF_INET6
|
||||||
|
#endif
|
||||||
|
#ifndef AF_INET6
|
||||||
|
#error Mlssing AF_INET6
|
||||||
|
#endif
|
||||||
|
],[
|
||||||
|
rb_cv_proto_inet6=yes
|
||||||
|
],[
|
||||||
|
rb_cv_proto_inet6=no
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
if test "X$rb_cv_proto_inet6" = "Xyes"; then :
|
||||||
|
$1
|
||||||
|
else :
|
||||||
|
$2
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
AC_DEFUN([RB_TYPE_STRUCT_SOCKADDR_IN6],[
|
||||||
|
rb_have_sockaddr_in6=
|
||||||
|
AC_CHECK_TYPES([struct sockaddr_in6],[
|
||||||
|
rb_have_sockaddr_in6=yes
|
||||||
|
],[
|
||||||
|
rb_have_sockaddr_in6=no
|
||||||
|
],[
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
])
|
||||||
|
|
||||||
|
if test "X$rb_have_sockaddr_in6" = "Xyes"; then :
|
||||||
|
$1
|
||||||
|
else :
|
||||||
|
$2
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
AC_DEFUN([RB_CHECK_TIMER_CREATE],
|
||||||
|
[AC_CACHE_CHECK([for a working timer_create(CLOCK_REALTIME)],
|
||||||
|
[rb__cv_timer_create_works],
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#ifdef HAVE_TIME_H
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SIGNAL_H
|
||||||
|
#include <signal.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
#if HAVE_TIMER_CREATE
|
||||||
|
struct sigevent ev;
|
||||||
|
timer_t timer;
|
||||||
|
ev.sigev_notify = SIGEV_SIGNAL;
|
||||||
|
ev.sigev_signo = SIGVTALRM;
|
||||||
|
if (timer_create(CLOCK_REALTIME, &ev, &timer) != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[rb__cv_timer_create_works=yes],
|
||||||
|
[rb__cv_timer_create_works=no])
|
||||||
|
])
|
||||||
|
case $rb__cv_timer_create_works in
|
||||||
|
yes) AC_DEFINE([USE_TIMER_CREATE], 1,
|
||||||
|
[Define to 1 if we can use timer_create(CLOCK_REALTIME,...)]);;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
7583
libratbox/aclocal.m4
vendored
Normal file
7583
libratbox/aclocal.m4
vendored
Normal file
File diff suppressed because it is too large
Load diff
1516
libratbox/config.guess
vendored
Executable file
1516
libratbox/config.guess
vendored
Executable file
File diff suppressed because it is too large
Load diff
1626
libratbox/config.sub
vendored
Executable file
1626
libratbox/config.sub
vendored
Executable file
File diff suppressed because it is too large
Load diff
27656
libratbox/configure
vendored
Executable file
27656
libratbox/configure
vendored
Executable file
File diff suppressed because it is too large
Load diff
675
libratbox/configure.ac
Normal file
675
libratbox/configure.ac
Normal file
|
@ -0,0 +1,675 @@
|
||||||
|
dnl $Id: configure.ac 23020 2006-09-01 18:20:19Z androsyn $
|
||||||
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
dnl TODO: clean up all the OpenSSL and shared module checking stuff;
|
||||||
|
dnl the most major changes have already been made and it looks like
|
||||||
|
dnl said functions need to be just about as complex as they already are.
|
||||||
|
|
||||||
|
AC_PREREQ(2.60)
|
||||||
|
AUTOMAKE_OPTIONS = 1.10
|
||||||
|
dnl Sneaky way to get an Id tag into the configure script
|
||||||
|
AC_COPYRIGHT([$Id: configure.ac 23020 2006-09-01 18:20:19Z androsyn $])
|
||||||
|
AC_INIT([libratbox],[devel])
|
||||||
|
AM_INIT_AUTOMAKE(AC_PACKAGE_TARNAME, AC_PACKAGE_VERSION, -)
|
||||||
|
|
||||||
|
AM_CONFIG_HEADER(include/libratbox_config.h)
|
||||||
|
|
||||||
|
AC_PREFIX_DEFAULT(/usr/local/libratbox)
|
||||||
|
AC_GNU_SOURCE
|
||||||
|
|
||||||
|
dnl Checks for programs.
|
||||||
|
AC_PROG_CC_C99
|
||||||
|
|
||||||
|
if test x"$ac_cv_prog_cc_c99" = "xno"; then
|
||||||
|
AC_ERROR([ircd-ratbox requires a C99 capable compiler])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
AC_PROG_EGREP
|
||||||
|
AC_PROG_SED
|
||||||
|
|
||||||
|
F77=no
|
||||||
|
CXX=no
|
||||||
|
GCJ=no
|
||||||
|
|
||||||
|
AM_DISABLE_STATIC
|
||||||
|
AM_ENABLE_SHARED
|
||||||
|
AM_MAINTAINER_MODE
|
||||||
|
|
||||||
|
AC_ISC_POSIX
|
||||||
|
AC_C_INLINE
|
||||||
|
AC_C_CONST
|
||||||
|
AC_PROG_MAKE_SET
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
AC_PATH_PROG(AUTOMAKE, automake)
|
||||||
|
AC_PATH_PROG(ACLOCAL, aclocal)
|
||||||
|
AC_PATH_PROG(AUTOHEADER, autoheader)
|
||||||
|
AC_PATH_PROG(AS, as)
|
||||||
|
AC_PATH_PROG(RM, rm)
|
||||||
|
AC_PATH_PROG(CP, cp)
|
||||||
|
AC_PATH_PROG(MV, mv)
|
||||||
|
AC_PATH_PROG(LN, ln)
|
||||||
|
AC_PATH_PROG(AR, ar)
|
||||||
|
AC_PATH_PROG(LD, ld)
|
||||||
|
AC_PATH_PROG(RANLIB, ranlib)
|
||||||
|
AC_PATH_PROG(TOUCH, touch)
|
||||||
|
AC_LANG(C)
|
||||||
|
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
|
||||||
|
LIBTOOL="$LIBTOOL --silent"
|
||||||
|
|
||||||
|
AC_CONFIG_SUBDIRS(libltdl)
|
||||||
|
|
||||||
|
|
||||||
|
case "$host_os" in
|
||||||
|
*cygwin*)
|
||||||
|
AC_DEFINE_UNQUOTED(CYGWIN,1,[This is a Cygwin system])
|
||||||
|
AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
|
||||||
|
;;
|
||||||
|
*mingw*)
|
||||||
|
AC_DEFINE_UNQUOTED(MINGW,1,[This is a MinGW system])
|
||||||
|
AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
|
||||||
|
AC_CHECK_HEADER(windows.h, , [AC_MSG_ERROR([** MinGW and no windows.h. I give up.])])
|
||||||
|
AC_CHECK_HEADER(winsock2.h, , [AC_MSG_ERROR([** MinGW and no winsock2.h. I give up.])])
|
||||||
|
LIBS="$LIBS -lws2_32 -liphlpapi"
|
||||||
|
is_mingw="yes"
|
||||||
|
;;
|
||||||
|
*interix*)
|
||||||
|
CPPFLAGS="$CFLAGS -D_ALL_SOURCE -D_XOPEN_SOURCE=500"
|
||||||
|
;;
|
||||||
|
*solaris*)
|
||||||
|
CPPFLAGS="$CFLAGS -D_POSIX_PTHREAD_SEMANTICS"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
AM_CONDITIONAL([MINGW], [test "$is_mingw" = "yes"])
|
||||||
|
|
||||||
|
|
||||||
|
# backwards support for IRC_CFLAGS
|
||||||
|
CFLAGS="$IRC_CFLAGS $CFLAGS -O0 -Wall"
|
||||||
|
|
||||||
|
dnl use directory structure of cached as default (hack)
|
||||||
|
if test "$libexecdir" = '${exec_prefix}/libexec' &&
|
||||||
|
test "$localstatedir" = '${prefix}/var'; then
|
||||||
|
libexecdir='${bindir}'
|
||||||
|
localstatedir='${prefix}'
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_TYPE_INT8_T
|
||||||
|
AC_TYPE_INT16_T
|
||||||
|
AC_TYPE_INT32_T
|
||||||
|
AC_TYPE_INT64_T
|
||||||
|
AC_TYPE_UINT8_T
|
||||||
|
AC_TYPE_UINT16_T
|
||||||
|
AC_TYPE_UINT32_T
|
||||||
|
AC_TYPE_UINT64_T
|
||||||
|
|
||||||
|
RB_TYPE_INTPTR_T
|
||||||
|
RB_TYPE_INTMAX_T
|
||||||
|
RB_TYPE_UINTMAX_T
|
||||||
|
RB_TYPE_UINTPTR_T
|
||||||
|
|
||||||
|
AC_TYPE_PID_T
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
AC_TYPE_SSIZE_T
|
||||||
|
AC_TYPE_UID_T
|
||||||
|
|
||||||
|
|
||||||
|
dnl Checks for header files.
|
||||||
|
AC_HEADER_STDC
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS([crypt.h unistd.h sys/socket.h sys/stat.h sys/time.h time.h netinet/in.h arpa/inet.h errno.h sys/uio.h spawn.h sys/poll.h sys/epoll.h sys/select.h sys/devpoll.h sys/event.h port.h signal.h sys/signalfd.h])
|
||||||
|
AC_HEADER_TIME
|
||||||
|
|
||||||
|
dnl Networking Functions
|
||||||
|
dnl ====================
|
||||||
|
|
||||||
|
AC_SEARCH_LIBS(socket, [socket],,)
|
||||||
|
|
||||||
|
|
||||||
|
AC_CHECK_MEMBER([struct sockaddr.sa_len], [AC_DEFINE(SOCKADDR_IN_HAS_LEN, 1, [Define to 1 if sockaddr has a 'sa_len'
|
||||||
|
member.])],,[[
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
]])
|
||||||
|
|
||||||
|
AC_CHECK_TYPE(socklen_t, ,
|
||||||
|
[AC_DEFINE([socklen_t], [unsigned int],
|
||||||
|
[If we don't have a real socklen_t, unsigned int is good enough.])],
|
||||||
|
[
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(ipv6,AC_HELP_STRING([--disable-ipv6],[Disable IPv6 support]),[ipv6=$enableval],[ipv6=yes])
|
||||||
|
|
||||||
|
if test x$ipv6 != xyes; then
|
||||||
|
have_v6="no"
|
||||||
|
else
|
||||||
|
|
||||||
|
have_v6=yes
|
||||||
|
RB_PROTO_INET6([], [
|
||||||
|
AC_MSG_NOTICE([Disabling IPv6 support: PF_INET6 not found])
|
||||||
|
have_v6=no
|
||||||
|
])
|
||||||
|
|
||||||
|
if test "X$have_v6" = "Xyes"; then
|
||||||
|
RB_TYPE_STRUCT_SOCKADDR_IN6([], [
|
||||||
|
AC_MSG_NOTICE([Disabling IPv6 support: struct sockaddr_in6 not found])
|
||||||
|
have_v6=no
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_TYPES([struct sockaddr_storage],[
|
||||||
|
rb_have_sockaddr_storage=yes
|
||||||
|
],[], [
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
save_LIBS=$LIBS
|
||||||
|
AC_SEARCH_LIBS(crypt, [crypt descrypt],,)
|
||||||
|
LIBS=$save_LIBS
|
||||||
|
|
||||||
|
CRYPT_LIB=$ac_cv_search_crypt
|
||||||
|
|
||||||
|
if test "$CRYPT_LIB" = "none required"; then
|
||||||
|
unset CRYPT_LIB
|
||||||
|
elif test "$CRYPT_LIB" = no; then
|
||||||
|
need_crypt=yes;
|
||||||
|
AC_DEFINE(NEED_CRYPT, 1, [Define if your system needs crypt.])
|
||||||
|
unset CRYPT_LIB
|
||||||
|
fi
|
||||||
|
|
||||||
|
AM_CONDITIONAL([NEED_CRYPT], [test x"$need_crypt" == "xyes"])
|
||||||
|
|
||||||
|
|
||||||
|
AC_SUBST(CRYPT_LIB)
|
||||||
|
|
||||||
|
dnl Check for stdarg.h - if we cant find it, halt configure
|
||||||
|
AC_CHECK_HEADER(stdarg.h, , [AC_MSG_ERROR([** stdarg.h could not be found - libratbox will not compile without it **])])
|
||||||
|
|
||||||
|
AC_CHECK_TYPE([sa_family_t], [],
|
||||||
|
[AC_DEFINE(sa_family_t, [u_int16_t], [If system does not define sa_family_t, define it here.])],
|
||||||
|
[[#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>]])
|
||||||
|
|
||||||
|
|
||||||
|
dnl check for various functions...
|
||||||
|
AC_CHECK_FUNCS([socketpair gettimeofday writev sendmsg gmtime_r strtok_r usleep posix_spawn strlcpy strlcat strnlen fstat signalfd select poll kevent port_create epoll_ctl])
|
||||||
|
|
||||||
|
AC_SEARCH_LIBS(nanosleep, rt posix4, AC_DEFINE(HAVE_NANOSLEEP, 1, [Define if you have nanosleep]))
|
||||||
|
AC_SEARCH_LIBS(timer_create, rt, AC_DEFINE(HAVE_TIMER_CREATE, 1, [Define if you have timer_create]))
|
||||||
|
RB_CHECK_TIMER_CREATE
|
||||||
|
|
||||||
|
AC_FUNC_ALLOCA
|
||||||
|
AC_FUNC_VFORK
|
||||||
|
AC_FUNC_MMAP
|
||||||
|
|
||||||
|
AC_MSG_CHECKING(for /dev/poll)
|
||||||
|
if test -c "/dev/poll"; then
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_DEVPOLL, [1], [Define to 1 if you have devpoll])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test "$is_mingw" = "yes"; then
|
||||||
|
AC_DEFINE(HAVE_WIN32, [1], [Define to 1 if you are on windows])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl OpenSSL support
|
||||||
|
AC_MSG_CHECKING(for OpenSSL)
|
||||||
|
AC_ARG_ENABLE(openssl,
|
||||||
|
[AC_HELP_STRING([--enable-openssl[=DIR]],[Enable OpenSSL support (DIR optional).])
|
||||||
|
AC_HELP_STRING([--disable-openssl],[Disable OpenSSL support.])],
|
||||||
|
[cf_enable_openssl=$enableval],
|
||||||
|
[cf_enable_openssl="auto"])
|
||||||
|
|
||||||
|
if test "$cf_enable_openssl" != "no" ; then
|
||||||
|
cf_openssl_basedir=""
|
||||||
|
if test "$cf_enable_openssl" != "auto" &&
|
||||||
|
test "$cf_enable_openssl" != "yes" ; then
|
||||||
|
dnl Support for --enable-openssl=/some/place
|
||||||
|
cf_openssl_basedir="`echo ${cf_enable_openssl} | sed 's/\/$//'`"
|
||||||
|
else
|
||||||
|
dnl Do the auto-probe here. Check some common directory paths.
|
||||||
|
for dirs in /usr/local/ssl /usr/pkg /usr/local \
|
||||||
|
/usr/local/openssl ; do
|
||||||
|
if test -f "${dirs}/include/openssl/opensslv.h" ; then
|
||||||
|
cf_openssl_basedir="${dirs}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
unset dirs
|
||||||
|
fi
|
||||||
|
dnl Now check cf_openssl_found to see if we found anything.
|
||||||
|
if test ! -z "$cf_openssl_basedir"; then
|
||||||
|
if test -f "${cf_openssl_basedir}/include/openssl/opensslv.h" ; then
|
||||||
|
SSL_INCLUDES="-I${cf_openssl_basedir}/include"
|
||||||
|
SSL_LIBS="-L${cf_openssl_basedir}/lib"
|
||||||
|
else
|
||||||
|
dnl OpenSSL wasn't found in the directory specified. Naughty
|
||||||
|
dnl administrator...
|
||||||
|
cf_openssl_basedir=""
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
dnl Check for stock FreeBSD 4.x and 5.x systems, since their files
|
||||||
|
dnl are in /usr/include and /usr/lib. In this case, we don't want to
|
||||||
|
dnl change INCLUDES or LIBS, but still want to enable OpenSSL.
|
||||||
|
dnl We can't do this check above, because some people want two versions
|
||||||
|
dnl of OpenSSL installed (stock FreeBSD 4.x/5.x and /usr/local/ssl)
|
||||||
|
dnl and they want /usr/local/ssl to have preference.
|
||||||
|
if test -f "/usr/include/openssl/opensslv.h" ; then
|
||||||
|
cf_openssl_basedir="/usr"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl If we have a basedir defined, then everything is okay. Otherwise,
|
||||||
|
dnl we have a problem.
|
||||||
|
if test ! -z "$cf_openssl_basedir"; then
|
||||||
|
AC_MSG_RESULT($cf_openssl_basedir)
|
||||||
|
cf_enable_openssl="yes"
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([not found. Specify a correct path?])
|
||||||
|
cf_enable_openssl="no"
|
||||||
|
fi
|
||||||
|
unset cf_openssl_basedir
|
||||||
|
else
|
||||||
|
dnl If --disable-openssl was specified
|
||||||
|
AC_MSG_RESULT(disabled)
|
||||||
|
fi
|
||||||
|
|
||||||
|
save_CPPFLAGS="$CPPFLAGS"
|
||||||
|
CPPFLAGS="$CPPFLAGS $SSL_INCLUDES"
|
||||||
|
save_LIBS="$LIBS"
|
||||||
|
LIBS="$LIBS $SSL_LIBS"
|
||||||
|
if test "$cf_enable_openssl" != no; then
|
||||||
|
dnl Check OpenSSL version (must be 0.9.7 or above!)
|
||||||
|
AC_MSG_CHECKING(for OpenSSL 0.9.7 or above)
|
||||||
|
AC_RUN_IFELSE(
|
||||||
|
AC_LANG_PROGRAM(
|
||||||
|
[#include <openssl/opensslv.h>
|
||||||
|
#include <stdlib.h>],
|
||||||
|
[[if (OPENSSL_VERSION_NUMBER >= 0x00907000)
|
||||||
|
exit(0); else exit(1);]]),
|
||||||
|
cf_enable_openssl=yes,
|
||||||
|
cf_enable_openssl=no,
|
||||||
|
cf_enable_openssl=no)
|
||||||
|
|
||||||
|
if test "$cf_enable_openssl" != no; then
|
||||||
|
AC_MSG_RESULT(found)
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no - OpenSSL support disabled)
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test "$cf_enable_openssl" != no; then
|
||||||
|
CPPFLAGS="$CPPFLAGS $SSL_LIBS"
|
||||||
|
AC_CHECK_LIB(crypto, RAND_status,
|
||||||
|
[cf_enable_openssl=yes],
|
||||||
|
[cf_enable_openssl=no])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test "$cf_enable_openssl" != no; then
|
||||||
|
CPPFLAGS="$CPPFLAGS $SSL_LIBS"
|
||||||
|
AC_CHECK_LIB(ssl, SSL_read,
|
||||||
|
[SSL_LIBS="-lssl -lcrypto"],
|
||||||
|
[cf_enable_openssl=no], [-lcrypto])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$cf_enable_openssl" != no; then
|
||||||
|
AC_DEFINE(HAVE_OPENSSL,1,[Has OpenSSL])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
CPPFLAGS="$save_CPPFLAGS"
|
||||||
|
LIBS="$save_LIBS"
|
||||||
|
|
||||||
|
dnl End OpenSSL detection
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dnl Debug-related options
|
||||||
|
dnl =====================
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(assert,
|
||||||
|
AC_HELP_STRING([--enable-assert],[Enable assert(). Choose between soft(warnings) and hard(aborts the daemon)]),
|
||||||
|
[assert=$enableval], [assert=no])
|
||||||
|
|
||||||
|
if test "$assert" = no; then
|
||||||
|
AC_DEFINE(NDEBUG, 1, [Define this to disable debugging support.])
|
||||||
|
elif test "$assert" = soft; then
|
||||||
|
AC_DEFINE(SOFT_ASSERT, 1, [Define this to enable soft asserts.])
|
||||||
|
AC_DEFINE(NDEBUG, 1, [Define this to disable debugging support.])
|
||||||
|
elif test "$assert" = yes; then
|
||||||
|
assert = "hard";
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_CHECKING(if you want to do a profile build)
|
||||||
|
AC_ARG_ENABLE(profile,
|
||||||
|
AC_HELP_STRING([--enable-profile],[Enable profiling]),
|
||||||
|
[profile=$enableval], [profile=no])
|
||||||
|
|
||||||
|
if test "$profile" = yes; then
|
||||||
|
if test "$ac_cv_c_compiler_gnu" = yes; then
|
||||||
|
CFLAGS="$CFLAGS -pg -static"
|
||||||
|
AC_MSG_RESULT([yes, adding -pg -static])
|
||||||
|
AC_DEFINE(RATBOX_PROFILE, 1, [Defined to mark profiling is enabled])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no, profile builds only work with gcc])
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(balloc,
|
||||||
|
AC_HELP_STRING([--disable-balloc],[Disable the block allocator.]),
|
||||||
|
[balloc=$enableval], [balloc=yes])
|
||||||
|
|
||||||
|
if test "$balloc" = no; then
|
||||||
|
AC_DEFINE([NOBALLOC], 1, [Define to 1 if you wish to disable the block allocator.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(warnings,
|
||||||
|
AC_HELP_STRING([--enable-warnings],[Enable all sorts of warnings for debugging.]),
|
||||||
|
[CFLAGS="$CFLAGS -Wall -Werror -Wcast-qual -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings -W -Wno-unused -Wunused-function -Wunused-variable"],[])
|
||||||
|
|
||||||
|
AC_SUBST(LDFLAGS)
|
||||||
|
AC_SUBST(PICFLAGS)
|
||||||
|
AC_SUBST(CFLAGS)
|
||||||
|
AC_SUBST(SEDOBJ)
|
||||||
|
AC_SUBST(SSL_INCLUDES)
|
||||||
|
AC_SUBST(SSL_LIBS)
|
||||||
|
|
||||||
|
|
||||||
|
if test "$prefix" = "NONE"; then
|
||||||
|
AC_DEFINE_UNQUOTED(RB_PREFIX, "$ac_default_prefix", [Prefix where libratbox is installed.])
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
dnl Don't get bitten by Cygwin's stupidity if the user specified
|
||||||
|
dnl a custom prefix with a trailing slash
|
||||||
|
|
||||||
|
prefix=`echo $prefix | sed 's/\/$//'`
|
||||||
|
AC_DEFINE_UNQUOTED(RB_PREFIX, "$prefix", [Prefix where libratbox is installed.])
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(RB_PREFIX)
|
||||||
|
|
||||||
|
for dtype in uint64_t uint32_t uint16_t uint8_t int64_t int32_t int16_t int8_t intmax_t intptr_t uintmax_t uintptr_t
|
||||||
|
do
|
||||||
|
var="\$ac_cv_c_${dtype}"
|
||||||
|
t_type=$(eval echo $var);
|
||||||
|
if test "x$t_type" = "xyes"; then
|
||||||
|
eval rb_$dtype="\"$dtype\""
|
||||||
|
else
|
||||||
|
eval rb_$dtype="\"$t_type\""
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
AC_CONFIG_COMMANDS([include/librb-config.h],
|
||||||
|
[
|
||||||
|
outfile=include/librb-config.h.tmp
|
||||||
|
cat > $outfile <<\_______EOF
|
||||||
|
/*
|
||||||
|
* librb-config.h: libratbox config file. Please modify configure.ac
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LIBRB_CONFIG_H
|
||||||
|
#define __LIBRB_CONFIG_H
|
||||||
|
|
||||||
|
_______EOF
|
||||||
|
|
||||||
|
if test "x$rb_have_ipv6" = "xyes"; then
|
||||||
|
echo "#define RB_IPV6 1" >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_windows_h" = "xyes"; then
|
||||||
|
echo '#define WIN32_LEAN_AND_MEAN 1' >> $outfile
|
||||||
|
echo '#include <windows.h>' >> $outfile
|
||||||
|
echo '#include <winsock2.h>' >> $outfile
|
||||||
|
echo '#include <iphlpapi.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_alloca_h" = "xyes"; then
|
||||||
|
echo '#define RB_HAVE_ALLOCA_H 1' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_header_stdc" = "xyes"; then
|
||||||
|
echo '#include <stdlib.h>' >> $outfile
|
||||||
|
echo '#include <stddef.h>' >> $outfile
|
||||||
|
elif test "x$rb_header_stdlib" = "xyes"; then
|
||||||
|
echo '#include <stdlib.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_header_string_h" = "xyes"; then
|
||||||
|
echo '#include <string.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_stdint_h" = "xyes"; then
|
||||||
|
echo '#include <stdint.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_inttypes_h" = "xyes"; then
|
||||||
|
echo '#include <inttypes.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_sys_types_h" = "xyes"; then
|
||||||
|
echo '#include <sys/types.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
if test "x$rb_sys_time_h" = "xyes"; then
|
||||||
|
echo '#include <sys/time.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
if test "x$rb_sys_stat_h" = "xyes"; then
|
||||||
|
echo '#include <sys/stat.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
if test "x$rb_time_h" = "xyes"; then
|
||||||
|
echo '#include <time.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_sys_socket_h" = "xyes"; then
|
||||||
|
echo '#include <sys/socket.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_netinet_in_h" = "xyes"; then
|
||||||
|
echo '#include <netinet/in.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_arpa_inet_h" = "xyes"; then
|
||||||
|
echo '#include <arpa/inet.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_unistd_h" = "xyes"; then
|
||||||
|
echo '#include <unistd.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_crypt_h" = "xyes"; then
|
||||||
|
echo '#include <crypt.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_errno_h" = "xyes"; then
|
||||||
|
echo '#include <errno.h>' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$rb_sockaddr_sa_len" = "xyes"; then
|
||||||
|
echo '#define RB_SOCKADDR_HAS_SA_LEN 1' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "typedef $rb_uint64_t rb_uint64_t;" >> $outfile
|
||||||
|
echo "typedef $rb_uint32_t rb_uint32_t;" >> $outfile
|
||||||
|
echo "typedef $rb_uint16_t rb_uint16_t;" >> $outfile
|
||||||
|
echo "typedef $rb_uint8_t rb_uint8_t;" >> $outfile
|
||||||
|
echo "typedef $rb_int64_t rb_int64_t;" >> $outfile
|
||||||
|
echo "typedef $rb_int32_t rb_int32_t;" >> $outfile
|
||||||
|
echo "typedef $rb_int16_t rb_int16_t;" >> $outfile
|
||||||
|
echo "typedef $rb_int8_t rb_int8_t;" >> $outfile
|
||||||
|
echo "typedef $rb_intmax_t rb_intmax_t;" >> $outfile
|
||||||
|
echo "typedef $rb_intptr_t rb_intptr_t;" >> $outfile
|
||||||
|
echo "typedef $rb_uintmax_t rb_uintmax_t;" >> $outfile
|
||||||
|
echo "typedef $rb_uintptr_t rb_uintptr_t;" >> $outfile
|
||||||
|
echo "typedef $rb_socklen_t rb_socklen_t;" >> $outfile
|
||||||
|
|
||||||
|
if test "x$rb_sockaddr_storage" = "xyes"; then
|
||||||
|
echo '#define rb_sockaddr_storage sockaddr_storage' >> $outfile
|
||||||
|
else
|
||||||
|
echo 'struct rb_sockaddr_storage { rb_uint8_t _padding[128]; };' >> $outfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat >> $outfile <<\_______EOF
|
||||||
|
#endif /* __LIBRB_CONFIG_H */
|
||||||
|
_______EOF
|
||||||
|
|
||||||
|
if cmp -s $outfile include/librb-config.h; then
|
||||||
|
AC_MSG_NOTICE([include/librb-config.h is unchanged])
|
||||||
|
${rb_rm} -f $outfile
|
||||||
|
else
|
||||||
|
${rb_mv} $outfile include/librb-config.h
|
||||||
|
fi
|
||||||
|
|
||||||
|
],[
|
||||||
|
rb_uint64_t="$rb_uint64_t"
|
||||||
|
rb_uint32_t="$rb_uint32_t"
|
||||||
|
rb_uint16_t="$rb_uint16_t"
|
||||||
|
rb_uint8_t="$rb_uint8_t"
|
||||||
|
rb_int64_t="$rb_int64_t"
|
||||||
|
rb_int32_t="$rb_int32_t"
|
||||||
|
rb_int16_t="$rb_int16_t"
|
||||||
|
rb_int8_t="$rb_int8_t"
|
||||||
|
rb_intmax_t="$rb_intmax_t"
|
||||||
|
rb_intptr_t="$rb_intptr_t"
|
||||||
|
rb_uintmax_t="$rb_uintmax_t"
|
||||||
|
rb_uintptr_t="$rb_uintptr_t"
|
||||||
|
if test x$ac_cv_header_stdc = xyes; then
|
||||||
|
rb_header_stdc=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_stdlib_h = xyes; then
|
||||||
|
rb_header_stdlib_h=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_string_h = xyes; then
|
||||||
|
rb_header_string_h=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_memory_h = xyes; then
|
||||||
|
rb_header_memory_h=yes
|
||||||
|
fi
|
||||||
|
if test "x${ac_cv_working_alloca_h+set}" = xset ; then
|
||||||
|
rb_alloca_h="$ac_cv_working_alloca_h"
|
||||||
|
else
|
||||||
|
rb_alloc_h="$ac_cv_header_alloca_h"
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_member_struct_sockaddr_sa_len = xyes; then
|
||||||
|
rb_sockaddr_sa_len=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_sys_socket_h = xyes; then
|
||||||
|
rb_sys_socket_h=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_sys_types_h = xyes; then
|
||||||
|
rb_sys_types_h=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_sys_stat_h = xyes; then
|
||||||
|
rb_sys_stat_h=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_sys_time_h = xyes; then
|
||||||
|
rb_sys_time_h=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_time = xyes; then
|
||||||
|
rb_time_h=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$ac_cv_header_stdint_h = xyes; then
|
||||||
|
rb_stdint_h=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_inttypes_h = xyes; then
|
||||||
|
rb_inttypes_h=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_netinet_in_h = xyes; then
|
||||||
|
rb_netinet_in_h=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$ac_cv_header_crypt_h = xyes; then
|
||||||
|
rb_crypt_h=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_errno_h = xyes; then
|
||||||
|
rb_errno_h=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_unistd_h = xyes; then
|
||||||
|
rb_unistd_h=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_windows_h = xyes; then
|
||||||
|
rb_windows_h=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_header_winsock2_h = xyes; then
|
||||||
|
rb_winsock2_h=yes
|
||||||
|
fi
|
||||||
|
if test x$ac_cv_type_socklen_t = xyes; then
|
||||||
|
rb_socklen_t="socklen_t"
|
||||||
|
else
|
||||||
|
rb_socklen_t="unsigned int"
|
||||||
|
fi
|
||||||
|
if test "x$rb_have_sockaddr_storage" = "xyes"; then
|
||||||
|
rb_sockaddr_storage="yes"
|
||||||
|
else
|
||||||
|
rb_sockaddr_storage="no"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rb_have_ipv6="$have_v6"
|
||||||
|
|
||||||
|
rb_mv="$MV"
|
||||||
|
rb_rm="$RM"
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
AC_CONFIG_FILES( \
|
||||||
|
src/Makefile \
|
||||||
|
Makefile \
|
||||||
|
)
|
||||||
|
|
||||||
|
AC_OUTPUT
|
||||||
|
|
||||||
|
dnl Make it look sexay!
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Compiling $PACKAGE_NAME $PACKAGE_VERSION"
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "Installing into: $prefix"
|
||||||
|
|
||||||
|
echo "IPv6 support ................... $have_v6"
|
||||||
|
echo "Assert debugging ............... $assert"
|
||||||
|
echo "Block allocator ................ $balloc"
|
||||||
|
echo "OpenSSL ........................ $cf_enable_openssl"
|
||||||
|
echo
|
||||||
|
|
526
libratbox/depcomp
Executable file
526
libratbox/depcomp
Executable file
|
@ -0,0 +1,526 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# depcomp - compile a program generating dependencies as side-effects
|
||||||
|
|
||||||
|
scriptversion=2004-04-25.13
|
||||||
|
|
||||||
|
# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
'')
|
||||||
|
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||||
|
exit 1;
|
||||||
|
;;
|
||||||
|
-h | --h*)
|
||||||
|
cat <<\EOF
|
||||||
|
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||||
|
|
||||||
|
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||||
|
as side-effects.
|
||||||
|
|
||||||
|
Environment variables:
|
||||||
|
depmode Dependency tracking mode.
|
||||||
|
source Source file read by `PROGRAMS ARGS'.
|
||||||
|
object Object file output by `PROGRAMS ARGS'.
|
||||||
|
depfile Dependency file to output.
|
||||||
|
tmpdepfile Temporary file to use when outputing dependencies.
|
||||||
|
libtool Whether libtool is used (yes/no).
|
||||||
|
|
||||||
|
Report bugs to <bug-automake@gnu.org>.
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-v | --v*)
|
||||||
|
echo "depcomp $scriptversion"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||||
|
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# `libtool' can also be set to `yes' or `no'.
|
||||||
|
|
||||||
|
if test -z "$depfile"; then
|
||||||
|
base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
|
||||||
|
dir=`echo "$object" | sed 's,/.*$,/,'`
|
||||||
|
if test "$dir" = "$object"; then
|
||||||
|
dir=
|
||||||
|
fi
|
||||||
|
# FIXME: should be _deps on DOS.
|
||||||
|
depfile="$dir.deps/$base"
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||||
|
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
|
||||||
|
# Some modes work just like other modes, but use different flags. We
|
||||||
|
# parameterize here, but still list the modes in the big case below,
|
||||||
|
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||||
|
# here, because this file can only contain one case statement.
|
||||||
|
if test "$depmode" = hp; then
|
||||||
|
# HP compiler uses -M and no extra arg.
|
||||||
|
gccflag=-M
|
||||||
|
depmode=gcc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$depmode" = dashXmstdout; then
|
||||||
|
# This is just like dashmstdout with a different argument.
|
||||||
|
dashmflag=-xM
|
||||||
|
depmode=dashmstdout
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$depmode" in
|
||||||
|
gcc3)
|
||||||
|
## gcc 3 implements dependency tracking that does exactly what
|
||||||
|
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||||
|
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||||
|
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
mv "$tmpdepfile" "$depfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
gcc)
|
||||||
|
## There are various ways to get dependency output from gcc. Here's
|
||||||
|
## why we pick this rather obscure method:
|
||||||
|
## - Don't want to use -MD because we'd like the dependencies to end
|
||||||
|
## up in a subdir. Having to rename by hand is ugly.
|
||||||
|
## (We might end up doing this anyway to support other compilers.)
|
||||||
|
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||||
|
## -MM, not -M (despite what the docs say).
|
||||||
|
## - Using -M directly means running the compiler twice (even worse
|
||||||
|
## than renaming).
|
||||||
|
if test -z "$gccflag"; then
|
||||||
|
gccflag=-MD,
|
||||||
|
fi
|
||||||
|
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||||
|
## The second -e expression handles DOS-style file names with drive letters.
|
||||||
|
sed -e 's/^[^:]*: / /' \
|
||||||
|
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||||
|
## This next piece of magic avoids the `deleted header file' problem.
|
||||||
|
## The problem is that when a header file which appears in a .P file
|
||||||
|
## is deleted, the dependency causes make to die (because there is
|
||||||
|
## typically no way to rebuild the header). We avoid this by adding
|
||||||
|
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||||
|
## this for us directly.
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" |
|
||||||
|
## Some versions of gcc put a space before the `:'. On the theory
|
||||||
|
## that the space means something, we add a space to the output as
|
||||||
|
## well.
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
hp)
|
||||||
|
# This case exists only to let depend.m4 do its work. It works by
|
||||||
|
# looking at the text of this script. This case will never be run,
|
||||||
|
# since it is checked for above.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
sgi)
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||||
|
else
|
||||||
|
"$@" -MDupdate "$tmpdepfile"
|
||||||
|
fi
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
|
||||||
|
# Clip off the initial element (the dependent). Don't try to be
|
||||||
|
# clever and replace this with sed code, as IRIX sed won't handle
|
||||||
|
# lines with more than a fixed number of characters (4096 in
|
||||||
|
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||||
|
# the IRIX cc adds comments like `#:fec' to the end of the
|
||||||
|
# dependency line.
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
||||||
|
tr '
|
||||||
|
' ' ' >> $depfile
|
||||||
|
echo >> $depfile
|
||||||
|
|
||||||
|
# The second pass generates a dummy entry for each header file.
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||||
|
>> $depfile
|
||||||
|
else
|
||||||
|
# The sourcefile does not contain any dependencies, so just
|
||||||
|
# store a dummy comment line, to avoid errors with the Makefile
|
||||||
|
# "include basename.Plo" scheme.
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
aix)
|
||||||
|
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||||
|
# in a .u file. In older versions, this file always lives in the
|
||||||
|
# current directory. Also, the AIX compiler puts `$object:' at the
|
||||||
|
# start of each line; $object doesn't have directory information.
|
||||||
|
# Version 6 uses the directory in both cases.
|
||||||
|
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
|
||||||
|
tmpdepfile="$stripped.u"
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
"$@" -Wc,-M
|
||||||
|
else
|
||||||
|
"$@" -M
|
||||||
|
fi
|
||||||
|
stat=$?
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile"; then :
|
||||||
|
else
|
||||||
|
stripped=`echo "$stripped" | sed 's,^.*/,,'`
|
||||||
|
tmpdepfile="$stripped.u"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile"; then
|
||||||
|
outname="$stripped.o"
|
||||||
|
# Each line is of the form `foo.o: dependent.h'.
|
||||||
|
# Do two passes, one to just change these to
|
||||||
|
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||||
|
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
|
||||||
|
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
|
||||||
|
else
|
||||||
|
# The sourcefile does not contain any dependencies, so just
|
||||||
|
# store a dummy comment line, to avoid errors with the Makefile
|
||||||
|
# "include basename.Plo" scheme.
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
icc)
|
||||||
|
# Intel's C compiler understands `-MD -MF file'. However on
|
||||||
|
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
|
||||||
|
# ICC 7.0 will fill foo.d with something like
|
||||||
|
# foo.o: sub/foo.c
|
||||||
|
# foo.o: sub/foo.h
|
||||||
|
# which is wrong. We want:
|
||||||
|
# sub/foo.o: sub/foo.c
|
||||||
|
# sub/foo.o: sub/foo.h
|
||||||
|
# sub/foo.c:
|
||||||
|
# sub/foo.h:
|
||||||
|
# ICC 7.1 will output
|
||||||
|
# foo.o: sub/foo.c sub/foo.h
|
||||||
|
# and will wrap long lines using \ :
|
||||||
|
# foo.o: sub/foo.c ... \
|
||||||
|
# sub/foo.h ... \
|
||||||
|
# ...
|
||||||
|
|
||||||
|
"$@" -MD -MF "$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
# Each line is of the form `foo.o: dependent.h',
|
||||||
|
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||||
|
# Do two passes, one to just change these to
|
||||||
|
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||||
|
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||||
|
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
# correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
|
||||||
|
sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
tru64)
|
||||||
|
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||||
|
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
||||||
|
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||||
|
# dependencies in `foo.d' instead, so we check for that too.
|
||||||
|
# Subdirectories are respected.
|
||||||
|
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||||
|
test "x$dir" = "x$object" && dir=
|
||||||
|
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||||
|
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
# Dependencies are output in .lo.d with libtool 1.4.
|
||||||
|
# They are output in .o.d with libtool 1.5.
|
||||||
|
tmpdepfile1="$dir.libs/$base.lo.d"
|
||||||
|
tmpdepfile2="$dir.libs/$base.o.d"
|
||||||
|
tmpdepfile3="$dir.libs/$base.d"
|
||||||
|
"$@" -Wc,-MD
|
||||||
|
else
|
||||||
|
tmpdepfile1="$dir$base.o.d"
|
||||||
|
tmpdepfile2="$dir$base.d"
|
||||||
|
tmpdepfile3="$dir$base.d"
|
||||||
|
"$@" -MD
|
||||||
|
fi
|
||||||
|
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile1"; then
|
||||||
|
tmpdepfile="$tmpdepfile1"
|
||||||
|
elif test -f "$tmpdepfile2"; then
|
||||||
|
tmpdepfile="$tmpdepfile2"
|
||||||
|
else
|
||||||
|
tmpdepfile="$tmpdepfile3"
|
||||||
|
fi
|
||||||
|
if test -f "$tmpdepfile"; then
|
||||||
|
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||||
|
# That's a tab and a space in the [].
|
||||||
|
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||||
|
else
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
#nosideeffect)
|
||||||
|
# This comment above is used by automake to tell side-effect
|
||||||
|
# dependency tracking mechanisms from slower ones.
|
||||||
|
|
||||||
|
dashmstdout)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the preprocessed file to stdout, regardless of -o.
|
||||||
|
"$@" || exit $?
|
||||||
|
|
||||||
|
# Remove the call to Libtool.
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test $1 != '--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove `-o $object'.
|
||||||
|
IFS=" "
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case $arg in
|
||||||
|
-o)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
$object)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift # fnord
|
||||||
|
shift # $arg
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
test -z "$dashmflag" && dashmflag=-M
|
||||||
|
# Require at least two characters before searching for `:'
|
||||||
|
# in the target name. This is to cope with DOS-style filenames:
|
||||||
|
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
|
||||||
|
"$@" $dashmflag |
|
||||||
|
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||||
|
rm -f "$depfile"
|
||||||
|
cat < "$tmpdepfile" > "$depfile"
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" | \
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
dashXmstdout)
|
||||||
|
# This case only exists to satisfy depend.m4. It is never actually
|
||||||
|
# run, as this mode is specially recognized in the preamble.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
makedepend)
|
||||||
|
"$@" || exit $?
|
||||||
|
# Remove any Libtool call
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test $1 != '--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
# X makedepend
|
||||||
|
shift
|
||||||
|
cleared=no
|
||||||
|
for arg in "$@"; do
|
||||||
|
case $cleared in
|
||||||
|
no)
|
||||||
|
set ""; shift
|
||||||
|
cleared=yes ;;
|
||||||
|
esac
|
||||||
|
case "$arg" in
|
||||||
|
-D*|-I*)
|
||||||
|
set fnord "$@" "$arg"; shift ;;
|
||||||
|
# Strip any option that makedepend may not understand. Remove
|
||||||
|
# the object too, otherwise makedepend will parse it as a source file.
|
||||||
|
-*|$object)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"; shift ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
obj_suffix="`echo $object | sed 's/^.*\././'`"
|
||||||
|
touch "$tmpdepfile"
|
||||||
|
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||||
|
rm -f "$depfile"
|
||||||
|
cat < "$tmpdepfile" > "$depfile"
|
||||||
|
sed '1,2d' "$tmpdepfile" | tr ' ' '
|
||||||
|
' | \
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||||
|
;;
|
||||||
|
|
||||||
|
cpp)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the preprocessed file to stdout.
|
||||||
|
"$@" || exit $?
|
||||||
|
|
||||||
|
# Remove the call to Libtool.
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test $1 != '--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove `-o $object'.
|
||||||
|
IFS=" "
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case $arg in
|
||||||
|
-o)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
$object)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift # fnord
|
||||||
|
shift # $arg
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
"$@" -E |
|
||||||
|
sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
|
||||||
|
sed '$ s: \\$::' > "$tmpdepfile"
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
cat < "$tmpdepfile" >> "$depfile"
|
||||||
|
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
msvisualcpp)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the preprocessed file to stdout, regardless of -o,
|
||||||
|
# because we must use -o when running libtool.
|
||||||
|
"$@" || exit $?
|
||||||
|
IFS=" "
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case "$arg" in
|
||||||
|
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||||
|
set fnord "$@"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
"$@" -E |
|
||||||
|
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
||||||
|
echo " " >> "$depfile"
|
||||||
|
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
none)
|
||||||
|
exec "$@"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Unknown depmode $depmode" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: shell-script
|
||||||
|
# sh-indentation: 2
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-end: "$"
|
||||||
|
# End:
|
232
libratbox/include/commio-int.h
Normal file
232
libratbox/include/commio-int.h
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* commio-int.h: A header for the network subsystem.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2002-2007 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: commio.h 24059 2007-07-24 17:25:41Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define RB_FD_HASH_BITS 12
|
||||||
|
#define RB_FD_HASH_SIZE (1UL << RB_FD_HASH_BITS)
|
||||||
|
#define RB_FD_HASH_MASK (RB_FD_HASH_SIZE-1)
|
||||||
|
|
||||||
|
#define FD_DESC_SZ 128 /* hostlen + comment */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define rb_get_errno() do { errno = WSAGetLastError(); WSASetLastError(errno); } while(0)
|
||||||
|
#else
|
||||||
|
#define rb_get_errno()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define rb_hash_fd(x) ((x ^ (x >> RB_FD_HASH_BITS) ^ (x >> (RB_FD_HASH_BITS * 2))) & RB_FD_HASH_MASK)
|
||||||
|
|
||||||
|
#ifdef HAVE_WRITEV
|
||||||
|
#ifndef UIO_MAXIOV
|
||||||
|
# if defined(__FreeBSD__) || defined(__APPLE__) || defined(__NetBSD__)
|
||||||
|
/* FreeBSD 4.7 defines it in sys/uio.h only if _KERNEL is specified */
|
||||||
|
# define RB_UIO_MAXIOV 1024
|
||||||
|
# elif defined(__sgi)
|
||||||
|
/* IRIX 6.5 has sysconf(_SC_IOV_MAX) which might return 512 or bigger */
|
||||||
|
# define RB_UIO_MAXIOV 512
|
||||||
|
# elif defined(__sun)
|
||||||
|
/* Solaris (and SunOS?) defines IOV_MAX instead */
|
||||||
|
# ifndef IOV_MAX
|
||||||
|
# define RB_UIO_MAXIOV 16
|
||||||
|
# else
|
||||||
|
# define RB_UIO_MAXIOV IOV_MAX
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# elif defined(IOV_MAX)
|
||||||
|
# define RB_UIO_MAXIOV IOV_MAX
|
||||||
|
# else
|
||||||
|
# define RB_UIO_MAXIOV 16
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
#define RB_UIO_MAXIOV UIO_MAXIOV
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define RB_UIO_MAXIOV 16
|
||||||
|
#endif
|
||||||
|
struct conndata
|
||||||
|
{
|
||||||
|
/* We don't need the host here ? */
|
||||||
|
struct rb_sockaddr_storage S;
|
||||||
|
struct rb_sockaddr_storage hostaddr;
|
||||||
|
time_t t;
|
||||||
|
CNCB *callback;
|
||||||
|
void *data;
|
||||||
|
/* We'd also add the retry count here when we get to that -- adrian */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct acceptdata
|
||||||
|
{
|
||||||
|
struct rb_sockaddr_storage S;
|
||||||
|
rb_socklen_t addrlen;
|
||||||
|
ACCB *callback;
|
||||||
|
ACPRE *precb;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Only have open flags for now, could be more later */
|
||||||
|
#define FLAG_OPEN 0x1
|
||||||
|
#define IsFDOpen(F) (F->flags & FLAG_OPEN)
|
||||||
|
#define SetFDOpen(F) (F->flags |= FLAG_OPEN)
|
||||||
|
#define ClearFDOpen(F) (F->flags &= ~FLAG_OPEN)
|
||||||
|
|
||||||
|
|
||||||
|
struct _fde
|
||||||
|
{
|
||||||
|
/* New-school stuff, again pretty much ripped from squid */
|
||||||
|
/*
|
||||||
|
* Yes, this gives us only one pending read and one pending write per
|
||||||
|
* filedescriptor. Think though: when do you think we'll need more?
|
||||||
|
*/
|
||||||
|
rb_dlink_node node;
|
||||||
|
int fd; /* So we can use the rb_fde_t as a callback ptr */
|
||||||
|
rb_uint8_t flags;
|
||||||
|
rb_uint8_t type;
|
||||||
|
int pflags;
|
||||||
|
char *desc;
|
||||||
|
PF *read_handler;
|
||||||
|
void *read_data;
|
||||||
|
PF *write_handler;
|
||||||
|
void *write_data;
|
||||||
|
struct timeout_data *timeout;
|
||||||
|
struct conndata *connect;
|
||||||
|
struct acceptdata *accept;
|
||||||
|
void *ssl;
|
||||||
|
unsigned long ssl_errno;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*comm_event_cb_t)(void *);
|
||||||
|
|
||||||
|
#ifdef USE_TIMER_CREATE
|
||||||
|
typedef struct timer_data {
|
||||||
|
timer_t td_timer_id;
|
||||||
|
comm_event_cb_t td_cb;
|
||||||
|
void *td_udata;
|
||||||
|
int td_repeat;
|
||||||
|
} *comm_event_id;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern rb_dlink_list *rb_fd_table;
|
||||||
|
|
||||||
|
static inline rb_fde_t *
|
||||||
|
rb_find_fd(int fd)
|
||||||
|
{
|
||||||
|
rb_dlink_list *hlist;
|
||||||
|
rb_dlink_node *ptr;
|
||||||
|
|
||||||
|
if(unlikely(fd < 0))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
hlist = &rb_fd_table[rb_hash_fd(fd)];
|
||||||
|
|
||||||
|
if(hlist->head == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
RB_DLINK_FOREACH(ptr, hlist->head)
|
||||||
|
{
|
||||||
|
rb_fde_t *F = ptr->data;
|
||||||
|
if(F->fd == fd)
|
||||||
|
return F;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int rb_setup_fd(rb_fde_t *F);
|
||||||
|
void rb_connect_callback(rb_fde_t *F, int status);
|
||||||
|
|
||||||
|
|
||||||
|
int rb_io_sched_event(struct ev_entry *ev, int when);
|
||||||
|
void rb_io_unsched_event(struct ev_entry *ev);
|
||||||
|
int rb_io_supports_event(void);
|
||||||
|
void rb_io_init_event(void);
|
||||||
|
|
||||||
|
/* epoll versions */
|
||||||
|
void rb_setselect_epoll(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
|
||||||
|
int rb_init_netio_epoll(void);
|
||||||
|
int rb_select_epoll(long);
|
||||||
|
int rb_setup_fd_epoll(rb_fde_t *F);
|
||||||
|
|
||||||
|
void rb_epoll_init_event(void);
|
||||||
|
int rb_epoll_sched_event(struct ev_entry *event, int when);
|
||||||
|
void rb_epoll_unsched_event(struct ev_entry *event);
|
||||||
|
int rb_epoll_supports_event(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* poll versions */
|
||||||
|
void rb_setselect_poll(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
|
||||||
|
int rb_init_netio_poll(void);
|
||||||
|
int rb_select_poll(long);
|
||||||
|
int rb_setup_fd_poll(rb_fde_t *F);
|
||||||
|
|
||||||
|
/* devpoll versions */
|
||||||
|
void rb_setselect_devpoll(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
|
||||||
|
int rb_init_netio_devpoll(void);
|
||||||
|
int rb_select_devpoll(long);
|
||||||
|
int rb_setup_fd_devpoll(rb_fde_t *F);
|
||||||
|
|
||||||
|
/* sigio versions */
|
||||||
|
void rb_setselect_sigio(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
|
||||||
|
int rb_init_netio_sigio(void);
|
||||||
|
int rb_select_sigio(long);
|
||||||
|
int rb_setup_fd_sigio(rb_fde_t *F);
|
||||||
|
|
||||||
|
void rb_sigio_init_event(void);
|
||||||
|
int rb_sigio_sched_event(struct ev_entry *event, int when);
|
||||||
|
void rb_sigio_unsched_event(struct ev_entry *event);
|
||||||
|
int rb_sigio_supports_event(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* ports versions */
|
||||||
|
void rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
|
||||||
|
int rb_init_netio_ports(void);
|
||||||
|
int rb_select_ports(long);
|
||||||
|
int rb_setup_fd_ports(rb_fde_t *F);
|
||||||
|
|
||||||
|
/* kqueue versions */
|
||||||
|
void rb_setselect_kqueue(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
|
||||||
|
int rb_init_netio_kqueue(void);
|
||||||
|
int rb_select_kqueue(long);
|
||||||
|
int rb_setup_fd_kqueue(rb_fde_t *F);
|
||||||
|
|
||||||
|
void rb_kqueue_init_event(void);
|
||||||
|
int rb_kqueue_sched_event(struct ev_entry *event, int when);
|
||||||
|
void rb_kqueue_unsched_event(struct ev_entry *event);
|
||||||
|
int rb_kqueue_supports_event(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* select versions */
|
||||||
|
void rb_setselect_select(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
|
||||||
|
int rb_init_netio_select(void);
|
||||||
|
int rb_select_select(long);
|
||||||
|
int rb_setup_fd_select(rb_fde_t *F);
|
||||||
|
|
||||||
|
/* win32 versions */
|
||||||
|
void rb_setselect_win32(rb_fde_t *F, unsigned int type, PF * handler, void *client_data);
|
||||||
|
int rb_init_netio_win32(void);
|
||||||
|
int rb_select_win32(long);
|
||||||
|
int rb_setup_fd_win32(rb_fde_t *F);
|
||||||
|
|
17
libratbox/include/commio-ssl.h
Normal file
17
libratbox/include/commio-ssl.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
int rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile);
|
||||||
|
int rb_init_ssl(void);
|
||||||
|
|
||||||
|
int rb_ssl_listen(rb_fde_t *F, int backlog);
|
||||||
|
int rb_init_prng(const char *path, prng_seed_t seed_type);
|
||||||
|
|
||||||
|
int rb_get_random(void *buf, size_t length);
|
||||||
|
const char *rb_get_ssl_strerror(rb_fde_t *F);
|
||||||
|
void rb_ssl_start_accepted(rb_fde_t *new_F, ACCB *cb, void *data, int timeout);
|
||||||
|
void rb_ssl_start_connected(rb_fde_t *F, CNCB *callback, void *data, int timeout);
|
||||||
|
void rb_connect_tcp_ssl(rb_fde_t *F, struct sockaddr *dest, struct sockaddr *clocal, int socklen, CNCB *callback, void *data, int timeout);
|
||||||
|
void rb_ssl_accept_setup(rb_fde_t *F, int new_fd, struct sockaddr *st, int addrlen);
|
||||||
|
void rb_ssl_shutdown(rb_fde_t *F);
|
||||||
|
ssize_t rb_ssl_read(rb_fde_t *F, void *buf, size_t count);
|
||||||
|
ssize_t rb_ssl_write(rb_fde_t *F, const void *buf, size_t count);
|
||||||
|
|
||||||
|
|
38
libratbox/include/event-int.h
Normal file
38
libratbox/include/event-int.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* event-int.h: internal structs for events
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 ircd-ratbox development team
|
||||||
|
* Copyright (C) 2007 Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: event-int.h 24840 2008-01-03 19:42:17Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
struct ev_entry
|
||||||
|
{
|
||||||
|
rb_dlink_node node;
|
||||||
|
EVH *func;
|
||||||
|
void *arg;
|
||||||
|
const char *name;
|
||||||
|
time_t frequency;
|
||||||
|
time_t when;
|
||||||
|
void *data;
|
||||||
|
void *comm_ptr;
|
||||||
|
};
|
||||||
|
void rb_event_io_register_all(void);
|
374
libratbox/include/libratbox_config.h.in
Normal file
374
libratbox/include/libratbox_config.h.in
Normal file
|
@ -0,0 +1,374 @@
|
||||||
|
/* include/libratbox_config.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||||
|
systems. This function is required for `alloca.c' support on those systems.
|
||||||
|
*/
|
||||||
|
#undef CRAY_STACKSEG_END
|
||||||
|
|
||||||
|
/* This is a Cygwin system */
|
||||||
|
#undef CYGWIN
|
||||||
|
|
||||||
|
/* Define to 1 if using `alloca.c'. */
|
||||||
|
#undef C_ALLOCA
|
||||||
|
|
||||||
|
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||||
|
#undef HAVE_ALLOCA
|
||||||
|
|
||||||
|
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||||
|
*/
|
||||||
|
#undef HAVE_ALLOCA_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||||
|
#undef HAVE_ARPA_INET_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <crypt.h> header file. */
|
||||||
|
#undef HAVE_CRYPT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have devpoll */
|
||||||
|
#undef HAVE_DEVPOLL
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
|
#undef HAVE_DLFCN_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `epoll_ctl' function. */
|
||||||
|
#undef HAVE_EPOLL_CTL
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <errno.h> header file. */
|
||||||
|
#undef HAVE_ERRNO_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fork' function. */
|
||||||
|
#undef HAVE_FORK
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fstat' function. */
|
||||||
|
#undef HAVE_FSTAT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getpagesize' function. */
|
||||||
|
#undef HAVE_GETPAGESIZE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `gettimeofday' function. */
|
||||||
|
#undef HAVE_GETTIMEOFDAY
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `gmtime_r' function. */
|
||||||
|
#undef HAVE_GMTIME_R
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `intmax_t'. */
|
||||||
|
#undef HAVE_INTMAX_T
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `intptr_t'. */
|
||||||
|
#undef HAVE_INTPTR_T
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `kevent' function. */
|
||||||
|
#undef HAVE_KEVENT
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `long long int'. */
|
||||||
|
#undef HAVE_LONG_LONG_INT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
|
#undef HAVE_MEMORY_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have a working `mmap' system call. */
|
||||||
|
#undef HAVE_MMAP
|
||||||
|
|
||||||
|
/* Define if you have nanosleep */
|
||||||
|
#undef HAVE_NANOSLEEP
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||||
|
#undef HAVE_NETINET_IN_H
|
||||||
|
|
||||||
|
/* Has OpenSSL */
|
||||||
|
#undef HAVE_OPENSSL
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `poll' function. */
|
||||||
|
#undef HAVE_POLL
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `port_create' function. */
|
||||||
|
#undef HAVE_PORT_CREATE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <port.h> header file. */
|
||||||
|
#undef HAVE_PORT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `posix_spawn' function. */
|
||||||
|
#undef HAVE_POSIX_SPAWN
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `select' function. */
|
||||||
|
#undef HAVE_SELECT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `sendmsg' function. */
|
||||||
|
#undef HAVE_SENDMSG
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `signalfd' function. */
|
||||||
|
#undef HAVE_SIGNALFD
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <signal.h> header file. */
|
||||||
|
#undef HAVE_SIGNAL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `socketpair' function. */
|
||||||
|
#undef HAVE_SOCKETPAIR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <spawn.h> header file. */
|
||||||
|
#undef HAVE_SPAWN_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
|
#undef HAVE_STDINT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||||
|
#undef HAVE_STDLIB_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
|
#undef HAVE_STRINGS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */
|
||||||
|
#undef HAVE_STRING_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strlcat' function. */
|
||||||
|
#undef HAVE_STRLCAT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strlcpy' function. */
|
||||||
|
#undef HAVE_STRLCPY
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strnlen' function. */
|
||||||
|
#undef HAVE_STRNLEN
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strtok_r' function. */
|
||||||
|
#undef HAVE_STRTOK_R
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `struct sockaddr_in6'. */
|
||||||
|
#undef HAVE_STRUCT_SOCKADDR_IN6
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `struct sockaddr_storage'. */
|
||||||
|
#undef HAVE_STRUCT_SOCKADDR_STORAGE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/devpoll.h> header file. */
|
||||||
|
#undef HAVE_SYS_DEVPOLL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||||
|
#undef HAVE_SYS_EPOLL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/event.h> header file. */
|
||||||
|
#undef HAVE_SYS_EVENT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/poll.h> header file. */
|
||||||
|
#undef HAVE_SYS_POLL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||||
|
#undef HAVE_SYS_SELECT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/signalfd.h> header file. */
|
||||||
|
#undef HAVE_SYS_SIGNALFD_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||||
|
#undef HAVE_SYS_SOCKET_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#undef HAVE_SYS_STAT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||||
|
#undef HAVE_SYS_TIME_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#undef HAVE_SYS_TYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||||
|
#undef HAVE_SYS_UIO_H
|
||||||
|
|
||||||
|
/* Define if you have timer_create */
|
||||||
|
#undef HAVE_TIMER_CREATE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <time.h> header file. */
|
||||||
|
#undef HAVE_TIME_H
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `uintmax_t'. */
|
||||||
|
#undef HAVE_UINTMAX_T
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `uintptr_t'. */
|
||||||
|
#undef HAVE_UINTPTR_T
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `unsigned long long int'. */
|
||||||
|
#undef HAVE_UNSIGNED_LONG_LONG_INT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `usleep' function. */
|
||||||
|
#undef HAVE_USLEEP
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vfork' function. */
|
||||||
|
#undef HAVE_VFORK
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <vfork.h> header file. */
|
||||||
|
#undef HAVE_VFORK_H
|
||||||
|
|
||||||
|
/* Define to 1 if you are on windows */
|
||||||
|
#undef HAVE_WIN32
|
||||||
|
|
||||||
|
/* Define to 1 if `fork' works. */
|
||||||
|
#undef HAVE_WORKING_FORK
|
||||||
|
|
||||||
|
/* Define to 1 if `vfork' works. */
|
||||||
|
#undef HAVE_WORKING_VFORK
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `writev' function. */
|
||||||
|
#undef HAVE_WRITEV
|
||||||
|
|
||||||
|
/* This is a MinGW system */
|
||||||
|
#undef MINGW
|
||||||
|
|
||||||
|
/* Define this to disable debugging support. */
|
||||||
|
#undef NDEBUG
|
||||||
|
|
||||||
|
/* Define if your system needs crypt. */
|
||||||
|
#undef NEED_CRYPT
|
||||||
|
|
||||||
|
/* Define to 1 if you wish to disable the block allocator. */
|
||||||
|
#undef NOBALLOC
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#undef PACKAGE_BUGREPORT
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#undef PACKAGE_NAME
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#undef PACKAGE_STRING
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#undef PACKAGE_TARNAME
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
|
/* Defined to mark profiling is enabled */
|
||||||
|
#undef RATBOX_PROFILE
|
||||||
|
|
||||||
|
/* Prefix where libratbox is installed. */
|
||||||
|
#undef RB_PREFIX
|
||||||
|
|
||||||
|
/* Define to 1 if sockaddr has a 'sa_len' member. */
|
||||||
|
#undef SOCKADDR_IN_HAS_LEN
|
||||||
|
|
||||||
|
/* Define this to enable soft asserts. */
|
||||||
|
#undef SOFT_ASSERT
|
||||||
|
|
||||||
|
/* If using the C implementation of alloca, define if you know the
|
||||||
|
direction of stack growth for your system; otherwise it will be
|
||||||
|
automatically deduced at runtime.
|
||||||
|
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||||
|
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||||
|
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||||
|
#undef STACK_DIRECTION
|
||||||
|
|
||||||
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
|
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||||
|
#undef TIME_WITH_SYS_TIME
|
||||||
|
|
||||||
|
/* Define to 1 if we can use timer_create(CLOCK_REALTIME,...) */
|
||||||
|
#undef USE_TIMER_CREATE
|
||||||
|
|
||||||
|
/* This is a Windows system */
|
||||||
|
#undef WINDOWS
|
||||||
|
|
||||||
|
/* Enable GNU extensions on systems that have them. */
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
# undef _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
|
||||||
|
<pthread.h>, or <semaphore.h> is not used. If the typedef was allowed, the
|
||||||
|
#define below would cause a syntax error. */
|
||||||
|
#undef _UINT32_T
|
||||||
|
|
||||||
|
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
|
||||||
|
<pthread.h>, or <semaphore.h> is not used. If the typedef was allowed, the
|
||||||
|
#define below would cause a syntax error. */
|
||||||
|
#undef _UINT64_T
|
||||||
|
|
||||||
|
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
|
||||||
|
<pthread.h>, or <semaphore.h> is not used. If the typedef was allowed, the
|
||||||
|
#define below would cause a syntax error. */
|
||||||
|
#undef _UINT8_T
|
||||||
|
|
||||||
|
/* Define to empty if `const' does not conform to ANSI C. */
|
||||||
|
#undef const
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
#undef gid_t
|
||||||
|
|
||||||
|
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||||
|
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#undef inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define to the type of a signed integer type of width exactly 16 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef int16_t
|
||||||
|
|
||||||
|
/* Define to the type of a signed integer type of width exactly 32 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef int32_t
|
||||||
|
|
||||||
|
/* Define to the type of a signed integer type of width exactly 64 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef int64_t
|
||||||
|
|
||||||
|
/* Define to the type of a signed integer type of width exactly 8 bits if such
|
||||||
|
a type exists and the standard includes do not define it. */
|
||||||
|
#undef int8_t
|
||||||
|
|
||||||
|
/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
|
||||||
|
not define. */
|
||||||
|
#undef intmax_t
|
||||||
|
|
||||||
|
/* Define to the type of a signed integer type wide enough to hold a pointer,
|
||||||
|
if such a type exists, and if the system does not define it. */
|
||||||
|
#undef intptr_t
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> does not define. */
|
||||||
|
#undef pid_t
|
||||||
|
|
||||||
|
/* If system does not define sa_family_t, define it here. */
|
||||||
|
#undef sa_family_t
|
||||||
|
|
||||||
|
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||||
|
#undef size_t
|
||||||
|
|
||||||
|
/* If we don't have a real socklen_t, unsigned int is good enough. */
|
||||||
|
#undef socklen_t
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> does not define. */
|
||||||
|
#undef ssize_t
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
#undef uid_t
|
||||||
|
|
||||||
|
/* Define to the type of an unsigned integer type of width exactly 16 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef uint16_t
|
||||||
|
|
||||||
|
/* Define to the type of an unsigned integer type of width exactly 32 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef uint32_t
|
||||||
|
|
||||||
|
/* Define to the type of an unsigned integer type of width exactly 64 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef uint64_t
|
||||||
|
|
||||||
|
/* Define to the type of an unsigned integer type of width exactly 8 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef uint8_t
|
||||||
|
|
||||||
|
/* Define to the widest unsigned integer type if <stdint.h> and <inttypes.h>
|
||||||
|
do not define. */
|
||||||
|
#undef uintmax_t
|
||||||
|
|
||||||
|
/* Define to the type of an unsigned integer type wide enough to hold a
|
||||||
|
pointer, if such a type exists, and if the system does not define it. */
|
||||||
|
#undef uintptr_t
|
||||||
|
|
||||||
|
/* Define as `fork' if `vfork' does not work. */
|
||||||
|
#undef vfork
|
224
libratbox/include/ratbox_lib.h
Normal file
224
libratbox/include/ratbox_lib.h
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
/*
|
||||||
|
* $Id: ratbox_lib.h 24866 2008-01-10 16:33:54Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RB_LIB_H
|
||||||
|
#define RB_LIB_H 1
|
||||||
|
|
||||||
|
#include <librb-config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#undef alloca
|
||||||
|
#define alloca __builtin_alloca
|
||||||
|
#else
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# include <malloc.h>
|
||||||
|
# define alloca _alloca
|
||||||
|
# else
|
||||||
|
# if RB_HAVE_ALLOCA_H
|
||||||
|
# include <alloca.h>
|
||||||
|
# else
|
||||||
|
# ifdef _AIX
|
||||||
|
#pragma alloca
|
||||||
|
# else
|
||||||
|
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||||
|
char *alloca();
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
|
||||||
|
#ifdef likely
|
||||||
|
#undef likely
|
||||||
|
#endif
|
||||||
|
#ifdef unlikely
|
||||||
|
#undef unlikely
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
|
||||||
|
# define __builtin_expect(x, expected_value) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
|
||||||
|
#else /* !__GNUC__ */
|
||||||
|
|
||||||
|
#define UNUSED(x) x
|
||||||
|
|
||||||
|
#ifdef likely
|
||||||
|
#undef likely
|
||||||
|
#endif
|
||||||
|
#ifdef unlikely
|
||||||
|
#undef unlikely
|
||||||
|
#endif
|
||||||
|
#define likely(x) (x)
|
||||||
|
#define unlikely(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <process.h>
|
||||||
|
|
||||||
|
#ifndef MAXPATHLEN
|
||||||
|
#define MAXPATHLEN 128
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef strerror
|
||||||
|
#undef strerror
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define strerror(x) wsock_strerror(x)
|
||||||
|
const char *wsock_strerror(int error);
|
||||||
|
|
||||||
|
|
||||||
|
#define ENOBUFS WSAENOBUFS
|
||||||
|
#define EINPROGRESS WSAEINPROGRESS
|
||||||
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
|
#define EMSGSIZE WSAEMSGSIZE
|
||||||
|
#define EALREADY WSAEALREADY
|
||||||
|
#define EISCONN WSAEISCONN
|
||||||
|
#define EADDRINUSE WSAEADDRINUSE
|
||||||
|
#define EAFNOSUPPORT WSAEAFNOSUPPORT
|
||||||
|
|
||||||
|
#define pipe(x) _pipe(x, 1024, O_BINARY)
|
||||||
|
#define ioctl(x,y,z) ioctlsocket(x,y, (u_long *)z)
|
||||||
|
|
||||||
|
int setenv(const char *, const char *, int);
|
||||||
|
int kill(int pid, int sig);
|
||||||
|
#define WNOHANG 1
|
||||||
|
pid_t waitpid(pid_t pid, int *status, int options);
|
||||||
|
pid_t getpid(void);
|
||||||
|
unsigned int geteuid(void);
|
||||||
|
|
||||||
|
#ifndef SIGKILL
|
||||||
|
#define SIGKILL SIGTERM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* WIN32 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HOSTIPLEN
|
||||||
|
#define HOSTIPLEN 53
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SOFT_ASSERT
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define lrb_assert(expr) do \
|
||||||
|
if(unlikely(!(expr))) { \
|
||||||
|
lib_ilog(L_MAIN, \
|
||||||
|
"file: %s line: %d (%s): Assertion failed: (%s)", \
|
||||||
|
__FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
|
||||||
|
sendto_realops_flags(UMODE_ALL, L_ALL, \
|
||||||
|
"file: %s line: %d (%s): Assertion failed: (%s)", \
|
||||||
|
__FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
|
||||||
|
} \
|
||||||
|
while(0)
|
||||||
|
#else
|
||||||
|
#define lrb_assert(expr) do \
|
||||||
|
if(unlikely(!(expr))) { \
|
||||||
|
lib_ilog(L_MAIN, \
|
||||||
|
"file: %s line: %d: Assertion failed: (%s)", \
|
||||||
|
__FILE__, __LINE__, #expr); \
|
||||||
|
sendto_realops_flags(UMODE_ALL, L_ALL, \
|
||||||
|
"file: %s line: %d: Assertion failed: (%s)" \
|
||||||
|
__FILE__, __LINE__, #expr); \
|
||||||
|
} \
|
||||||
|
while(0)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define lrb_assert(expr) assert(expr)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SOCKADDR_IN_HAS_LEN
|
||||||
|
#define ss_len sa_len
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GET_SS_FAMILY(x) (((struct sockaddr *)(x))->sa_family)
|
||||||
|
|
||||||
|
#ifdef SOCKADDR_IN_HAS_LEN
|
||||||
|
#define SET_SS_LEN(x, y) do { \
|
||||||
|
struct sockaddr *storage; \
|
||||||
|
storage = ((struct sockaddr *)(x));\
|
||||||
|
storage->sa_len = (y); \
|
||||||
|
} while (0)
|
||||||
|
#define GET_SS_LEN(x) (((struct sockaddr *)(x))->sa_len)
|
||||||
|
#else /* !SOCKADDR_IN_HAS_LEN */
|
||||||
|
#define SET_SS_LEN(x, y) (((struct sockaddr *)(x))->sa_family = ((struct sockaddr *)(x))->sa_family)
|
||||||
|
#ifdef RB_IPV6
|
||||||
|
#define GET_SS_LEN(x) (((struct sockaddr *)(x))->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))
|
||||||
|
#else
|
||||||
|
#define GET_SS_LEN(x) (((struct sockaddr *)(x))->sa_family == AF_INET ? sizeof(struct sockaddr_in) : 0)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INADDRSZ
|
||||||
|
#define INADDRSZ 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef IN6ADDRSZ
|
||||||
|
#define IN6ADDRSZ 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INT16SZ
|
||||||
|
#define INT16SZ 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef void log_cb(const char *buffer);
|
||||||
|
typedef void restart_cb(const char *buffer);
|
||||||
|
typedef void die_cb(const char *buffer);
|
||||||
|
|
||||||
|
char *rb_ctime(const time_t, char *, size_t);
|
||||||
|
char *rb_date(const time_t, char *, size_t);
|
||||||
|
void rb_lib_log(const char *, ...);
|
||||||
|
void rb_lib_restart(const char *, ...);
|
||||||
|
void rb_lib_die(const char *, ...);
|
||||||
|
void rb_set_time(void);
|
||||||
|
const char *rb_lib_version(void);
|
||||||
|
|
||||||
|
void rb_lib_init(log_cb * xilog, restart_cb * irestart, die_cb * idie, int closeall, int maxfds,
|
||||||
|
size_t dh_size, size_t fd_heap_size);
|
||||||
|
void rb_lib_loop(long delay);
|
||||||
|
|
||||||
|
time_t rb_current_time(void);
|
||||||
|
const struct timeval *rb_current_time_tv(void);
|
||||||
|
pid_t rb_spawn_process(const char *, const char **);
|
||||||
|
|
||||||
|
char *rb_strtok_r(char *, const char *, char **);
|
||||||
|
|
||||||
|
int rb_gettimeofday(struct timeval *, void *);
|
||||||
|
|
||||||
|
void rb_sleep(unsigned int seconds, unsigned int useconds);
|
||||||
|
char *rb_crypt(const char *, const char *);
|
||||||
|
|
||||||
|
unsigned char *rb_base64_encode(const unsigned char *str, int length);
|
||||||
|
unsigned char *rb_base64_decode(const unsigned char *str, int length, int *ret);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <rb_tools.h>
|
||||||
|
#include <rb_memory.h>
|
||||||
|
#include <rb_commio.h>
|
||||||
|
#include <rb_balloc.h>
|
||||||
|
#include <rb_linebuf.h>
|
||||||
|
#include <rb_snprintf.h>
|
||||||
|
#include <rb_event.h>
|
||||||
|
#include <rb_helper.h>
|
||||||
|
#include <rb_rawbuf.h>
|
||||||
|
#include <rb_patricia.h>
|
||||||
|
|
||||||
|
#endif
|
51
libratbox/include/rb_balloc.h
Normal file
51
libratbox/include/rb_balloc.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* balloc.h: The ircd block allocator header.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: rb_balloc.h 24324 2007-08-31 22:05:45Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RB_LIB_H
|
||||||
|
# error "Do not use balloc.h directly"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDED_balloc_h
|
||||||
|
#define INCLUDED_balloc_h
|
||||||
|
|
||||||
|
|
||||||
|
struct rb_bh;
|
||||||
|
typedef struct rb_bh rb_bh;
|
||||||
|
typedef void rb_bh_usage_cb(size_t bused, size_t bfree, size_t bmemusage, size_t heapalloc, const char *desc, void *data);
|
||||||
|
|
||||||
|
|
||||||
|
int rb_bh_free(rb_bh *, void *);
|
||||||
|
void *rb_bh_alloc(rb_bh *);
|
||||||
|
|
||||||
|
rb_bh *rb_bh_create(size_t elemsize, int elemsperblock, const char *desc);
|
||||||
|
int rb_bh_destroy(rb_bh * bh);
|
||||||
|
int rb_bh_gc(rb_bh *bh);
|
||||||
|
void rb_init_bh(void);
|
||||||
|
void rb_bh_usage(rb_bh * bh, size_t * bused, size_t * bfree, size_t * bmemusage, const char **desc);
|
||||||
|
void rb_bh_usage_all(rb_bh_usage_cb *cb, void *data);
|
||||||
|
void rb_bh_total_usage(size_t *total_alloc, size_t *total_used);
|
||||||
|
|
||||||
|
#endif /* INCLUDED_balloc_h */
|
172
libratbox/include/rb_commio.h
Normal file
172
libratbox/include/rb_commio.h
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* commio.h: A header for the network subsystem.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: rb_commio.h 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RB_LIB_H
|
||||||
|
# error "Do not use commio.h directly"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDED_commio_h
|
||||||
|
#define INCLUDED_commio_h
|
||||||
|
|
||||||
|
|
||||||
|
struct sockaddr;
|
||||||
|
struct _fde;
|
||||||
|
typedef struct _fde rb_fde_t;
|
||||||
|
|
||||||
|
/* Callback for completed IO events */
|
||||||
|
typedef void PF(rb_fde_t *, void *);
|
||||||
|
|
||||||
|
/* Callback for completed connections */
|
||||||
|
/* int fd, int status, void * */
|
||||||
|
typedef void CNCB(rb_fde_t *, int, void *);
|
||||||
|
/* callback for fd table dumps */
|
||||||
|
typedef void DUMPCB(int, const char *desc, void *);
|
||||||
|
/* callback for accept callbacks */
|
||||||
|
typedef void ACCB(rb_fde_t *, int status, struct sockaddr *addr, rb_socklen_t len, void *);
|
||||||
|
/* callback for pre-accept callback */
|
||||||
|
typedef int ACPRE(rb_fde_t *, struct sockaddr *addr, rb_socklen_t len, void *);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
RB_OK,
|
||||||
|
RB_ERR_BIND,
|
||||||
|
RB_ERR_DNS,
|
||||||
|
RB_ERR_TIMEOUT,
|
||||||
|
RB_ERR_CONNECT,
|
||||||
|
RB_ERROR,
|
||||||
|
RB_ERROR_SSL,
|
||||||
|
RB_ERR_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RB_FD_NONE 0x01
|
||||||
|
#define RB_FD_FILE 0x02
|
||||||
|
#define RB_FD_SOCKET 0x04
|
||||||
|
#ifndef WIN32
|
||||||
|
#define RB_FD_PIPE 0x08
|
||||||
|
#else
|
||||||
|
#define RB_FD_PIPE RB_FD_SOCKET
|
||||||
|
#endif
|
||||||
|
#define RB_FD_LISTEN 0x10
|
||||||
|
#define RB_FD_SSL 0x20
|
||||||
|
#define RB_FD_UNKNOWN 0x40
|
||||||
|
|
||||||
|
#define RB_RW_IO_ERROR -1 /* System call error */
|
||||||
|
#define RB_RW_SSL_ERROR -2 /* SSL Error */
|
||||||
|
#define RB_RW_SSL_NEED_READ -3 /* SSL Needs read */
|
||||||
|
#define RB_RW_SSL_NEED_WRITE -4 /* SSL Needs write */
|
||||||
|
|
||||||
|
|
||||||
|
struct rb_iovec
|
||||||
|
{
|
||||||
|
void *iov_base;
|
||||||
|
size_t iov_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void rb_fdlist_init(int closeall, int maxfds, size_t heapsize);
|
||||||
|
|
||||||
|
rb_fde_t * rb_open(int, rb_uint8_t, const char *);
|
||||||
|
void rb_close(rb_fde_t *);
|
||||||
|
void rb_dump_fd(DUMPCB *, void *xdata);
|
||||||
|
void rb_note(rb_fde_t *, const char *);
|
||||||
|
|
||||||
|
/* Type of IO */
|
||||||
|
#define RB_SELECT_READ 0x1
|
||||||
|
#define RB_SELECT_WRITE 0x2
|
||||||
|
|
||||||
|
#define RB_SELECT_ACCEPT RB_SELECT_READ
|
||||||
|
#define RB_SELECT_CONNECT RB_SELECT_WRITE
|
||||||
|
|
||||||
|
int rb_set_nb(rb_fde_t *);
|
||||||
|
int rb_set_buffers(rb_fde_t *, int);
|
||||||
|
|
||||||
|
int rb_get_sockerr(rb_fde_t *);
|
||||||
|
|
||||||
|
void rb_settimeout(rb_fde_t *, time_t, PF *, void *);
|
||||||
|
void rb_checktimeouts(void *);
|
||||||
|
void rb_connect_tcp(rb_fde_t *, struct sockaddr *,
|
||||||
|
struct sockaddr *, int, CNCB *, void *, int);
|
||||||
|
void rb_connect_tcp_ssl(rb_fde_t *, struct sockaddr *,
|
||||||
|
struct sockaddr *, int, CNCB *, void *, int);
|
||||||
|
int rb_connect_sockaddr(rb_fde_t *, struct sockaddr *addr, int len);
|
||||||
|
|
||||||
|
const char *rb_errstr(int status);
|
||||||
|
rb_fde_t *rb_socket(int family, int sock_type, int proto, const char *note);
|
||||||
|
int rb_socketpair(int family, int sock_type, int proto, rb_fde_t **F1, rb_fde_t **F2, const char *note);
|
||||||
|
|
||||||
|
void rb_accept_tcp(rb_fde_t *, ACPRE *precb, ACCB *callback, void *data);
|
||||||
|
ssize_t rb_write(rb_fde_t *, const void *buf, int count);
|
||||||
|
ssize_t rb_writev(rb_fde_t *, struct rb_iovec *vector, int count);
|
||||||
|
|
||||||
|
ssize_t rb_read(rb_fde_t *, void *buf, int count);
|
||||||
|
int rb_pipe(rb_fde_t **, rb_fde_t **, const char *desc);
|
||||||
|
|
||||||
|
int rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile);
|
||||||
|
int rb_ssl_listen(rb_fde_t *, int backlog);
|
||||||
|
int rb_listen(rb_fde_t *, int backlog);
|
||||||
|
|
||||||
|
const char *rb_inet_ntop(int af, const void *src, char *dst, unsigned int size);
|
||||||
|
int rb_inet_pton(int af, const char *src, void *dst);
|
||||||
|
const char *rb_inet_ntop_sock(struct sockaddr *src, char *dst, unsigned int size);
|
||||||
|
int rb_inet_pton_sock(const char *src, struct sockaddr *dst);
|
||||||
|
int rb_getmaxconnect(void);
|
||||||
|
int rb_ignore_errno(int);
|
||||||
|
|
||||||
|
/* Generic wrappers */
|
||||||
|
void rb_setselect(rb_fde_t *, unsigned int type, PF * handler, void *client_data);
|
||||||
|
void rb_init_netio(void);
|
||||||
|
int rb_select(unsigned long);
|
||||||
|
int rb_fd_ssl(rb_fde_t *F);
|
||||||
|
int rb_get_fd(rb_fde_t *F);
|
||||||
|
const char *rb_get_ssl_strerror(rb_fde_t *F);
|
||||||
|
|
||||||
|
rb_fde_t *rb_get_fde(int fd);
|
||||||
|
|
||||||
|
int rb_send_fd_buf(rb_fde_t *xF, rb_fde_t **F, int count, void *data, size_t datasize);
|
||||||
|
int rb_recv_fd_buf(rb_fde_t *F, void *data, size_t datasize, rb_fde_t **xF, int count);
|
||||||
|
|
||||||
|
void rb_set_type(rb_fde_t *F, rb_uint8_t type);
|
||||||
|
rb_uint8_t rb_get_type(rb_fde_t *F);
|
||||||
|
|
||||||
|
const char *rb_get_iotype(void);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RB_PRNG_EGD,
|
||||||
|
RB_PRNG_FILE,
|
||||||
|
#ifdef WIN32
|
||||||
|
RB_PRNGWIN32,
|
||||||
|
#endif
|
||||||
|
RB_PRNG_DEFAULT,
|
||||||
|
} prng_seed_t;
|
||||||
|
|
||||||
|
int rb_init_prng(const char *path, prng_seed_t seed_type);
|
||||||
|
int rb_get_random(void *buf, size_t len);
|
||||||
|
void rb_ssl_start_accepted(rb_fde_t *new_F, ACCB *cb, void *data, int timeout);
|
||||||
|
void rb_ssl_start_connected(rb_fde_t *F, CNCB *callback, void *data, int timeout);
|
||||||
|
int rb_supports_ssl(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* INCLUDED_commio_h */
|
50
libratbox/include/rb_event.h
Normal file
50
libratbox/include/rb_event.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* event.h: The ircd event header.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: rb_event.h 25151 2008-03-28 17:19:12Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RB_LIB_H
|
||||||
|
# error "Do not use event.h directly"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDED_event_h
|
||||||
|
#define INCLUDED_event_h
|
||||||
|
|
||||||
|
struct ev_entry;
|
||||||
|
typedef void EVH(void *);
|
||||||
|
|
||||||
|
struct ev_entry *rb_event_add(const char *name, EVH * func, void *arg, time_t when);
|
||||||
|
struct ev_entry *rb_event_addonce(const char *name, EVH * func, void *arg, time_t when);
|
||||||
|
struct ev_entry *rb_event_addish(const char *name, EVH * func, void *arg, time_t delta_ish);
|
||||||
|
void rb_event_run(void);
|
||||||
|
void rb_event_init(void);
|
||||||
|
void rb_event_delete(struct ev_entry *);
|
||||||
|
void rb_event_find_delete(EVH * func, void *);
|
||||||
|
void rb_event_update(struct ev_entry *, time_t freq);
|
||||||
|
void rb_set_back_events(time_t);
|
||||||
|
void rb_dump_events(void (*func)(char *, void *), void *ptr);
|
||||||
|
void rb_run_event(struct ev_entry *);
|
||||||
|
time_t rb_event_next(void);
|
||||||
|
|
||||||
|
#endif /* INCLUDED_event_h */
|
60
libratbox/include/rb_helper.h
Normal file
60
libratbox/include/rb_helper.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd
|
||||||
|
* helper.h: Starts and deals with ircd helpers
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: rb_helper.h 24936 2008-01-14 20:43:23Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RB_LIB_H
|
||||||
|
# error "Do not use helper.h directly"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDED_helper_h
|
||||||
|
#define INCLUDED_helper_h
|
||||||
|
|
||||||
|
struct _rb_helper;
|
||||||
|
typedef struct _rb_helper rb_helper;
|
||||||
|
|
||||||
|
typedef void rb_helper_cb(rb_helper *);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rb_helper *rb_helper_start(const char *name, const char *fullpath, rb_helper_cb *read_cb, rb_helper_cb *error_cb);
|
||||||
|
|
||||||
|
rb_helper *rb_helper_child(rb_helper_cb *read_cb, rb_helper_cb *error_cb,
|
||||||
|
log_cb *ilog, restart_cb *irestart, die_cb *idie,
|
||||||
|
int maxcon, size_t lb_heap_size, size_t dh_size, size_t fd_heap_size);
|
||||||
|
|
||||||
|
void rb_helper_restart(rb_helper *helper);
|
||||||
|
#ifdef __GNUC__
|
||||||
|
void rb_helper_write(rb_helper *helper, const char *format, ...) __attribute((format(printf, 2, 3)));
|
||||||
|
void rb_helper_write_queue(rb_helper *helper, const char *format, ...) __attribute((format(printf, 2, 3)));
|
||||||
|
#else
|
||||||
|
void rb_helper_write(rb_helper *helper, const char *format, ...);
|
||||||
|
void rb_helper_write_queue(rb_helper *helper, const char *format, ...);
|
||||||
|
#endif
|
||||||
|
void rb_helper_write_flush(rb_helper *helper);
|
||||||
|
|
||||||
|
void rb_helper_run(rb_helper *helper);
|
||||||
|
void rb_helper_close(rb_helper *helper);
|
||||||
|
int rb_helper_read(rb_helper *helper, void *buf, size_t bufsize);
|
||||||
|
void rb_helper_loop(rb_helper *helper, long delay);
|
||||||
|
#endif
|
||||||
|
|
84
libratbox/include/rb_linebuf.h
Normal file
84
libratbox/include/rb_linebuf.h
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* linebuf.h: A header for the linebuf code.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: rb_linebuf.h 24324 2007-08-31 22:05:45Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RB_LIB_H
|
||||||
|
# error "Do not use linebuf.h directly"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __LINEBUF_H__
|
||||||
|
#define __LINEBUF_H__
|
||||||
|
|
||||||
|
#define LINEBUF_COMPLETE 0
|
||||||
|
#define LINEBUF_PARTIAL 1
|
||||||
|
#define LINEBUF_PARSED 0
|
||||||
|
#define LINEBUF_RAW 1
|
||||||
|
|
||||||
|
struct _buf_line;
|
||||||
|
struct _buf_head;
|
||||||
|
|
||||||
|
/* How big we want a buffer - 510 data bytes, plus space for a '\0' */
|
||||||
|
#define BUF_DATA_SIZE 511
|
||||||
|
|
||||||
|
typedef struct _buf_line
|
||||||
|
{
|
||||||
|
char buf[BUF_DATA_SIZE + 2];
|
||||||
|
rb_uint8_t terminated; /* Whether we've terminated the buffer */
|
||||||
|
rb_uint8_t flushing; /* Whether we're flushing .. */
|
||||||
|
rb_uint8_t raw; /* Whether this linebuf may hold 8-bit data */
|
||||||
|
int len; /* How much data we've got */
|
||||||
|
int refcount; /* how many linked lists are we in? */
|
||||||
|
} buf_line_t;
|
||||||
|
|
||||||
|
typedef struct _buf_head
|
||||||
|
{
|
||||||
|
rb_dlink_list list; /* the actual dlink list */
|
||||||
|
int len; /* length of all the data */
|
||||||
|
int alloclen; /* Actual allocated data length */
|
||||||
|
int writeofs; /* offset in the first line for the write */
|
||||||
|
int numlines; /* number of lines */
|
||||||
|
} buf_head_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* they should be functions, but .. */
|
||||||
|
#define rb_linebuf_len(x) ((x)->len)
|
||||||
|
#define rb_linebuf_alloclen(x) ((x)->alloclen)
|
||||||
|
#define rb_linebuf_numlines(x) ((x)->numlines)
|
||||||
|
|
||||||
|
void rb_linebuf_init(size_t heap_size);
|
||||||
|
void rb_linebuf_newbuf(buf_head_t *);
|
||||||
|
void rb_linebuf_donebuf(buf_head_t *);
|
||||||
|
int rb_linebuf_parse(buf_head_t *, char *, int, int);
|
||||||
|
int rb_linebuf_get(buf_head_t *, char *, int, int, int);
|
||||||
|
void rb_linebuf_putmsg(buf_head_t *, const char *, va_list *, const char *, ...);
|
||||||
|
void rb_linebuf_put(buf_head_t *, const char *, ...);
|
||||||
|
void rb_linebuf_putbuf(buf_head_t *bufhead, const char *buffer);
|
||||||
|
void rb_linebuf_attach(buf_head_t *, buf_head_t *);
|
||||||
|
void rb_count_rb_linebuf_memory(size_t *, size_t *);
|
||||||
|
int rb_linebuf_flush(rb_fde_t *F, buf_head_t *);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
86
libratbox/include/rb_memory.h
Normal file
86
libratbox/include/rb_memory.h
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* memory.h: A header for the memory functions.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: rb_memory.h 25022 2008-01-23 03:54:00Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RB_LIB_H
|
||||||
|
#error "Do not use rb_memory.h directly"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _RB_MEMORY_H
|
||||||
|
#define _RB_MEMORY_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
void rb_outofmemory(void);
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
rb_malloc(size_t size)
|
||||||
|
{
|
||||||
|
void *ret = calloc(1, size);
|
||||||
|
if(unlikely(ret == NULL))
|
||||||
|
rb_outofmemory();
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
rb_realloc(void *x, size_t y)
|
||||||
|
{
|
||||||
|
void *ret = realloc(x, y);
|
||||||
|
|
||||||
|
if(unlikely(ret == NULL))
|
||||||
|
rb_outofmemory();
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
rb_strndup(const char *x, size_t y)
|
||||||
|
{
|
||||||
|
char *ret = malloc(y);
|
||||||
|
if(unlikely(ret == NULL))
|
||||||
|
rb_outofmemory();
|
||||||
|
rb_strlcpy(ret, x, y);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
rb_strdup(const char *x)
|
||||||
|
{
|
||||||
|
char *ret = malloc(strlen(x) + 1);
|
||||||
|
if(unlikely(ret == NULL))
|
||||||
|
rb_outofmemory();
|
||||||
|
strcpy(ret, x);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
rb_free(void *ptr)
|
||||||
|
{
|
||||||
|
if(likely(ptr != NULL))
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _I_MEMORY_H */
|
142
libratbox/include/rb_patricia.h
Normal file
142
libratbox/include/rb_patricia.h
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* $Id: patricia.h 23020 2006-09-01 18:20:19Z androsyn $
|
||||||
|
* Dave Plonka <plonka@doit.wisc.edu>
|
||||||
|
*
|
||||||
|
* This product includes software developed by the University of Michigan,
|
||||||
|
* Merit Network, Inc., and their contributors.
|
||||||
|
*
|
||||||
|
* This file had been called "radix.h" in the MRT sources.
|
||||||
|
*
|
||||||
|
* I renamed it to "patricia.h" since it's not an implementation of a general
|
||||||
|
* radix trie. Also, pulled in various requirements from "mrt.h" and added
|
||||||
|
* some other things it could be used as a standalone API.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RB_PATRICIA_H
|
||||||
|
#define _RB_PATRICIA_H
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE !(FALSE)
|
||||||
|
#endif
|
||||||
|
#ifndef INET6_ADDRSTRLEN
|
||||||
|
#define INET6_ADDRSTRLEN 46
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* typedef unsigned int u_int; */
|
||||||
|
typedef void (*void_fn_t) ();
|
||||||
|
#define rb_prefix_touchar(prefix) ((unsigned char *)&(prefix)->add.sin)
|
||||||
|
#define MAXLINE 1024
|
||||||
|
#define BIT_TEST(f, b) ((f) & (b))
|
||||||
|
|
||||||
|
typedef struct _rb_prefix_t
|
||||||
|
{
|
||||||
|
unsigned short family; /* AF_INET | AF_INET6 */
|
||||||
|
unsigned short bitlen; /* same as mask? */
|
||||||
|
int ref_count; /* reference count */
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct in_addr sin;
|
||||||
|
#ifdef RB_IPV6
|
||||||
|
struct in6_addr sin6;
|
||||||
|
#endif /* RB_IPV6 */
|
||||||
|
}
|
||||||
|
add;
|
||||||
|
}
|
||||||
|
rb_prefix_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _rb_patricia_node_t
|
||||||
|
{
|
||||||
|
unsigned int bit; /* flag if this node used */
|
||||||
|
rb_prefix_t *prefix; /* who we are in patricia tree */
|
||||||
|
struct _rb_patricia_node_t *l, *r; /* left and right children */
|
||||||
|
struct _rb_patricia_node_t *parent; /* may be used */
|
||||||
|
void *data;
|
||||||
|
}
|
||||||
|
rb_patricia_node_t;
|
||||||
|
|
||||||
|
typedef struct _rb_patricia_tree_t
|
||||||
|
{
|
||||||
|
rb_patricia_node_t *head;
|
||||||
|
unsigned int maxbits; /* for IP, 32 bit addresses */
|
||||||
|
int num_active_node; /* for debug purpose */
|
||||||
|
}
|
||||||
|
rb_patricia_tree_t;
|
||||||
|
|
||||||
|
|
||||||
|
rb_patricia_node_t *rb_match_ip(rb_patricia_tree_t * tree, struct sockaddr *ip);
|
||||||
|
rb_patricia_node_t *rb_match_ip_exact(rb_patricia_tree_t * tree, struct sockaddr *ip, unsigned int len);
|
||||||
|
rb_patricia_node_t *rb_match_string(rb_patricia_tree_t * tree, const char *string);
|
||||||
|
rb_patricia_node_t *rb_match_exact_string(rb_patricia_tree_t * tree, const char *string);
|
||||||
|
rb_patricia_node_t *rb_patricia_search_exact(rb_patricia_tree_t * patricia, rb_prefix_t * prefix);
|
||||||
|
rb_patricia_node_t *rb_patricia_search_best(rb_patricia_tree_t * patricia, rb_prefix_t * prefix);
|
||||||
|
rb_patricia_node_t *rb_patricia_search_best2(rb_patricia_tree_t * patricia,
|
||||||
|
rb_prefix_t * prefix, int inclusive);
|
||||||
|
rb_patricia_node_t *rb_patricia_lookup(rb_patricia_tree_t * patricia, rb_prefix_t * prefix);
|
||||||
|
|
||||||
|
void rb_patricia_remove(rb_patricia_tree_t * patricia, rb_patricia_node_t * node);
|
||||||
|
rb_patricia_tree_t *rb_new_patricia(int maxbits);
|
||||||
|
void rb_clear_patricia(rb_patricia_tree_t * patricia, void_fn_t func);
|
||||||
|
void rb_destroy_patricia(rb_patricia_tree_t * patricia, void_fn_t func);
|
||||||
|
void rb_patricia_process(rb_patricia_tree_t * patricia, void_fn_t func);
|
||||||
|
void rb_init_patricia(void);
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
rb_prefix_t *ascii2prefix(int family, char *string);
|
||||||
|
#endif
|
||||||
|
rb_patricia_node_t *make_and_lookup(rb_patricia_tree_t * tree, const char *string);
|
||||||
|
rb_patricia_node_t *make_and_lookup_ip(rb_patricia_tree_t * tree, struct sockaddr *, int bitlen);
|
||||||
|
|
||||||
|
|
||||||
|
#define RB_PATRICIA_MAXBITS 128
|
||||||
|
#define RB_PATRICIA_NBIT(x) (0x80 >> ((x) & 0x7f))
|
||||||
|
#define RB_PATRICIA_NBYTE(x) ((x) >> 3)
|
||||||
|
|
||||||
|
#define RB_PATRICIA_DATA_GET(node, type) (type *)((node)->data)
|
||||||
|
#define RB_PATRICIA_DATA_SET(node, value) ((node)->data = (void *)(value))
|
||||||
|
|
||||||
|
#define RB_PATRICIA_WALK(Xhead, Xnode) \
|
||||||
|
do { \
|
||||||
|
rb_patricia_node_t *Xstack[RB_PATRICIA_MAXBITS+1]; \
|
||||||
|
rb_patricia_node_t **Xsp = Xstack; \
|
||||||
|
rb_patricia_node_t *Xrn = (Xhead); \
|
||||||
|
while ((Xnode = Xrn)) { \
|
||||||
|
if (Xnode->prefix)
|
||||||
|
|
||||||
|
#define RB_PATRICIA_WALK_ALL(Xhead, Xnode) \
|
||||||
|
do { \
|
||||||
|
rb_patricia_node_t *Xstack[RB_PATRICIA_MAXBITS+1]; \
|
||||||
|
rb_patricia_node_t **Xsp = Xstack; \
|
||||||
|
rb_patricia_node_t *Xrn = (Xhead); \
|
||||||
|
while ((Xnode = Xrn)) { \
|
||||||
|
if (1)
|
||||||
|
|
||||||
|
#define RB_PATRICIA_WALK_BREAK { \
|
||||||
|
if (Xsp != Xstack) { \
|
||||||
|
Xrn = *(--Xsp); \
|
||||||
|
} else { \
|
||||||
|
Xrn = (rb_patricia_node_t *) 0; \
|
||||||
|
} \
|
||||||
|
continue; }
|
||||||
|
|
||||||
|
#define RB_PATRICIA_WALK_END \
|
||||||
|
if (Xrn->l) { \
|
||||||
|
if (Xrn->r) { \
|
||||||
|
*Xsp++ = Xrn->r; \
|
||||||
|
} \
|
||||||
|
Xrn = Xrn->l; \
|
||||||
|
} else if (Xrn->r) { \
|
||||||
|
Xrn = Xrn->r; \
|
||||||
|
} else if (Xsp != Xstack) { \
|
||||||
|
Xrn = *(--Xsp); \
|
||||||
|
} else { \
|
||||||
|
Xrn = (rb_patricia_node_t *) 0; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif /* _RB_PATRICIA_H */
|
46
libratbox/include/rb_rawbuf.h
Normal file
46
libratbox/include/rb_rawbuf.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* rawbuf.h: A header for rawbuf.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
* Copyright (C) 2007 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RB_LIB_H
|
||||||
|
# error "Do not use rawbuf.h directly"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDED_RAWBUF_H__
|
||||||
|
#define INCLUDED_RAWBUF_H__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _rawbuf rawbuf_t;
|
||||||
|
typedef struct _rawbuf_head rawbuf_head_t;
|
||||||
|
|
||||||
|
void rb_init_rawbuffers(int heapsize);
|
||||||
|
void rb_free_rawbuffer(rawbuf_head_t *);
|
||||||
|
rawbuf_head_t *rb_new_rawbuffer(void);
|
||||||
|
int rb_rawbuf_get(rawbuf_head_t *, void *data, int len);
|
||||||
|
void rb_rawbuf_append(rawbuf_head_t *, void *data, int len);
|
||||||
|
int rb_rawbuf_flush(rawbuf_head_t *, rb_fde_t *F);
|
||||||
|
int rb_rawbuf_length(rawbuf_head_t *rb);
|
||||||
|
|
||||||
|
#endif
|
60
libratbox/include/rb_snprintf.h
Normal file
60
libratbox/include/rb_snprintf.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* sprintf_rb_.h: The irc sprintf header.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: rb_snprintf.h 24324 2007-08-31 22:05:45Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RB_LIB_H
|
||||||
|
# error "Do not use snprintf.h directly"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SPRINTF_IRC
|
||||||
|
#define SPRINTF_IRC
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
* Proto types
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_sprintf - optimized sprintf
|
||||||
|
*/
|
||||||
|
#ifdef __GNUC__
|
||||||
|
int rb_sprintf(char *str, const char *fmt, ...) __attribute((format(printf, 2, 3)));
|
||||||
|
int rb_snprintf(char *str, const size_t size, const char *, ...) __attribute__ ((format(printf, 3, 4)));
|
||||||
|
int rb_sprintf_append(char *str, const char *format, ...) __attribute((format(printf, 2, 3)));
|
||||||
|
int rb_snprintf_append(char *str, size_t len, const char *format, ...) __attribute__ ((format(printf, 3, 4)));
|
||||||
|
#else
|
||||||
|
int rb_sprintf(char *str, const char *format, ...);
|
||||||
|
int rb_snprintf(char *str, const size_t size, const char *, ...);
|
||||||
|
int rb_sprintf_append(char *str, const char *format, ...);
|
||||||
|
int rb_snprintf_append(char *str, const size_t size, const char *, ...);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int rb_vsnprintf(char *str, const size_t size, const char *fmt, va_list args);
|
||||||
|
int rb_vsprintf(char *str, const char *fmt, va_list args);
|
||||||
|
int rb_vsnprintf_append(char *str, const size_t size, const char *fmt, va_list args);
|
||||||
|
int rb_vsprintf_append(char *str, const char *fmt, va_list args);
|
||||||
|
|
||||||
|
#endif /* SPRINTF_IRC */
|
345
libratbox/include/rb_tools.h
Normal file
345
libratbox/include/rb_tools.h
Normal file
|
@ -0,0 +1,345 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* tools.h: Header for the various tool functions.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: rb_tools.h 25042 2008-01-23 16:14:08Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RB_LIB_H
|
||||||
|
# error "Do not use tools.h directly"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __TOOLS_H__
|
||||||
|
#define __TOOLS_H__
|
||||||
|
|
||||||
|
size_t rb_strlcpy(char *dst, const char *src, size_t siz);
|
||||||
|
size_t rb_strlcat(char *dst, const char *src, size_t siz);
|
||||||
|
size_t rb_strnlen(const char *s, size_t count);
|
||||||
|
|
||||||
|
int rb_string_to_array(char *string, char **parv, int maxpara);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* double-linked-list stuff
|
||||||
|
*/
|
||||||
|
typedef struct _rb_dlink_node rb_dlink_node;
|
||||||
|
typedef struct _rb_dlink_list rb_dlink_list;
|
||||||
|
|
||||||
|
struct _rb_dlink_node
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
rb_dlink_node *prev;
|
||||||
|
rb_dlink_node *next;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _rb_dlink_list
|
||||||
|
{
|
||||||
|
rb_dlink_node *head;
|
||||||
|
rb_dlink_node *tail;
|
||||||
|
unsigned long length;
|
||||||
|
};
|
||||||
|
|
||||||
|
rb_dlink_node *rb_make_rb_dlink_node(void);
|
||||||
|
void rb_free_rb_dlink_node(rb_dlink_node * lp);
|
||||||
|
void rb_init_rb_dlink_nodes(size_t dh_size);
|
||||||
|
|
||||||
|
/* This macros are basically swiped from the linux kernel
|
||||||
|
* they are simple yet effective
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Walks forward of a list.
|
||||||
|
* pos is your node
|
||||||
|
* head is your list head
|
||||||
|
*/
|
||||||
|
#define RB_DLINK_FOREACH(pos, head) for (pos = (head); pos != NULL; pos = pos->next)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Walks forward of a list safely while removing nodes
|
||||||
|
* pos is your node
|
||||||
|
* n is another list head for temporary storage
|
||||||
|
* head is your list head
|
||||||
|
*/
|
||||||
|
#define RB_DLINK_FOREACH_SAFE(pos, n, head) for (pos = (head), n = pos ? pos->next : NULL; pos != NULL; pos = n, n = pos ? pos->next : NULL)
|
||||||
|
|
||||||
|
#define RB_DLINK_FOREACH_PREV(pos, head) for (pos = (head); pos != NULL; pos = pos->prev)
|
||||||
|
|
||||||
|
|
||||||
|
/* Returns the list length */
|
||||||
|
#define rb_dlink_list_length(list) (list)->length
|
||||||
|
|
||||||
|
#define rb_dlinkAddAlloc(data, list) rb_dlinkAdd(data, rb_make_rb_dlink_node(), list)
|
||||||
|
#define rb_dlinkAddTailAlloc(data, list) rb_dlinkAddTail(data, rb_make_rb_dlink_node(), list)
|
||||||
|
#define rb_dlinkDestroy(node, list) do { rb_dlinkDelete(node, list); rb_free_rb_dlink_node(node); } while(0)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dlink_ routines are stolen from squid, except for rb_dlinkAddBefore,
|
||||||
|
* which is mine.
|
||||||
|
* -- adrian
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
rb_dlinkMoveNode(rb_dlink_node * m, rb_dlink_list * oldlist, rb_dlink_list * newlist)
|
||||||
|
{
|
||||||
|
/* Assumption: If m->next == NULL, then list->tail == m
|
||||||
|
* and: If m->prev == NULL, then list->head == m
|
||||||
|
*/
|
||||||
|
assert(m != NULL);
|
||||||
|
assert(oldlist != NULL);
|
||||||
|
assert(newlist != NULL);
|
||||||
|
|
||||||
|
if(m->next)
|
||||||
|
m->next->prev = m->prev;
|
||||||
|
else
|
||||||
|
oldlist->tail = m->prev;
|
||||||
|
|
||||||
|
if(m->prev)
|
||||||
|
m->prev->next = m->next;
|
||||||
|
else
|
||||||
|
oldlist->head = m->next;
|
||||||
|
|
||||||
|
m->prev = NULL;
|
||||||
|
m->next = newlist->head;
|
||||||
|
if(newlist->head != NULL)
|
||||||
|
newlist->head->prev = m;
|
||||||
|
else if(newlist->tail == NULL)
|
||||||
|
newlist->tail = m;
|
||||||
|
newlist->head = m;
|
||||||
|
|
||||||
|
oldlist->length--;
|
||||||
|
newlist->length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
rb_dlinkAdd(void *data, rb_dlink_node * m, rb_dlink_list * list)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
assert(m != NULL);
|
||||||
|
assert(list != NULL);
|
||||||
|
|
||||||
|
m->data = data;
|
||||||
|
m->prev = NULL;
|
||||||
|
m->next = list->head;
|
||||||
|
|
||||||
|
/* Assumption: If list->tail != NULL, list->head != NULL */
|
||||||
|
if(list->head != NULL)
|
||||||
|
list->head->prev = m;
|
||||||
|
else if(list->tail == NULL)
|
||||||
|
list->tail = m;
|
||||||
|
|
||||||
|
list->head = m;
|
||||||
|
list->length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
rb_dlinkAddBefore(rb_dlink_node * b, void *data, rb_dlink_node * m, rb_dlink_list * list)
|
||||||
|
{
|
||||||
|
assert(b != NULL);
|
||||||
|
assert(data != NULL);
|
||||||
|
assert(m != NULL);
|
||||||
|
assert(list != NULL);
|
||||||
|
|
||||||
|
/* Shortcut - if its the first one, call rb_dlinkAdd only */
|
||||||
|
if(b == list->head)
|
||||||
|
{
|
||||||
|
rb_dlinkAdd(data, m, list);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m->data = data;
|
||||||
|
b->prev->next = m;
|
||||||
|
m->prev = b->prev;
|
||||||
|
b->prev = m;
|
||||||
|
m->next = b;
|
||||||
|
list->length++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
rb_dlinkMoveTail(rb_dlink_node *m, rb_dlink_list *list)
|
||||||
|
{
|
||||||
|
if(list->tail == m)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* From here assume that m->next != NULL as that can only
|
||||||
|
* be at the tail and assume that the node is on the list
|
||||||
|
*/
|
||||||
|
|
||||||
|
m->next->prev = m->prev;
|
||||||
|
|
||||||
|
if(m->prev != NULL)
|
||||||
|
m->prev->next = m->next;
|
||||||
|
else
|
||||||
|
list->head = m->next;
|
||||||
|
|
||||||
|
list->tail->next = m;
|
||||||
|
m->prev = list->tail;
|
||||||
|
m->next = NULL;
|
||||||
|
list->tail = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
rb_dlinkAddTail(void *data, rb_dlink_node * m, rb_dlink_list * list)
|
||||||
|
{
|
||||||
|
assert(m != NULL);
|
||||||
|
assert(list != NULL);
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
m->data = data;
|
||||||
|
m->next = NULL;
|
||||||
|
m->prev = list->tail;
|
||||||
|
|
||||||
|
/* Assumption: If list->tail != NULL, list->head != NULL */
|
||||||
|
if(list->tail != NULL)
|
||||||
|
list->tail->next = m;
|
||||||
|
else if(list->head == NULL)
|
||||||
|
list->head = m;
|
||||||
|
|
||||||
|
list->tail = m;
|
||||||
|
list->length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Execution profiles show that this function is called the most
|
||||||
|
* often of all non-spontaneous functions. So it had better be
|
||||||
|
* efficient. */
|
||||||
|
static inline void
|
||||||
|
rb_dlinkDelete(rb_dlink_node * m, rb_dlink_list * list)
|
||||||
|
{
|
||||||
|
assert(m != NULL);
|
||||||
|
assert(list != NULL);
|
||||||
|
/* Assumption: If m->next == NULL, then list->tail == m
|
||||||
|
* and: If m->prev == NULL, then list->head == m
|
||||||
|
*/
|
||||||
|
if(m->next)
|
||||||
|
m->next->prev = m->prev;
|
||||||
|
else
|
||||||
|
list->tail = m->prev;
|
||||||
|
|
||||||
|
if(m->prev)
|
||||||
|
m->prev->next = m->next;
|
||||||
|
else
|
||||||
|
list->head = m->next;
|
||||||
|
|
||||||
|
m->next = m->prev = NULL;
|
||||||
|
list->length--;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline rb_dlink_node *
|
||||||
|
rb_dlinkFindDelete(void *data, rb_dlink_list *list)
|
||||||
|
{
|
||||||
|
rb_dlink_node *m;
|
||||||
|
assert(list != NULL);
|
||||||
|
assert(data != NULL);
|
||||||
|
RB_DLINK_FOREACH(m, list->head)
|
||||||
|
{
|
||||||
|
if(m->data != data)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(m->next)
|
||||||
|
m->next->prev = m->prev;
|
||||||
|
else
|
||||||
|
list->tail = m->prev;
|
||||||
|
|
||||||
|
if(m->prev)
|
||||||
|
m->prev->next = m->next;
|
||||||
|
else
|
||||||
|
list->head = m->next;
|
||||||
|
|
||||||
|
m->next = m->prev = NULL;
|
||||||
|
list->length--;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
rb_dlinkFindDestroy(void *data, rb_dlink_list *list)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
assert(list != NULL);
|
||||||
|
assert(data != NULL);
|
||||||
|
ptr = rb_dlinkFindDelete(data, list);
|
||||||
|
|
||||||
|
if(ptr != NULL)
|
||||||
|
{
|
||||||
|
rb_free_rb_dlink_node(ptr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_dlinkFind
|
||||||
|
* inputs - list to search
|
||||||
|
* - data
|
||||||
|
* output - pointer to link or NULL if not found
|
||||||
|
* side effects - Look for ptr in the linked listed pointed to by link.
|
||||||
|
*/
|
||||||
|
static inline rb_dlink_node *
|
||||||
|
rb_dlinkFind(void *data, rb_dlink_list *list)
|
||||||
|
{
|
||||||
|
rb_dlink_node *ptr;
|
||||||
|
assert(list != NULL);
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
RB_DLINK_FOREACH(ptr, list->head)
|
||||||
|
{
|
||||||
|
if(ptr->data == data)
|
||||||
|
return (ptr);
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
rb_dlinkMoveList(rb_dlink_list * from, rb_dlink_list * to)
|
||||||
|
{
|
||||||
|
assert(from != NULL);
|
||||||
|
assert(to != NULL);
|
||||||
|
|
||||||
|
/* There are three cases */
|
||||||
|
/* case one, nothing in from list */
|
||||||
|
if(from->head == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* case two, nothing in to list */
|
||||||
|
if(to->head == NULL)
|
||||||
|
{
|
||||||
|
to->head = from->head;
|
||||||
|
to->tail = from->tail;
|
||||||
|
from->head = from->tail = NULL;
|
||||||
|
to->length = from->length;
|
||||||
|
from->length = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* third case play with the links */
|
||||||
|
from->tail->next = to->head;
|
||||||
|
to->head->prev = from->tail;
|
||||||
|
to->head = from->head;
|
||||||
|
from->head = from->tail = NULL;
|
||||||
|
to->length += from->length;
|
||||||
|
from->length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __TOOLS_H__ */
|
325
libratbox/install-sh
Executable file
325
libratbox/install-sh
Executable file
|
@ -0,0 +1,325 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# install - install a program, script, or datafile
|
||||||
|
|
||||||
|
scriptversion=2004-04-01.17
|
||||||
|
|
||||||
|
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||||
|
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||||
|
# following copyright and license.
|
||||||
|
#
|
||||||
|
# Copyright (C) 1994 X Consortium
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||||
|
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
# Except as contained in this notice, the name of the X Consortium shall not
|
||||||
|
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||||
|
# ings in this Software without prior written authorization from the X Consor-
|
||||||
|
# tium.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FSF changes to this file are in the public domain.
|
||||||
|
#
|
||||||
|
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||||
|
# `make' implicit rules from creating a file called install from it
|
||||||
|
# when there is no Makefile.
|
||||||
|
#
|
||||||
|
# This script is compatible with the BSD install script, but was written
|
||||||
|
# from scratch. It can only install one file at a time, a restriction
|
||||||
|
# shared with many OS's install programs.
|
||||||
|
|
||||||
|
# set DOITPROG to echo to test this script
|
||||||
|
|
||||||
|
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||||
|
doit="${DOITPROG-}"
|
||||||
|
|
||||||
|
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||||
|
|
||||||
|
mvprog="${MVPROG-mv}"
|
||||||
|
cpprog="${CPPROG-cp}"
|
||||||
|
chmodprog="${CHMODPROG-chmod}"
|
||||||
|
chownprog="${CHOWNPROG-chown}"
|
||||||
|
chgrpprog="${CHGRPPROG-chgrp}"
|
||||||
|
stripprog="${STRIPPROG-strip}"
|
||||||
|
rmprog="${RMPROG-rm}"
|
||||||
|
mkdirprog="${MKDIRPROG-mkdir}"
|
||||||
|
|
||||||
|
transformbasename=
|
||||||
|
transform_arg=
|
||||||
|
instcmd="$mvprog"
|
||||||
|
chmodcmd="$chmodprog 0755"
|
||||||
|
chowncmd=
|
||||||
|
chgrpcmd=
|
||||||
|
stripcmd=
|
||||||
|
rmcmd="$rmprog -f"
|
||||||
|
mvcmd="$mvprog"
|
||||||
|
src=
|
||||||
|
dst=
|
||||||
|
dir_arg=
|
||||||
|
|
||||||
|
usage="Usage: $0 [OPTION]... SRCFILE DSTFILE
|
||||||
|
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||||
|
or: $0 -d DIRECTORIES...
|
||||||
|
|
||||||
|
In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default.
|
||||||
|
In the second, create the directory path DIR.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-b=TRANSFORMBASENAME
|
||||||
|
-c copy source (using $cpprog) instead of moving (using $mvprog).
|
||||||
|
-d create directories instead of installing files.
|
||||||
|
-g GROUP $chgrp installed files to GROUP.
|
||||||
|
-m MODE $chmod installed files to MODE.
|
||||||
|
-o USER $chown installed files to USER.
|
||||||
|
-s strip installed files (using $stripprog).
|
||||||
|
-t=TRANSFORM
|
||||||
|
--help display this help and exit.
|
||||||
|
--version display version info and exit.
|
||||||
|
|
||||||
|
Environment variables override the default commands:
|
||||||
|
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
|
||||||
|
"
|
||||||
|
|
||||||
|
while test -n "$1"; do
|
||||||
|
case $1 in
|
||||||
|
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-c) instcmd=$cpprog
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-d) dir_arg=true
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-g) chgrpcmd="$chgrpprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
--help) echo "$usage"; exit 0;;
|
||||||
|
|
||||||
|
-m) chmodcmd="$chmodprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-o) chowncmd="$chownprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-s) stripcmd=$stripprog
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
--version) echo "$0 $scriptversion"; exit 0;;
|
||||||
|
|
||||||
|
*) # When -d is used, all remaining arguments are directories to create.
|
||||||
|
test -n "$dir_arg" && break
|
||||||
|
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
if test -n "$dstarg"; then
|
||||||
|
# $@ is not empty: it contains at least $arg.
|
||||||
|
set fnord "$@" "$dstarg"
|
||||||
|
shift # fnord
|
||||||
|
fi
|
||||||
|
shift # arg
|
||||||
|
dstarg=$arg
|
||||||
|
done
|
||||||
|
break;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -z "$1"; then
|
||||||
|
if test -z "$dir_arg"; then
|
||||||
|
echo "$0: no input file specified." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# It's OK to call `install-sh -d' without argument.
|
||||||
|
# This can happen when creating conditional directories.
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for src
|
||||||
|
do
|
||||||
|
# Protect names starting with `-'.
|
||||||
|
case $src in
|
||||||
|
-*) src=./$src ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
dst=$src
|
||||||
|
src=
|
||||||
|
|
||||||
|
if test -d "$dst"; then
|
||||||
|
instcmd=:
|
||||||
|
chmodcmd=
|
||||||
|
else
|
||||||
|
instcmd=$mkdirprog
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||||
|
# might cause directories to be created, which would be especially bad
|
||||||
|
# if $src (and thus $dsttmp) contains '*'.
|
||||||
|
if test ! -f "$src" && test ! -d "$src"; then
|
||||||
|
echo "$0: $src does not exist." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$dstarg"; then
|
||||||
|
echo "$0: no destination specified." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
dst=$dstarg
|
||||||
|
# Protect names starting with `-'.
|
||||||
|
case $dst in
|
||||||
|
-*) dst=./$dst ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# If destination is a directory, append the input filename; won't work
|
||||||
|
# if double slashes aren't ignored.
|
||||||
|
if test -d "$dst"; then
|
||||||
|
dst=$dst/`basename "$src"`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This sed command emulates the dirname command.
|
||||||
|
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||||
|
|
||||||
|
# Make sure that the destination directory exists.
|
||||||
|
|
||||||
|
# Skip lots of stat calls in the usual case.
|
||||||
|
if test ! -d "$dstdir"; then
|
||||||
|
defaultIFS='
|
||||||
|
'
|
||||||
|
IFS="${IFS-$defaultIFS}"
|
||||||
|
|
||||||
|
oIFS=$IFS
|
||||||
|
# Some sh's can't handle IFS=/ for some reason.
|
||||||
|
IFS='%'
|
||||||
|
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||||
|
IFS=$oIFS
|
||||||
|
|
||||||
|
pathcomp=
|
||||||
|
|
||||||
|
while test $# -ne 0 ; do
|
||||||
|
pathcomp=$pathcomp$1
|
||||||
|
shift
|
||||||
|
if test ! -d "$pathcomp"; then
|
||||||
|
$mkdirprog "$pathcomp" || lasterr=$?
|
||||||
|
# mkdir can fail with a `File exist' error in case several
|
||||||
|
# install-sh are creating the directory concurrently. This
|
||||||
|
# is OK.
|
||||||
|
test ! -d "$pathcomp" && { (exit ${lasterr-1}); exit; }
|
||||||
|
fi
|
||||||
|
pathcomp=$pathcomp/
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
$doit $instcmd "$dst" \
|
||||||
|
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
|
||||||
|
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
|
||||||
|
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
|
||||||
|
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
|
||||||
|
|
||||||
|
else
|
||||||
|
# If we're going to rename the final executable, determine the name now.
|
||||||
|
if test -z "$transformarg"; then
|
||||||
|
dstfile=`basename "$dst"`
|
||||||
|
else
|
||||||
|
dstfile=`basename "$dst" $transformbasename \
|
||||||
|
| sed $transformarg`$transformbasename
|
||||||
|
fi
|
||||||
|
|
||||||
|
# don't allow the sed command to completely eliminate the filename.
|
||||||
|
test -z "$dstfile" && dstfile=`basename "$dst"`
|
||||||
|
|
||||||
|
# Make a couple of temp file names in the proper directory.
|
||||||
|
dsttmp=$dstdir/_inst.$$_
|
||||||
|
rmtmp=$dstdir/_rm.$$_
|
||||||
|
|
||||||
|
# Trap to clean up those temp files at exit.
|
||||||
|
trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
|
||||||
|
trap '(exit $?); exit' 1 2 13 15
|
||||||
|
|
||||||
|
# Move or copy the file name to the temp name
|
||||||
|
$doit $instcmd "$src" "$dsttmp" &&
|
||||||
|
|
||||||
|
# and set any options; do chmod last to preserve setuid bits.
|
||||||
|
#
|
||||||
|
# If any of these fail, we abort the whole thing. If we want to
|
||||||
|
# ignore errors from any of these, just make sure not to ignore
|
||||||
|
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||||
|
#
|
||||||
|
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
|
||||||
|
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
|
||||||
|
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
|
||||||
|
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
|
||||||
|
|
||||||
|
# Now rename the file to the real destination.
|
||||||
|
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|
||||||
|
|| {
|
||||||
|
# The rename failed, perhaps because mv can't rename something else
|
||||||
|
# to itself, or perhaps because mv is so ancient that it does not
|
||||||
|
# support -f.
|
||||||
|
|
||||||
|
# Now remove or move aside any old file at destination location.
|
||||||
|
# We try this two ways since rm can't unlink itself on some
|
||||||
|
# systems and the destination file might be busy for other
|
||||||
|
# reasons. In this case, the final cleanup might fail but the new
|
||||||
|
# file should still install successfully.
|
||||||
|
{
|
||||||
|
if test -f "$dstdir/$dstfile"; then
|
||||||
|
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|
||||||
|
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|
||||||
|
|| {
|
||||||
|
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
|
||||||
|
(exit 1); exit
|
||||||
|
}
|
||||||
|
else
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
} &&
|
||||||
|
|
||||||
|
# Now rename the file to the real destination.
|
||||||
|
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fi || { (exit 1); exit; }
|
||||||
|
done
|
||||||
|
|
||||||
|
# The final little trick to "correctly" pass the exit status to the exit trap.
|
||||||
|
{
|
||||||
|
(exit 0); exit
|
||||||
|
}
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-end: "$"
|
||||||
|
# End:
|
6938
libratbox/ltmain.sh
Normal file
6938
libratbox/ltmain.sh
Normal file
File diff suppressed because it is too large
Load diff
360
libratbox/missing
Executable file
360
libratbox/missing
Executable file
|
@ -0,0 +1,360 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# Common stub for a few missing GNU programs while installing.
|
||||||
|
|
||||||
|
scriptversion=2003-09-02.23
|
||||||
|
|
||||||
|
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
if test $# -eq 0; then
|
||||||
|
echo 1>&2 "Try \`$0 --help' for more information"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
run=:
|
||||||
|
|
||||||
|
# In the cases where this matters, `missing' is being run in the
|
||||||
|
# srcdir already.
|
||||||
|
if test -f configure.ac; then
|
||||||
|
configure_ac=configure.ac
|
||||||
|
else
|
||||||
|
configure_ac=configure.in
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg="missing on your system"
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
--run)
|
||||||
|
# Try to run requested program, and just exit if it succeeds.
|
||||||
|
run=
|
||||||
|
shift
|
||||||
|
"$@" && exit 0
|
||||||
|
# Exit code 63 means version mismatch. This often happens
|
||||||
|
# when the user try to use an ancient version of a tool on
|
||||||
|
# a file that requires a minimum version. In this case we
|
||||||
|
# we should proceed has if the program had been absent, or
|
||||||
|
# if --run hadn't been passed.
|
||||||
|
if test $? = 63; then
|
||||||
|
run=:
|
||||||
|
msg="probably too old"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# If it does not exist, or fails to run (possibly an outdated version),
|
||||||
|
# try to emulate it.
|
||||||
|
case "$1" in
|
||||||
|
|
||||||
|
-h|--h|--he|--hel|--help)
|
||||||
|
echo "\
|
||||||
|
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||||
|
|
||||||
|
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
|
||||||
|
error status if there is no known handling for PROGRAM.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help display this help and exit
|
||||||
|
-v, --version output version information and exit
|
||||||
|
--run try to run the given command, and emulate it if it fails
|
||||||
|
|
||||||
|
Supported PROGRAM values:
|
||||||
|
aclocal touch file \`aclocal.m4'
|
||||||
|
autoconf touch file \`configure'
|
||||||
|
autoheader touch file \`config.h.in'
|
||||||
|
automake touch all \`Makefile.in' files
|
||||||
|
bison create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||||
|
flex create \`lex.yy.c', if possible, from existing .c
|
||||||
|
help2man touch the output file
|
||||||
|
lex create \`lex.yy.c', if possible, from existing .c
|
||||||
|
makeinfo touch the output file
|
||||||
|
tar try tar, gnutar, gtar, then tar without non-portable flags
|
||||||
|
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||||
|
|
||||||
|
Send bug reports to <bug-automake@gnu.org>."
|
||||||
|
;;
|
||||||
|
|
||||||
|
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||||
|
echo "missing $scriptversion (GNU Automake)"
|
||||||
|
;;
|
||||||
|
|
||||||
|
-*)
|
||||||
|
echo 1>&2 "$0: Unknown \`$1' option"
|
||||||
|
echo 1>&2 "Try \`$0 --help' for more information"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
aclocal*)
|
||||||
|
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||||
|
# We have it, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
|
||||||
|
to install the \`Automake' and \`Perl' packages. Grab them from
|
||||||
|
any GNU archive site."
|
||||||
|
touch aclocal.m4
|
||||||
|
;;
|
||||||
|
|
||||||
|
autoconf)
|
||||||
|
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||||
|
# We have it, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified \`${configure_ac}'. You might want to install the
|
||||||
|
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
|
||||||
|
archive site."
|
||||||
|
touch configure
|
||||||
|
;;
|
||||||
|
|
||||||
|
autoheader)
|
||||||
|
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||||
|
# We have it, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified \`acconfig.h' or \`${configure_ac}'. You might want
|
||||||
|
to install the \`Autoconf' and \`GNU m4' packages. Grab them
|
||||||
|
from any GNU archive site."
|
||||||
|
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
|
||||||
|
test -z "$files" && files="config.h"
|
||||||
|
touch_files=
|
||||||
|
for f in $files; do
|
||||||
|
case "$f" in
|
||||||
|
*:*) touch_files="$touch_files "`echo "$f" |
|
||||||
|
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
|
||||||
|
*) touch_files="$touch_files $f.in";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
touch $touch_files
|
||||||
|
;;
|
||||||
|
|
||||||
|
automake*)
|
||||||
|
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||||
|
# We have it, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
|
||||||
|
You might want to install the \`Automake' and \`Perl' packages.
|
||||||
|
Grab them from any GNU archive site."
|
||||||
|
find . -type f -name Makefile.am -print |
|
||||||
|
sed 's/\.am$/.in/' |
|
||||||
|
while read f; do touch "$f"; done
|
||||||
|
;;
|
||||||
|
|
||||||
|
autom4te)
|
||||||
|
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||||
|
# We have it, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is needed, but is $msg.
|
||||||
|
You might have modified some files without having the
|
||||||
|
proper tools for further handling them.
|
||||||
|
You can get \`$1' as part of \`Autoconf' from any GNU
|
||||||
|
archive site."
|
||||||
|
|
||||||
|
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
|
||||||
|
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
|
||||||
|
if test -f "$file"; then
|
||||||
|
touch $file
|
||||||
|
else
|
||||||
|
test -z "$file" || exec >$file
|
||||||
|
echo "#! /bin/sh"
|
||||||
|
echo "# Created by GNU Automake missing as a replacement of"
|
||||||
|
echo "# $ $@"
|
||||||
|
echo "exit 0"
|
||||||
|
chmod +x $file
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
bison|yacc)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' $msg. You should only need it if
|
||||||
|
you modified a \`.y' file. You may need the \`Bison' package
|
||||||
|
in order for those modifications to take effect. You can get
|
||||||
|
\`Bison' from any GNU archive site."
|
||||||
|
rm -f y.tab.c y.tab.h
|
||||||
|
if [ $# -ne 1 ]; then
|
||||||
|
eval LASTARG="\${$#}"
|
||||||
|
case "$LASTARG" in
|
||||||
|
*.y)
|
||||||
|
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
|
||||||
|
if [ -f "$SRCFILE" ]; then
|
||||||
|
cp "$SRCFILE" y.tab.c
|
||||||
|
fi
|
||||||
|
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
|
||||||
|
if [ -f "$SRCFILE" ]; then
|
||||||
|
cp "$SRCFILE" y.tab.h
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
if [ ! -f y.tab.h ]; then
|
||||||
|
echo >y.tab.h
|
||||||
|
fi
|
||||||
|
if [ ! -f y.tab.c ]; then
|
||||||
|
echo 'main() { return 0; }' >y.tab.c
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
lex|flex)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified a \`.l' file. You may need the \`Flex' package
|
||||||
|
in order for those modifications to take effect. You can get
|
||||||
|
\`Flex' from any GNU archive site."
|
||||||
|
rm -f lex.yy.c
|
||||||
|
if [ $# -ne 1 ]; then
|
||||||
|
eval LASTARG="\${$#}"
|
||||||
|
case "$LASTARG" in
|
||||||
|
*.l)
|
||||||
|
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
|
||||||
|
if [ -f "$SRCFILE" ]; then
|
||||||
|
cp "$SRCFILE" lex.yy.c
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
if [ ! -f lex.yy.c ]; then
|
||||||
|
echo 'main() { return 0; }' >lex.yy.c
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
help2man)
|
||||||
|
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||||
|
# We have it, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified a dependency of a manual page. You may need the
|
||||||
|
\`Help2man' package in order for those modifications to take
|
||||||
|
effect. You can get \`Help2man' from any GNU archive site."
|
||||||
|
|
||||||
|
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||||
|
if test -z "$file"; then
|
||||||
|
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
|
||||||
|
fi
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
touch $file
|
||||||
|
else
|
||||||
|
test -z "$file" || exec >$file
|
||||||
|
echo ".ab help2man is required to generate this page"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
makeinfo)
|
||||||
|
if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
|
||||||
|
# We have makeinfo, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is $msg. You should only need it if
|
||||||
|
you modified a \`.texi' or \`.texinfo' file, or any other file
|
||||||
|
indirectly affecting the aspect of the manual. The spurious
|
||||||
|
call might also be the consequence of using a buggy \`make' (AIX,
|
||||||
|
DU, IRIX). You might want to install the \`Texinfo' package or
|
||||||
|
the \`GNU make' package. Grab either from any GNU archive site."
|
||||||
|
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||||
|
if test -z "$file"; then
|
||||||
|
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
|
||||||
|
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
|
||||||
|
fi
|
||||||
|
touch $file
|
||||||
|
;;
|
||||||
|
|
||||||
|
tar)
|
||||||
|
shift
|
||||||
|
if test -n "$run"; then
|
||||||
|
echo 1>&2 "ERROR: \`tar' requires --run"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# We have already tried tar in the generic part.
|
||||||
|
# Look for gnutar/gtar before invocation to avoid ugly error
|
||||||
|
# messages.
|
||||||
|
if (gnutar --version > /dev/null 2>&1); then
|
||||||
|
gnutar "$@" && exit 0
|
||||||
|
fi
|
||||||
|
if (gtar --version > /dev/null 2>&1); then
|
||||||
|
gtar "$@" && exit 0
|
||||||
|
fi
|
||||||
|
firstarg="$1"
|
||||||
|
if shift; then
|
||||||
|
case "$firstarg" in
|
||||||
|
*o*)
|
||||||
|
firstarg=`echo "$firstarg" | sed s/o//`
|
||||||
|
tar "$firstarg" "$@" && exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case "$firstarg" in
|
||||||
|
*h*)
|
||||||
|
firstarg=`echo "$firstarg" | sed s/h//`
|
||||||
|
tar "$firstarg" "$@" && exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: I can't seem to be able to run \`tar' with the given arguments.
|
||||||
|
You may want to install GNU tar or Free paxutils, or check the
|
||||||
|
command line arguments."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is needed, and is $msg.
|
||||||
|
You might have modified some files without having the
|
||||||
|
proper tools for further handling them. Check the \`README' file,
|
||||||
|
it often tells you about the needed prerequisites for installing
|
||||||
|
this package. You may also peek at any GNU archive site, in case
|
||||||
|
some other package would contain this missing \`$1' program."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-end: "$"
|
||||||
|
# End:
|
36
libratbox/src/Makefile.am
Normal file
36
libratbox/src/Makefile.am
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# $Id: Makefile.am 24820 2008-01-02 19:47:32Z androsyn $
|
||||||
|
|
||||||
|
AUTOMAKE_OPTIONS = foreign
|
||||||
|
|
||||||
|
INCLUDES = -I. -I../include @SSL_INCLUDES@
|
||||||
|
|
||||||
|
libratbox_la_SOURCES = \
|
||||||
|
unix.c \
|
||||||
|
win32.c \
|
||||||
|
crypt.c \
|
||||||
|
balloc.c \
|
||||||
|
commio.c \
|
||||||
|
openssl.c \
|
||||||
|
nossl.c \
|
||||||
|
event.c \
|
||||||
|
ratbox_lib.c \
|
||||||
|
rb_memory.c \
|
||||||
|
linebuf.c \
|
||||||
|
snprintf.c \
|
||||||
|
tools.c \
|
||||||
|
helper.c \
|
||||||
|
devpoll.c \
|
||||||
|
epoll.c \
|
||||||
|
poll.c \
|
||||||
|
ports.c \
|
||||||
|
sigio.c \
|
||||||
|
select.c \
|
||||||
|
kqueue.c \
|
||||||
|
rawbuf.c \
|
||||||
|
patricia.c
|
||||||
|
|
||||||
|
|
||||||
|
libratbox_la_LDFLAGS = -avoid-version -no-undefined -export-symbols export-syms.txt
|
||||||
|
libratbox_la_LIBADD = @CRYPT_LIB@ @SSL_LIBS@
|
||||||
|
lib_LTLIBRARIES = libratbox.la
|
||||||
|
|
537
libratbox/src/Makefile.in
Normal file
537
libratbox/src/Makefile.in
Normal file
|
@ -0,0 +1,537 @@
|
||||||
|
# Makefile.in generated by automake 1.10 from Makefile.am.
|
||||||
|
# @configure_input@
|
||||||
|
|
||||||
|
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||||
|
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||||
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||||
|
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
@SET_MAKE@
|
||||||
|
|
||||||
|
# $Id: Makefile.am 24808 2008-01-02 08:17:05Z androsyn $
|
||||||
|
|
||||||
|
VPATH = @srcdir@
|
||||||
|
pkgdatadir = $(datadir)/@PACKAGE@
|
||||||
|
pkglibdir = $(libdir)/@PACKAGE@
|
||||||
|
pkgincludedir = $(includedir)/@PACKAGE@
|
||||||
|
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||||
|
install_sh_DATA = $(install_sh) -c -m 644
|
||||||
|
install_sh_PROGRAM = $(install_sh) -c
|
||||||
|
install_sh_SCRIPT = $(install_sh) -c
|
||||||
|
INSTALL_HEADER = $(INSTALL_DATA)
|
||||||
|
transform = $(program_transform_name)
|
||||||
|
NORMAL_INSTALL = :
|
||||||
|
PRE_INSTALL = :
|
||||||
|
POST_INSTALL = :
|
||||||
|
NORMAL_UNINSTALL = :
|
||||||
|
PRE_UNINSTALL = :
|
||||||
|
POST_UNINSTALL = :
|
||||||
|
build_triplet = @build@
|
||||||
|
host_triplet = @host@
|
||||||
|
subdir = src
|
||||||
|
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||||
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
|
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
|
||||||
|
$(top_srcdir)/configure.ac
|
||||||
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
|
$(ACLOCAL_M4)
|
||||||
|
mkinstalldirs = $(install_sh) -d
|
||||||
|
CONFIG_HEADER = $(top_builddir)/include/libratbox_config.h
|
||||||
|
CONFIG_CLEAN_FILES =
|
||||||
|
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||||
|
am__vpath_adj = case $$p in \
|
||||||
|
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||||
|
*) f=$$p;; \
|
||||||
|
esac;
|
||||||
|
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
|
||||||
|
am__installdirs = "$(DESTDIR)$(libdir)"
|
||||||
|
libLTLIBRARIES_INSTALL = $(INSTALL)
|
||||||
|
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||||
|
libratbox_la_DEPENDENCIES =
|
||||||
|
am_libratbox_la_OBJECTS = unix.lo win32.lo crypt.lo balloc.lo \
|
||||||
|
commio.lo openssl.lo nossl.lo event.lo ratbox_lib.lo \
|
||||||
|
rb_memory.lo linebuf.lo snprintf.lo tools.lo helper.lo \
|
||||||
|
devpoll.lo epoll.lo poll.lo ports.lo sigio.lo select.lo \
|
||||||
|
kqueue.lo rawbuf.lo patricia.lo
|
||||||
|
libratbox_la_OBJECTS = $(am_libratbox_la_OBJECTS)
|
||||||
|
libratbox_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||||
|
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||||
|
$(libratbox_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||||
|
DEFAULT_INCLUDES = -I. -I$(top_builddir)/include@am__isrc@
|
||||||
|
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||||
|
am__depfiles_maybe = depfiles
|
||||||
|
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||||
|
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
|
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||||
|
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||||
|
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
|
CCLD = $(CC)
|
||||||
|
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||||
|
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||||
|
$(LDFLAGS) -o $@
|
||||||
|
SOURCES = $(libratbox_la_SOURCES)
|
||||||
|
DIST_SOURCES = $(libratbox_la_SOURCES)
|
||||||
|
ETAGS = etags
|
||||||
|
CTAGS = ctags
|
||||||
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
ACLOCAL = @ACLOCAL@
|
||||||
|
ALLOCA = @ALLOCA@
|
||||||
|
AMTAR = @AMTAR@
|
||||||
|
AR = @AR@
|
||||||
|
AS = @AS@
|
||||||
|
AUTOCONF = @AUTOCONF@
|
||||||
|
AUTOHEADER = @AUTOHEADER@
|
||||||
|
AUTOMAKE = @AUTOMAKE@
|
||||||
|
AWK = @AWK@
|
||||||
|
CC = @CC@
|
||||||
|
CCDEPMODE = @CCDEPMODE@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CP = @CP@
|
||||||
|
CPP = @CPP@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CRYPT_LIB = @CRYPT_LIB@
|
||||||
|
CXX = @CXX@
|
||||||
|
CXXCPP = @CXXCPP@
|
||||||
|
CXXDEPMODE = @CXXDEPMODE@
|
||||||
|
CXXFLAGS = @CXXFLAGS@
|
||||||
|
CYGPATH_W = @CYGPATH_W@
|
||||||
|
DEFS = @DEFS@
|
||||||
|
DEPDIR = @DEPDIR@
|
||||||
|
ECHO = @ECHO@
|
||||||
|
ECHO_C = @ECHO_C@
|
||||||
|
ECHO_N = @ECHO_N@
|
||||||
|
ECHO_T = @ECHO_T@
|
||||||
|
EGREP = @EGREP@
|
||||||
|
EXEEXT = @EXEEXT@
|
||||||
|
F77 = @F77@
|
||||||
|
FFLAGS = @FFLAGS@
|
||||||
|
GREP = @GREP@
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
|
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||||
|
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||||
|
LD = @LD@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBOBJS = @LIBOBJS@
|
||||||
|
LIBS = @LIBS@
|
||||||
|
LIBTOOL = @LIBTOOL@
|
||||||
|
LN = @LN@
|
||||||
|
LN_S = @LN_S@
|
||||||
|
LTLIBOBJS = @LTLIBOBJS@
|
||||||
|
MAINT = @MAINT@
|
||||||
|
MAKEINFO = @MAKEINFO@
|
||||||
|
MKDIR_P = @MKDIR_P@
|
||||||
|
MV = @MV@
|
||||||
|
OBJEXT = @OBJEXT@
|
||||||
|
PACKAGE = @PACKAGE@
|
||||||
|
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||||
|
PACKAGE_NAME = @PACKAGE_NAME@
|
||||||
|
PACKAGE_STRING = @PACKAGE_STRING@
|
||||||
|
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||||
|
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||||
|
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||||
|
PICFLAGS = @PICFLAGS@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
RB_PREFIX = @RB_PREFIX@
|
||||||
|
RM = @RM@
|
||||||
|
SED = @SED@
|
||||||
|
SEDOBJ = @SEDOBJ@
|
||||||
|
SET_MAKE = @SET_MAKE@
|
||||||
|
SHELL = @SHELL@
|
||||||
|
SSL_INCLUDES = @SSL_INCLUDES@
|
||||||
|
SSL_LIBS = @SSL_LIBS@
|
||||||
|
STRIP = @STRIP@
|
||||||
|
TOUCH = @TOUCH@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
abs_builddir = @abs_builddir@
|
||||||
|
abs_srcdir = @abs_srcdir@
|
||||||
|
abs_top_builddir = @abs_top_builddir@
|
||||||
|
abs_top_srcdir = @abs_top_srcdir@
|
||||||
|
ac_ct_CC = @ac_ct_CC@
|
||||||
|
ac_ct_CXX = @ac_ct_CXX@
|
||||||
|
ac_ct_F77 = @ac_ct_F77@
|
||||||
|
am__include = @am__include@
|
||||||
|
am__leading_dot = @am__leading_dot@
|
||||||
|
am__quote = @am__quote@
|
||||||
|
am__tar = @am__tar@
|
||||||
|
am__untar = @am__untar@
|
||||||
|
bindir = @bindir@
|
||||||
|
build = @build@
|
||||||
|
build_alias = @build_alias@
|
||||||
|
build_cpu = @build_cpu@
|
||||||
|
build_os = @build_os@
|
||||||
|
build_vendor = @build_vendor@
|
||||||
|
builddir = @builddir@
|
||||||
|
datadir = @datadir@
|
||||||
|
datarootdir = @datarootdir@
|
||||||
|
docdir = @docdir@
|
||||||
|
dvidir = @dvidir@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
host = @host@
|
||||||
|
host_alias = @host_alias@
|
||||||
|
host_cpu = @host_cpu@
|
||||||
|
host_os = @host_os@
|
||||||
|
host_vendor = @host_vendor@
|
||||||
|
htmldir = @htmldir@
|
||||||
|
includedir = @includedir@
|
||||||
|
infodir = @infodir@
|
||||||
|
install_sh = @install_sh@
|
||||||
|
libdir = @libdir@
|
||||||
|
libexecdir = @libexecdir@
|
||||||
|
localedir = @localedir@
|
||||||
|
localstatedir = @localstatedir@
|
||||||
|
mandir = @mandir@
|
||||||
|
mkdir_p = @mkdir_p@
|
||||||
|
oldincludedir = @oldincludedir@
|
||||||
|
pdfdir = @pdfdir@
|
||||||
|
prefix = @prefix@
|
||||||
|
program_transform_name = @program_transform_name@
|
||||||
|
psdir = @psdir@
|
||||||
|
sbindir = @sbindir@
|
||||||
|
sharedstatedir = @sharedstatedir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
subdirs = @subdirs@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
target_alias = @target_alias@
|
||||||
|
top_builddir = @top_builddir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
AUTOMAKE_OPTIONS = foreign
|
||||||
|
INCLUDES = -I. -I../include @SSL_INCLUDES@
|
||||||
|
libratbox_la_SOURCES = \
|
||||||
|
unix.c \
|
||||||
|
win32.c \
|
||||||
|
crypt.c \
|
||||||
|
balloc.c \
|
||||||
|
commio.c \
|
||||||
|
openssl.c \
|
||||||
|
nossl.c \
|
||||||
|
event.c \
|
||||||
|
ratbox_lib.c \
|
||||||
|
rb_memory.c \
|
||||||
|
linebuf.c \
|
||||||
|
snprintf.c \
|
||||||
|
tools.c \
|
||||||
|
helper.c \
|
||||||
|
devpoll.c \
|
||||||
|
epoll.c \
|
||||||
|
poll.c \
|
||||||
|
ports.c \
|
||||||
|
sigio.c \
|
||||||
|
select.c \
|
||||||
|
kqueue.c \
|
||||||
|
rawbuf.c \
|
||||||
|
patricia.c
|
||||||
|
|
||||||
|
libratbox_la_LDFLAGS = -avoid-version -no-undefined -export-symbols export-syms.txt
|
||||||
|
libratbox_la_LIBADD = @CRYPT_LIB@ @SSL_LIBS@
|
||||||
|
lib_LTLIBRARIES = libratbox.la
|
||||||
|
all: all-am
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .c .lo .o .obj
|
||||||
|
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||||
|
@for dep in $?; do \
|
||||||
|
case '$(am__configure_deps)' in \
|
||||||
|
*$$dep*) \
|
||||||
|
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
|
||||||
|
&& exit 0; \
|
||||||
|
exit 1;; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
|
||||||
|
cd $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --foreign src/Makefile
|
||||||
|
.PRECIOUS: Makefile
|
||||||
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
|
@case '$?' in \
|
||||||
|
*config.status*) \
|
||||||
|
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||||
|
*) \
|
||||||
|
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||||
|
esac;
|
||||||
|
|
||||||
|
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||||
|
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||||
|
|
||||||
|
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||||
|
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||||
|
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||||
|
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||||
|
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||||
|
@$(NORMAL_INSTALL)
|
||||||
|
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
|
||||||
|
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||||
|
if test -f $$p; then \
|
||||||
|
f=$(am__strip_dir) \
|
||||||
|
echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
|
||||||
|
$(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
|
||||||
|
else :; fi; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall-libLTLIBRARIES:
|
||||||
|
@$(NORMAL_UNINSTALL)
|
||||||
|
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||||
|
p=$(am__strip_dir) \
|
||||||
|
echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
|
||||||
|
$(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
|
||||||
|
done
|
||||||
|
|
||||||
|
clean-libLTLIBRARIES:
|
||||||
|
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
|
||||||
|
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||||
|
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||||
|
test "$$dir" != "$$p" || dir=.; \
|
||||||
|
echo "rm -f \"$${dir}/so_locations\""; \
|
||||||
|
rm -f "$${dir}/so_locations"; \
|
||||||
|
done
|
||||||
|
libratbox.la: $(libratbox_la_OBJECTS) $(libratbox_la_DEPENDENCIES)
|
||||||
|
$(libratbox_la_LINK) -rpath $(libdir) $(libratbox_la_OBJECTS) $(libratbox_la_LIBADD) $(LIBS)
|
||||||
|
|
||||||
|
mostlyclean-compile:
|
||||||
|
-rm -f *.$(OBJEXT)
|
||||||
|
|
||||||
|
distclean-compile:
|
||||||
|
-rm -f *.tab.c
|
||||||
|
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/balloc.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commio.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypt.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devpoll.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epoll.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kqueue.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linebuf.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nossl.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/patricia.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poll.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ports.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ratbox_lib.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rawbuf.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb_memory.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/select.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigio.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snprintf.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tools.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/win32.Plo@am__quote@
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||||
|
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
|
||||||
|
|
||||||
|
.c.obj:
|
||||||
|
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||||
|
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||||
|
|
||||||
|
.c.lo:
|
||||||
|
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||||
|
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
|
||||||
|
|
||||||
|
mostlyclean-libtool:
|
||||||
|
-rm -f *.lo
|
||||||
|
|
||||||
|
clean-libtool:
|
||||||
|
-rm -rf .libs _libs
|
||||||
|
|
||||||
|
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
mkid -fID $$unique
|
||||||
|
tags: TAGS
|
||||||
|
|
||||||
|
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
tags=; \
|
||||||
|
here=`pwd`; \
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
|
||||||
|
test -n "$$unique" || unique=$$empty_fix; \
|
||||||
|
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||||
|
$$tags $$unique; \
|
||||||
|
fi
|
||||||
|
ctags: CTAGS
|
||||||
|
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
tags=; \
|
||||||
|
here=`pwd`; \
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|
||||||
|
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||||
|
$$tags $$unique
|
||||||
|
|
||||||
|
GTAGS:
|
||||||
|
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||||
|
&& cd $(top_srcdir) \
|
||||||
|
&& gtags -i $(GTAGS_ARGS) $$here
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
|
|
||||||
|
distdir: $(DISTFILES)
|
||||||
|
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||||
|
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||||
|
list='$(DISTFILES)'; \
|
||||||
|
dist_files=`for file in $$list; do echo $$file; done | \
|
||||||
|
sed -e "s|^$$srcdirstrip/||;t" \
|
||||||
|
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||||
|
case $$dist_files in \
|
||||||
|
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||||
|
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||||
|
sort -u` ;; \
|
||||||
|
esac; \
|
||||||
|
for file in $$dist_files; do \
|
||||||
|
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||||
|
if test -d $$d/$$file; then \
|
||||||
|
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||||
|
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||||
|
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||||
|
fi; \
|
||||||
|
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||||
|
else \
|
||||||
|
test -f $(distdir)/$$file \
|
||||||
|
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||||
|
|| exit 1; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
check-am: all-am
|
||||||
|
check: check-am
|
||||||
|
all-am: Makefile $(LTLIBRARIES)
|
||||||
|
installdirs:
|
||||||
|
for dir in "$(DESTDIR)$(libdir)"; do \
|
||||||
|
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||||
|
done
|
||||||
|
install: install-am
|
||||||
|
install-exec: install-exec-am
|
||||||
|
install-data: install-data-am
|
||||||
|
uninstall: uninstall-am
|
||||||
|
|
||||||
|
install-am: all-am
|
||||||
|
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
|
|
||||||
|
installcheck: installcheck-am
|
||||||
|
install-strip:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
`test -z '$(STRIP)' || \
|
||||||
|
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||||
|
mostlyclean-generic:
|
||||||
|
|
||||||
|
clean-generic:
|
||||||
|
|
||||||
|
distclean-generic:
|
||||||
|
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||||
|
|
||||||
|
maintainer-clean-generic:
|
||||||
|
@echo "This command is intended for maintainers to use"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
clean: clean-am
|
||||||
|
|
||||||
|
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
|
||||||
|
mostlyclean-am
|
||||||
|
|
||||||
|
distclean: distclean-am
|
||||||
|
-rm -rf ./$(DEPDIR)
|
||||||
|
-rm -f Makefile
|
||||||
|
distclean-am: clean-am distclean-compile distclean-generic \
|
||||||
|
distclean-tags
|
||||||
|
|
||||||
|
dvi: dvi-am
|
||||||
|
|
||||||
|
dvi-am:
|
||||||
|
|
||||||
|
html: html-am
|
||||||
|
|
||||||
|
info: info-am
|
||||||
|
|
||||||
|
info-am:
|
||||||
|
|
||||||
|
install-data-am:
|
||||||
|
|
||||||
|
install-dvi: install-dvi-am
|
||||||
|
|
||||||
|
install-exec-am: install-libLTLIBRARIES
|
||||||
|
|
||||||
|
install-html: install-html-am
|
||||||
|
|
||||||
|
install-info: install-info-am
|
||||||
|
|
||||||
|
install-man:
|
||||||
|
|
||||||
|
install-pdf: install-pdf-am
|
||||||
|
|
||||||
|
install-ps: install-ps-am
|
||||||
|
|
||||||
|
installcheck-am:
|
||||||
|
|
||||||
|
maintainer-clean: maintainer-clean-am
|
||||||
|
-rm -rf ./$(DEPDIR)
|
||||||
|
-rm -f Makefile
|
||||||
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||||
|
|
||||||
|
mostlyclean: mostlyclean-am
|
||||||
|
|
||||||
|
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||||
|
mostlyclean-libtool
|
||||||
|
|
||||||
|
pdf: pdf-am
|
||||||
|
|
||||||
|
pdf-am:
|
||||||
|
|
||||||
|
ps: ps-am
|
||||||
|
|
||||||
|
ps-am:
|
||||||
|
|
||||||
|
uninstall-am: uninstall-libLTLIBRARIES
|
||||||
|
|
||||||
|
.MAKE: install-am install-strip
|
||||||
|
|
||||||
|
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||||
|
clean-libLTLIBRARIES clean-libtool ctags distclean \
|
||||||
|
distclean-compile distclean-generic distclean-libtool \
|
||||||
|
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||||
|
install install-am install-data install-data-am install-dvi \
|
||||||
|
install-dvi-am install-exec install-exec-am install-html \
|
||||||
|
install-html-am install-info install-info-am \
|
||||||
|
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
|
||||||
|
install-ps install-ps-am install-strip installcheck \
|
||||||
|
installcheck-am installdirs maintainer-clean \
|
||||||
|
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||||
|
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||||
|
tags uninstall uninstall-am uninstall-libLTLIBRARIES
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
574
libratbox/src/balloc.c
Normal file
574
libratbox/src/balloc.c
Normal file
|
@ -0,0 +1,574 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* balloc.c: A block allocator.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2002-2006 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* Below are the orignal headers from the old blalloc.c
|
||||||
|
*
|
||||||
|
* File: blalloc.c
|
||||||
|
* Owner: Wohali (Joan Touzet)
|
||||||
|
*
|
||||||
|
* Modified 2001/11/29 for mmap() support by Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: balloc.c 25048 2008-01-23 18:34:02Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* About the block allocator
|
||||||
|
*
|
||||||
|
* Basically we have three ways of getting memory off of the operating
|
||||||
|
* system. Below are this list of methods and the order of preference.
|
||||||
|
*
|
||||||
|
* 1. mmap() anonymous pages with the MMAP_ANON flag.
|
||||||
|
* 2. mmap() via the /dev/zero trick.
|
||||||
|
* 3. HeapCreate/HeapAlloc (on win32)
|
||||||
|
* 4. malloc()
|
||||||
|
*
|
||||||
|
* The advantages of 1 and 2 are this. We can munmap() the pages which will
|
||||||
|
* return the pages back to the operating system, thus reducing the size
|
||||||
|
* of the process as the memory is unused. malloc() on many systems just keeps
|
||||||
|
* a heap of memory to itself, which never gets given back to the OS, except on
|
||||||
|
* exit. This of course is bad, if say we have an event that causes us to allocate
|
||||||
|
* say, 200MB of memory, while our normal memory consumption would be 15MB. In the
|
||||||
|
* malloc() case, the amount of memory allocated to our process never goes down, as
|
||||||
|
* malloc() has it locked up in its heap. With the mmap() method, we can munmap()
|
||||||
|
* the block and return it back to the OS, thus causing our memory consumption to go
|
||||||
|
* down after we no longer need it.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_MMAP /* We've got mmap() that is good */
|
||||||
|
#include <sys/mman.h>
|
||||||
|
/* HP-UX sucks */
|
||||||
|
#ifdef MAP_ANONYMOUS
|
||||||
|
#ifndef MAP_ANON
|
||||||
|
#define MAP_ANON MAP_ANONYMOUS
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* status information for an allocated block in heap */
|
||||||
|
struct rb_heap_block
|
||||||
|
{
|
||||||
|
size_t alloc_size;
|
||||||
|
rb_dlink_node node;
|
||||||
|
unsigned long free_count;
|
||||||
|
void *elems; /* Points to allocated memory */
|
||||||
|
};
|
||||||
|
typedef struct rb_heap_block rb_heap_block;
|
||||||
|
|
||||||
|
struct rb_heap_memblock
|
||||||
|
{
|
||||||
|
rb_heap_block *block;
|
||||||
|
union {
|
||||||
|
rb_dlink_node node;
|
||||||
|
char data[1]; /* stub pointer..this is ugly */
|
||||||
|
} ndata;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct rb_heap_memblock rb_heap_memblock;
|
||||||
|
|
||||||
|
/* information for the root node of the heap */
|
||||||
|
struct rb_bh
|
||||||
|
{
|
||||||
|
rb_dlink_node hlist;
|
||||||
|
size_t elemSize; /* Size of each element to be stored */
|
||||||
|
unsigned long elemsPerBlock; /* Number of elements per block */
|
||||||
|
rb_dlink_list block_list;
|
||||||
|
rb_dlink_list free_list;
|
||||||
|
char *desc;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
static int newblock(rb_bh * bh);
|
||||||
|
static void rb_bh_gc_event(void *unused);
|
||||||
|
#endif /* !NOBALLOC */
|
||||||
|
static rb_dlink_list *heap_lists;
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
static HANDLE block_heap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define rb_bh_fail(x) _rb_bh_fail(x, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
static void
|
||||||
|
_rb_bh_fail(const char *reason, const char *file, int line)
|
||||||
|
{
|
||||||
|
rb_lib_log("rb_heap_blockheap failure: %s (%s:%d)", reason, file, line);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
/*
|
||||||
|
* static inline void free_block(void *ptr, size_t size)
|
||||||
|
*
|
||||||
|
* Inputs: The block and its size
|
||||||
|
* Output: None
|
||||||
|
* Side Effects: Returns memory for the block back to the OS
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
free_block(void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_MMAP
|
||||||
|
munmap(ptr, size);
|
||||||
|
#else
|
||||||
|
#ifdef WIN32
|
||||||
|
HeapFree(block_heap, 0, ptr);
|
||||||
|
#else
|
||||||
|
free(ptr);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* !NOBALLOC */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void rb_init_bh(void)
|
||||||
|
*
|
||||||
|
* Inputs: None
|
||||||
|
* Outputs: None
|
||||||
|
* Side Effects: Initializes the block heap
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_init_bh(void)
|
||||||
|
{
|
||||||
|
heap_lists = rb_malloc(sizeof(rb_dlink_list));
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
#ifdef WIN32
|
||||||
|
block_heap = HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
|
||||||
|
#endif
|
||||||
|
rb_event_addish("rb_bh_gc_event", rb_bh_gc_event, NULL, 300);
|
||||||
|
#endif /* !NOBALLOC */
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
/*
|
||||||
|
* static inline void *get_block(size_t size)
|
||||||
|
*
|
||||||
|
* Input: Size of block to allocate
|
||||||
|
* Output: Pointer to new block
|
||||||
|
* Side Effects: None
|
||||||
|
*/
|
||||||
|
static inline void *
|
||||||
|
get_block(size_t size)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
#ifdef HAVE_MMAP
|
||||||
|
#ifdef MAP_ANON
|
||||||
|
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||||
|
#else
|
||||||
|
int zero_fd;
|
||||||
|
zero_fd = open("/dev/zero", O_RDWR);
|
||||||
|
if(zero_fd < 0)
|
||||||
|
rb_bh_fail("Failed opening /dev/zero");
|
||||||
|
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, zero_fd, 0);
|
||||||
|
close(zero_fd);
|
||||||
|
#endif /* MAP_ANON */
|
||||||
|
if(ptr == MAP_FAILED)
|
||||||
|
ptr = NULL;
|
||||||
|
#else
|
||||||
|
#ifdef WIN32
|
||||||
|
ptr = HeapAlloc(block_heap, 0, size);
|
||||||
|
#else
|
||||||
|
ptr = malloc(size);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
rb_bh_gc_event(void *unused)
|
||||||
|
{
|
||||||
|
rb_dlink_node *ptr;
|
||||||
|
RB_DLINK_FOREACH(ptr, heap_lists->head)
|
||||||
|
{
|
||||||
|
rb_bh_gc(ptr->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************ */
|
||||||
|
/* FUNCTION DOCUMENTATION: */
|
||||||
|
/* newblock */
|
||||||
|
/* Description: */
|
||||||
|
/* Allocates a new block for addition to a blockheap */
|
||||||
|
/* Parameters: */
|
||||||
|
/* bh (IN): Pointer to parent blockheap. */
|
||||||
|
/* Returns: */
|
||||||
|
/* 0 if successful, 1 if not */
|
||||||
|
/* ************************************************************************ */
|
||||||
|
|
||||||
|
static int
|
||||||
|
newblock(rb_bh * bh)
|
||||||
|
{
|
||||||
|
rb_heap_block *b;
|
||||||
|
unsigned long i;
|
||||||
|
rb_uintptr_t offset;
|
||||||
|
|
||||||
|
/* Setup the initial data structure. */
|
||||||
|
b = rb_malloc(sizeof(rb_heap_block));
|
||||||
|
|
||||||
|
b->alloc_size = bh->elemsPerBlock * (bh->elemSize + sizeof(rb_heap_block *));
|
||||||
|
|
||||||
|
b->elems = get_block(b->alloc_size);
|
||||||
|
if(unlikely(b->elems == NULL))
|
||||||
|
{
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
offset = (rb_uintptr_t)b->elems;
|
||||||
|
/* Setup our blocks now */
|
||||||
|
for (i = 0; i < bh->elemsPerBlock; i++, offset += (bh->elemSize + sizeof(rb_heap_block *)))
|
||||||
|
{
|
||||||
|
rb_heap_memblock *memblock = (rb_heap_memblock *)offset;
|
||||||
|
memblock->block = b;
|
||||||
|
rb_dlinkAdd(memblock, &memblock->ndata.node, &bh->free_list);
|
||||||
|
}
|
||||||
|
rb_dlinkAdd(b, &b->node, &bh->block_list);
|
||||||
|
b->free_count = bh->elemsPerBlock;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
#endif /* !NOBALLOC */
|
||||||
|
|
||||||
|
/* ************************************************************************ */
|
||||||
|
/* FUNCTION DOCUMENTATION: */
|
||||||
|
/* rb_bh_create */
|
||||||
|
/* Description: */
|
||||||
|
/* Creates a new blockheap from which smaller blocks can be allocated. */
|
||||||
|
/* Intended to be used instead of multiple calls to malloc() when */
|
||||||
|
/* performance is an issue. */
|
||||||
|
/* Parameters: */
|
||||||
|
/* elemsize (IN): Size of the basic element to be stored */
|
||||||
|
/* elemsperblock (IN): Number of elements to be stored in a single block */
|
||||||
|
/* of memory. When the blockheap runs out of free memory, it will */
|
||||||
|
/* allocate elemsize * elemsperblock more. */
|
||||||
|
/* Returns: */
|
||||||
|
/* Pointer to new rb_bh, or NULL if unsuccessful */
|
||||||
|
/* ************************************************************************ */
|
||||||
|
rb_bh *
|
||||||
|
rb_bh_create(size_t elemsize, int elemsperblock, const char *desc)
|
||||||
|
{
|
||||||
|
rb_bh *bh;
|
||||||
|
lrb_assert(elemsize > 0 && elemsperblock > 0);
|
||||||
|
lrb_assert(elemsize >= sizeof(rb_dlink_node));
|
||||||
|
/* Catch idiotic requests up front */
|
||||||
|
if((elemsize <= 0) || (elemsperblock <= 0))
|
||||||
|
{
|
||||||
|
rb_bh_fail("Attempting to rb_bh_create idiotic sizes");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(elemsize < sizeof(rb_dlink_node))
|
||||||
|
rb_bh_fail("Attempt to rb_bh_create smaller than sizeof(rb_dlink_node)");
|
||||||
|
|
||||||
|
/* Allocate our new rb_bh */
|
||||||
|
bh = rb_malloc(sizeof(rb_bh));
|
||||||
|
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
if((elemsize % sizeof(void *)) != 0)
|
||||||
|
{
|
||||||
|
/* Pad to even pointer boundary */
|
||||||
|
elemsize += sizeof(void *);
|
||||||
|
elemsize &= ~(sizeof(void *) - 1);
|
||||||
|
}
|
||||||
|
#endif /* !NOBALLOC */
|
||||||
|
|
||||||
|
bh->elemSize = elemsize;
|
||||||
|
bh->elemsPerBlock = elemsperblock;
|
||||||
|
if(desc != NULL)
|
||||||
|
bh->desc = rb_strdup(desc);
|
||||||
|
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
/* Be sure our malloc was successful */
|
||||||
|
if(newblock(bh))
|
||||||
|
{
|
||||||
|
if(bh != NULL)
|
||||||
|
free(bh);
|
||||||
|
rb_lib_log("newblock() failed");
|
||||||
|
rb_outofmemory(); /* die.. out of memory */
|
||||||
|
}
|
||||||
|
#endif /* !NOBALLOC */
|
||||||
|
|
||||||
|
if(bh == NULL)
|
||||||
|
{
|
||||||
|
rb_bh_fail("bh == NULL when it shouldn't be");
|
||||||
|
}
|
||||||
|
rb_dlinkAdd(bh, &bh->hlist, heap_lists);
|
||||||
|
return (bh);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************ */
|
||||||
|
/* FUNCTION DOCUMENTATION: */
|
||||||
|
/* rb_bh_alloc */
|
||||||
|
/* Description: */
|
||||||
|
/* Returns a pointer to a struct within our rb_bh that's free for */
|
||||||
|
/* the taking. */
|
||||||
|
/* Parameters: */
|
||||||
|
/* bh (IN): Pointer to the Blockheap. */
|
||||||
|
/* Returns: */
|
||||||
|
/* Pointer to a structure (void *), or NULL if unsuccessful. */
|
||||||
|
/* ************************************************************************ */
|
||||||
|
|
||||||
|
void *
|
||||||
|
rb_bh_alloc(rb_bh * bh)
|
||||||
|
{
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
rb_dlink_node *new_node;
|
||||||
|
rb_heap_memblock *memblock;
|
||||||
|
#endif
|
||||||
|
lrb_assert(bh != NULL);
|
||||||
|
if(unlikely(bh == NULL))
|
||||||
|
{
|
||||||
|
rb_bh_fail("Cannot allocate if bh == NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NOBALLOC
|
||||||
|
return(rb_malloc(bh->elemSize));
|
||||||
|
#else
|
||||||
|
if(bh->free_list.head == NULL)
|
||||||
|
{
|
||||||
|
/* Allocate new block and assign */
|
||||||
|
/* newblock returns 1 if unsuccessful, 0 if not */
|
||||||
|
|
||||||
|
if(unlikely(newblock(bh)))
|
||||||
|
{
|
||||||
|
rb_lib_log("newblock() failed");
|
||||||
|
rb_outofmemory(); /* Well that didn't work either...bail */
|
||||||
|
}
|
||||||
|
if(bh->free_list.head == NULL)
|
||||||
|
{
|
||||||
|
rb_lib_log("out of memory after newblock()...");
|
||||||
|
rb_outofmemory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new_node = bh->free_list.head;
|
||||||
|
memblock = new_node->data;
|
||||||
|
rb_dlinkDelete(new_node, &bh->free_list);
|
||||||
|
memblock->block->free_count--;
|
||||||
|
memset((void *)memblock->ndata.data, 0, bh->elemSize);
|
||||||
|
return((void *)memblock->ndata.data);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ************************************************************************ */
|
||||||
|
/* FUNCTION DOCUMENTATION: */
|
||||||
|
/* rb_bh_free */
|
||||||
|
/* Description: */
|
||||||
|
/* Returns an element to the free pool, does not free() */
|
||||||
|
/* Parameters: */
|
||||||
|
/* bh (IN): Pointer to rb_bh containing element */
|
||||||
|
/* ptr (in): Pointer to element to be "freed" */
|
||||||
|
/* Returns: */
|
||||||
|
/* 0 if successful, 1 if element not contained within rb_bh. */
|
||||||
|
/* ************************************************************************ */
|
||||||
|
int
|
||||||
|
rb_bh_free(rb_bh * bh, void *ptr)
|
||||||
|
{
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
rb_heap_memblock *memblock;
|
||||||
|
#endif
|
||||||
|
lrb_assert(bh != NULL);
|
||||||
|
lrb_assert(ptr != NULL);
|
||||||
|
|
||||||
|
if(unlikely(bh == NULL))
|
||||||
|
{
|
||||||
|
rb_lib_log("balloc.c:rb_bhFree() bh == NULL");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(unlikely(ptr == NULL))
|
||||||
|
{
|
||||||
|
rb_lib_log("balloc.rb_bhFree() ptr == NULL");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NOBALLOC
|
||||||
|
rb_free(ptr);
|
||||||
|
#else
|
||||||
|
memblock = (rb_heap_memblock *) ((uintptr_t)ptr - sizeof(rb_heap_block *));
|
||||||
|
/* XXX */
|
||||||
|
if(unlikely(!((uintptr_t)ptr >= (uintptr_t)memblock->block->elems && (uintptr_t)ptr < (uintptr_t)memblock->block->elems + (uintptr_t)memblock->block->alloc_size)))
|
||||||
|
{
|
||||||
|
rb_bh_fail("rb_bh_free() bogus pointer");
|
||||||
|
}
|
||||||
|
memblock->block->free_count++;
|
||||||
|
rb_dlinkAdd(memblock, &memblock->ndata.node, &bh->free_list);
|
||||||
|
#endif /* !NOBALLOC */
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ************************************************************************ */
|
||||||
|
/* FUNCTION DOCUMENTATION: */
|
||||||
|
/* rb_bhDestroy */
|
||||||
|
/* Description: */
|
||||||
|
/* Completely free()s a rb_bh. Use for cleanup. */
|
||||||
|
/* Parameters: */
|
||||||
|
/* bh (IN): Pointer to the rb_bh to be destroyed. */
|
||||||
|
/* Returns: */
|
||||||
|
/* 0 if successful, 1 if bh == NULL */
|
||||||
|
/* ************************************************************************ */
|
||||||
|
int
|
||||||
|
rb_bh_destroy(rb_bh * bh)
|
||||||
|
{
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
rb_dlink_node *ptr, *next;
|
||||||
|
rb_heap_block *b;
|
||||||
|
#endif
|
||||||
|
if(bh == NULL)
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
RB_DLINK_FOREACH_SAFE(ptr, next, bh->block_list.head)
|
||||||
|
{
|
||||||
|
b = ptr->data;
|
||||||
|
free_block(b->elems, b->alloc_size);
|
||||||
|
rb_free(b);
|
||||||
|
}
|
||||||
|
#endif /* !NOBALLOC */
|
||||||
|
|
||||||
|
rb_dlinkDelete(&bh->hlist, heap_lists);
|
||||||
|
rb_free(bh->desc);
|
||||||
|
rb_free(bh);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_bh_usage(rb_bh * bh, size_t * bused, size_t * bfree, size_t * bmemusage, const char **desc)
|
||||||
|
{
|
||||||
|
size_t used, freem, memusage;
|
||||||
|
|
||||||
|
if(bh == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
freem = rb_dlink_list_length(&bh->free_list);
|
||||||
|
used = (rb_dlink_list_length(&bh->block_list) * bh->elemsPerBlock) - freem;
|
||||||
|
memusage = used * (bh->elemSize + sizeof(void *));
|
||||||
|
if(bused != NULL)
|
||||||
|
*bused = used;
|
||||||
|
if(bfree != NULL)
|
||||||
|
*bfree = freem;
|
||||||
|
if(bmemusage != NULL)
|
||||||
|
*bmemusage = memusage;
|
||||||
|
if(desc != NULL)
|
||||||
|
*desc = bh->desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rb_bh_usage_all(rb_bh_usage_cb *cb, void *data)
|
||||||
|
{
|
||||||
|
rb_dlink_node *ptr;
|
||||||
|
rb_bh *bh;
|
||||||
|
size_t used, freem, memusage, heapalloc;
|
||||||
|
static const char *unnamed = "(unnamed_heap)";
|
||||||
|
const char *desc = unnamed;
|
||||||
|
|
||||||
|
if(cb == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RB_DLINK_FOREACH(ptr, heap_lists->head)
|
||||||
|
{
|
||||||
|
bh = (rb_bh *)ptr->data;
|
||||||
|
freem = rb_dlink_list_length(&bh->free_list);
|
||||||
|
used = (rb_dlink_list_length(&bh->block_list) * bh->elemsPerBlock) - freem;
|
||||||
|
memusage = used * (bh->elemSize + sizeof(void *));
|
||||||
|
heapalloc = (freem + used) * (bh->elemSize + sizeof(void *));
|
||||||
|
if(bh->desc != NULL)
|
||||||
|
desc = bh->desc;
|
||||||
|
cb(used, freem, memusage, heapalloc, desc, data);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_bh_total_usage(size_t *total_alloc, size_t *total_used)
|
||||||
|
{
|
||||||
|
rb_dlink_node *ptr;
|
||||||
|
size_t total_memory = 0, used_memory = 0, used, freem;
|
||||||
|
rb_bh *bh;
|
||||||
|
|
||||||
|
RB_DLINK_FOREACH(ptr, heap_lists->head)
|
||||||
|
{
|
||||||
|
bh = (rb_bh *)ptr->data;
|
||||||
|
freem = rb_dlink_list_length(&bh->free_list);
|
||||||
|
used = (rb_dlink_list_length(&bh->block_list) * bh->elemsPerBlock) - freem;
|
||||||
|
used_memory += used * (bh->elemSize + sizeof(void *));
|
||||||
|
total_memory += (freem + used) * (bh->elemSize + sizeof(void *));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(total_alloc != NULL)
|
||||||
|
*total_alloc = total_memory;
|
||||||
|
if(total_used != NULL)
|
||||||
|
*total_used = used_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
int
|
||||||
|
rb_bh_gc(rb_bh * bh)
|
||||||
|
{
|
||||||
|
rb_heap_block *b;
|
||||||
|
rb_dlink_node *ptr, *next;
|
||||||
|
unsigned long i;
|
||||||
|
uintptr_t offset;
|
||||||
|
|
||||||
|
if(bh == NULL)
|
||||||
|
{
|
||||||
|
/* somebody is smoking some craq..(probably lee, but don't tell him that) */
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((rb_dlink_list_length(&bh->free_list) < bh->elemsPerBlock) || rb_dlink_list_length(&bh->block_list) == 1)
|
||||||
|
{
|
||||||
|
/* There couldn't possibly be an entire free block. Return. */
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
RB_DLINK_FOREACH_SAFE(ptr, next, bh->block_list.head)
|
||||||
|
{
|
||||||
|
b = ptr->data;
|
||||||
|
if(rb_dlink_list_length(&bh->block_list) == 1)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if(b->free_count == bh->elemsPerBlock)
|
||||||
|
{
|
||||||
|
/* i'm seriously going to hell for this.. */
|
||||||
|
|
||||||
|
offset = (uintptr_t)b->elems;
|
||||||
|
for (i = 0; i < bh->elemsPerBlock; i++, offset += ((uintptr_t)bh->elemSize + sizeof(rb_heap_memblock *)))
|
||||||
|
{
|
||||||
|
rb_heap_memblock *memblock = (rb_heap_memblock *)offset;
|
||||||
|
rb_dlinkDelete(&memblock->ndata.node, &bh->free_list);
|
||||||
|
}
|
||||||
|
rb_dlinkDelete(&b->node, &bh->block_list);
|
||||||
|
free_block(b->elems, b->alloc_size);
|
||||||
|
rb_free(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
#endif /* !NOBALLOC */
|
2107
libratbox/src/commio.c
Normal file
2107
libratbox/src/commio.c
Normal file
File diff suppressed because it is too large
Load diff
1443
libratbox/src/crypt.c
Normal file
1443
libratbox/src/crypt.c
Normal file
File diff suppressed because it is too large
Load diff
304
libratbox/src/devpoll.c
Normal file
304
libratbox/src/devpoll.c
Normal file
|
@ -0,0 +1,304 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* s_bsd_devpoll.c: /dev/poll compatible network routines.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: devpoll.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <commio-int.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_DEVPOLL) && (HAVE_DEVPOLL_H)
|
||||||
|
#include <sys/devpoll.h>
|
||||||
|
|
||||||
|
|
||||||
|
static void devpoll_update_events(int, short, PF *);
|
||||||
|
static int dpfd;
|
||||||
|
static int maxfd;
|
||||||
|
static short *fdmask;
|
||||||
|
static void devpoll_update_events(int, short, PF *);
|
||||||
|
static void devpoll_write_update(int, int);
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_devpoll(rb_fde_t *F)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write an update to the devpoll filter.
|
||||||
|
* See, we end up having to do a seperate (?) remove before we do an
|
||||||
|
* add of a new polltype, so we have to have this function seperate from
|
||||||
|
* the others.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
devpoll_write_update(int fd, int events)
|
||||||
|
{
|
||||||
|
struct pollfd pollfds[1]; /* Just to be careful */
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
/* Build the pollfd entry */
|
||||||
|
pollfds[0].revents = 0;
|
||||||
|
pollfds[0].fd = fd;
|
||||||
|
pollfds[0].events = events;
|
||||||
|
|
||||||
|
/* Write the thing to our poll fd */
|
||||||
|
retval = write(dpfd, &pollfds[0], sizeof(struct pollfd));
|
||||||
|
if(retval != sizeof(struct pollfd))
|
||||||
|
rb_lib_log("devpoll_write_update: dpfd write failed %d: %s", errno, strerror(errno));
|
||||||
|
/* Done! */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
devpoll_update_events(int fd, short filter, PF * handler)
|
||||||
|
{
|
||||||
|
int update_required = 0;
|
||||||
|
int cur_mask = fdmask[fd];
|
||||||
|
PF *cur_handler;
|
||||||
|
|
||||||
|
fdmask[fd] = 0;
|
||||||
|
switch (filter)
|
||||||
|
{
|
||||||
|
case RB_SELECT_READ:
|
||||||
|
cur_handler = F->read_handler;
|
||||||
|
if(handler)
|
||||||
|
fdmask[fd] |= POLLRDNORM;
|
||||||
|
else
|
||||||
|
fdmask[fd] &= ~POLLRDNORM;
|
||||||
|
if(F->write_handler)
|
||||||
|
fdmask[fd] |= POLLWRNORM;
|
||||||
|
break;
|
||||||
|
case RB_SELECT_WRITE:
|
||||||
|
cur_handler = F->write_handler;
|
||||||
|
if(handler)
|
||||||
|
fdmask[fd] |= POLLWRNORM;
|
||||||
|
else
|
||||||
|
fdmask[fd] &= ~POLLWRNORM;
|
||||||
|
if(F->read_handler)
|
||||||
|
fdmask[fd] |= POLLRDNORM;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cur_handler == NULL && handler != NULL)
|
||||||
|
update_required++;
|
||||||
|
else if(cur_handler != NULL && handler == NULL)
|
||||||
|
update_required++;
|
||||||
|
if(cur_mask != fdmask[fd])
|
||||||
|
update_required++;
|
||||||
|
if(update_required)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Ok, we can call devpoll_write_update() here now to re-build the
|
||||||
|
* fd struct. If we end up with nothing on this fd, it won't write
|
||||||
|
* anything.
|
||||||
|
*/
|
||||||
|
if(fdmask[fd])
|
||||||
|
{
|
||||||
|
devpoll_write_update(fd, POLLREMOVE);
|
||||||
|
devpoll_write_update(fd, fdmask[fd]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
devpoll_write_update(fd, POLLREMOVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
|
||||||
|
/* Public functions */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_init_netio
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to initialise
|
||||||
|
* the network loop code.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rb_init_netio_devpoll(void)
|
||||||
|
{
|
||||||
|
dpfd = open("/dev/poll", O_RDWR);
|
||||||
|
if(dpfd < 0)
|
||||||
|
{
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
maxfd = getdtablesize() - 2; /* This makes more sense than HARD_FDLIMIT */
|
||||||
|
fdmask = rb_malloc(sizeof(fdmask) * maxfd + 1);
|
||||||
|
rb_open(dpfd, RB_FD_UNKNOWN, "/dev/poll file descriptor");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_setselect
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to register
|
||||||
|
* and deregister interest in a pending IO state for a given FD.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_setselect_devpoll(rb_fde_t *F, unsigned int type, PF * handler,
|
||||||
|
void *client_data)
|
||||||
|
{
|
||||||
|
lrb_assert(IsFDOpen(F));
|
||||||
|
|
||||||
|
if(type & RB_SELECT_READ)
|
||||||
|
{
|
||||||
|
devpoll_update_events(fd, RB_SELECT_READ, handler);
|
||||||
|
F->read_handler = handler;
|
||||||
|
F->read_data = client_data;
|
||||||
|
}
|
||||||
|
if(type & RB_SELECT_WRITE)
|
||||||
|
{
|
||||||
|
devpoll_update_events(fd, RB_SELECT_WRITE, handler);
|
||||||
|
F->write_handler = handler;
|
||||||
|
F->write_data = client_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check all connections for new connections and input data that is to be
|
||||||
|
* processed. Also check for connections with data queued and whether we can
|
||||||
|
* write it out.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_select
|
||||||
|
*
|
||||||
|
* Called to do the new-style IO, courtesy of squid (like most of this
|
||||||
|
* new IO code). This routine handles the stuff we've hidden in
|
||||||
|
* rb_setselect and fd_table[] and calls callbacks for IO ready
|
||||||
|
* events.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_devpoll(long delay)
|
||||||
|
{
|
||||||
|
int num, i;
|
||||||
|
struct pollfd pollfds[maxfd];
|
||||||
|
struct dvpoll dopoll;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
dopoll.dp_timeout = delay;
|
||||||
|
dopoll.dp_nfds = maxfd;
|
||||||
|
dopoll.dp_fds = &pollfds[0];
|
||||||
|
num = ioctl(dpfd, DP_POLL, &dopoll);
|
||||||
|
if(num >= 0)
|
||||||
|
break;
|
||||||
|
if(rb_ignore_errno(errno))
|
||||||
|
break;
|
||||||
|
rb_set_time();
|
||||||
|
return RB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_set_time();
|
||||||
|
if(num == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
int fd = dopoll.dp_fds[i].fd;
|
||||||
|
PF *hdl = NULL;
|
||||||
|
rb_fde_t *F = rb_find_fd(fd);
|
||||||
|
if((dopoll.dp_fds[i].
|
||||||
|
revents & (POLLRDNORM | POLLIN | POLLHUP |
|
||||||
|
POLLERR))
|
||||||
|
&& (dopoll.dp_fds[i].events & (POLLRDNORM | POLLIN)))
|
||||||
|
{
|
||||||
|
if((hdl = F->read_handler) != NULL)
|
||||||
|
{
|
||||||
|
F->read_handler = NULL;
|
||||||
|
hdl(F, F->read_data);
|
||||||
|
/*
|
||||||
|
* this call used to be with a NULL pointer, BUT
|
||||||
|
* in the devpoll case we only want to update the
|
||||||
|
* poll set *if* the handler changes state (active ->
|
||||||
|
* NULL or vice versa.)
|
||||||
|
*/
|
||||||
|
devpoll_update_events(fd,
|
||||||
|
RB_SELECT_READ, F->read_handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!IsFDOpen(F))
|
||||||
|
continue; /* Read handler closed us..go on to do something more useful */
|
||||||
|
if((dopoll.dp_fds[i].
|
||||||
|
revents & (POLLWRNORM | POLLOUT | POLLHUP |
|
||||||
|
POLLERR))
|
||||||
|
&& (dopoll.dp_fds[i].events & (POLLWRNORM | POLLOUT)))
|
||||||
|
{
|
||||||
|
if((hdl = F->write_handler) != NULL)
|
||||||
|
{
|
||||||
|
F->write_handler = NULL;
|
||||||
|
hdl(F, F->write_data);
|
||||||
|
/* See above similar code in the read case */
|
||||||
|
devpoll_update_events(fd,
|
||||||
|
RB_SELECT_WRITE, F->write_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RB_OK;
|
||||||
|
}
|
||||||
|
while (0);
|
||||||
|
/* XXX Get here, we broke! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* /dev/poll not supported */
|
||||||
|
int
|
||||||
|
rb_init_netio_devpoll(void)
|
||||||
|
{
|
||||||
|
return ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_setselect_devpoll(rb_fde_t *F, unsigned int type, PF * handler, void *client_data)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_devpoll(long delay)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_devpoll(rb_fde_t *F)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
464
libratbox/src/epoll.c
Normal file
464
libratbox/src/epoll.c
Normal file
|
@ -0,0 +1,464 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* epoll.c: Linux epoll compatible network routines.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
* Copyright (C) 2002 Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: epoll.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
#define _GNU_SOURCE 1
|
||||||
|
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <commio-int.h>
|
||||||
|
#include <event-int.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_EPOLL_CTL) && (HAVE_SYS_EPOLL_H)
|
||||||
|
#define USING_EPOLL
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_SIGNALFD) && (HAVE_SYS_SIGNALFD_H) && (USE_TIMER_CREATE) && (HAVE_SYS_UIO_H)
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/signalfd.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#define EPOLL_SCHED_EVENT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RTSIGNAL SIGRTMIN
|
||||||
|
struct epoll_info
|
||||||
|
{
|
||||||
|
int ep;
|
||||||
|
struct epoll_event *pfd;
|
||||||
|
int pfd_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct epoll_info *ep_info;
|
||||||
|
static int can_do_event;
|
||||||
|
|
||||||
|
//static void setup_signalfd(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_init_netio
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to initialise
|
||||||
|
* the network loop code.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rb_init_netio_epoll(void)
|
||||||
|
{
|
||||||
|
can_do_event = 0; /* shut up gcc */
|
||||||
|
ep_info = rb_malloc(sizeof(struct epoll_info));
|
||||||
|
ep_info->pfd_size = getdtablesize();
|
||||||
|
ep_info->ep = epoll_create(ep_info->pfd_size);
|
||||||
|
if(ep_info->ep < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
rb_open(ep_info->ep, RB_FD_UNKNOWN, "epoll file descriptor");
|
||||||
|
ep_info->pfd = rb_malloc(sizeof(struct epoll_event) * ep_info->pfd_size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_epoll(rb_fde_t * F)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_setselect
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to register
|
||||||
|
* and deregister interest in a pending IO state for a given FD.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_setselect_epoll(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
|
||||||
|
{
|
||||||
|
struct epoll_event ep_event;
|
||||||
|
int old_flags = F->pflags;
|
||||||
|
int op = -1;
|
||||||
|
|
||||||
|
lrb_assert(IsFDOpen(F));
|
||||||
|
|
||||||
|
/* Update the list, even though we're not using it .. */
|
||||||
|
if(type & RB_SELECT_READ)
|
||||||
|
{
|
||||||
|
if(handler != NULL)
|
||||||
|
F->pflags |= EPOLLIN;
|
||||||
|
else
|
||||||
|
F->pflags &= ~EPOLLIN;
|
||||||
|
F->read_handler = handler;
|
||||||
|
F->read_data = client_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type & RB_SELECT_WRITE)
|
||||||
|
{
|
||||||
|
if(handler != NULL)
|
||||||
|
F->pflags |= EPOLLOUT;
|
||||||
|
else
|
||||||
|
F->pflags &= ~EPOLLOUT;
|
||||||
|
F->write_handler = handler;
|
||||||
|
F->write_data = client_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(old_flags == 0 && F->pflags == 0)
|
||||||
|
return;
|
||||||
|
else if(F->pflags <= 0)
|
||||||
|
op = EPOLL_CTL_DEL;
|
||||||
|
else if(old_flags == 0 && F->pflags > 0)
|
||||||
|
op = EPOLL_CTL_ADD;
|
||||||
|
else if(F->pflags != old_flags)
|
||||||
|
op = EPOLL_CTL_MOD;
|
||||||
|
|
||||||
|
if(op == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ep_event.events = F->pflags;
|
||||||
|
ep_event.data.ptr = F;
|
||||||
|
|
||||||
|
if(op == EPOLL_CTL_ADD || op == EPOLL_CTL_MOD)
|
||||||
|
ep_event.events |= EPOLLET;
|
||||||
|
|
||||||
|
if(epoll_ctl(ep_info->ep, op, F->fd, &ep_event) != 0)
|
||||||
|
{
|
||||||
|
rb_lib_log("rb_setselect_epoll(): epoll_ctl failed: %s", strerror(errno));
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_select
|
||||||
|
*
|
||||||
|
* Called to do the new-style IO, courtesy of squid (like most of this
|
||||||
|
* new IO code). This routine handles the stuff we've hidden in
|
||||||
|
* rb_setselect and fd_table[] and calls callbacks for IO ready
|
||||||
|
* events.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_epoll(long delay)
|
||||||
|
{
|
||||||
|
int num, i, flags, old_flags, op;
|
||||||
|
struct epoll_event ep_event;
|
||||||
|
int o_errno;
|
||||||
|
void *data;
|
||||||
|
|
||||||
|
num = epoll_wait(ep_info->ep, ep_info->pfd, ep_info->pfd_size, delay);
|
||||||
|
|
||||||
|
/* save errno as rb_set_time() will likely clobber it */
|
||||||
|
o_errno = errno;
|
||||||
|
rb_set_time();
|
||||||
|
errno = o_errno;
|
||||||
|
|
||||||
|
if(num < 0 && !rb_ignore_errno(o_errno))
|
||||||
|
return RB_ERROR;
|
||||||
|
|
||||||
|
if(num <= 0)
|
||||||
|
return RB_OK;
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
PF *hdl;
|
||||||
|
rb_fde_t *F = ep_info->pfd[i].data.ptr;
|
||||||
|
old_flags = F->pflags;
|
||||||
|
if(ep_info->pfd[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR))
|
||||||
|
{
|
||||||
|
hdl = F->read_handler;
|
||||||
|
data = F->read_data;
|
||||||
|
F->read_handler = NULL;
|
||||||
|
F->read_data = NULL;
|
||||||
|
if(hdl)
|
||||||
|
{
|
||||||
|
hdl(F, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!IsFDOpen(F))
|
||||||
|
continue;
|
||||||
|
if(ep_info->pfd[i].events & (EPOLLOUT | EPOLLHUP | EPOLLERR))
|
||||||
|
{
|
||||||
|
hdl = F->write_handler;
|
||||||
|
data = F->write_data;
|
||||||
|
F->write_handler = NULL;
|
||||||
|
F->write_data = NULL;
|
||||||
|
|
||||||
|
if(hdl)
|
||||||
|
{
|
||||||
|
hdl(F, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!IsFDOpen(F))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
|
if(F->read_handler != NULL)
|
||||||
|
flags |= EPOLLIN;
|
||||||
|
if(F->write_handler != NULL)
|
||||||
|
flags |= EPOLLOUT;
|
||||||
|
|
||||||
|
if(old_flags != flags)
|
||||||
|
{
|
||||||
|
if(flags == 0)
|
||||||
|
op = EPOLL_CTL_DEL;
|
||||||
|
else
|
||||||
|
op = EPOLL_CTL_MOD;
|
||||||
|
F->pflags = ep_event.events = flags;
|
||||||
|
ep_event.data.ptr = F;
|
||||||
|
if(op == EPOLL_CTL_MOD || op == EPOLL_CTL_ADD)
|
||||||
|
ep_event.events |= EPOLLET;
|
||||||
|
|
||||||
|
if(epoll_ctl(ep_info->ep, op, F->fd, &ep_event) != 0)
|
||||||
|
{
|
||||||
|
rb_lib_log("rb_select_epoll(): epoll_ctl failed: %s",
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return RB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EPOLL_SCHED_EVENT
|
||||||
|
int
|
||||||
|
rb_epoll_supports_event(void)
|
||||||
|
{
|
||||||
|
/* try to detect at runtime if everything we need actually works */
|
||||||
|
timer_t timer;
|
||||||
|
struct sigevent ev;
|
||||||
|
int fd;
|
||||||
|
sigset_t set;
|
||||||
|
|
||||||
|
if(can_do_event == 1)
|
||||||
|
return 1;
|
||||||
|
if(can_do_event == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ev.sigev_signo = SIGVTALRM;
|
||||||
|
ev.sigev_notify = SIGEV_SIGNAL;
|
||||||
|
if(timer_create(CLOCK_REALTIME, &ev, &timer) != 0)
|
||||||
|
{
|
||||||
|
can_do_event = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
timer_delete(timer);
|
||||||
|
sigemptyset(&set);
|
||||||
|
fd = signalfd(-1, &set, 0);
|
||||||
|
if(fd < 0)
|
||||||
|
{
|
||||||
|
can_do_event = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
can_do_event = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* bleh..work around a glibc header bug on 32bit systems */
|
||||||
|
struct our_signalfd_siginfo {
|
||||||
|
rb_uint32_t signo;
|
||||||
|
rb_int32_t err;
|
||||||
|
rb_int32_t code;
|
||||||
|
rb_uint32_t pid;
|
||||||
|
rb_uint32_t uid;
|
||||||
|
rb_int32_t fd;
|
||||||
|
rb_uint32_t tid;
|
||||||
|
rb_uint32_t band;
|
||||||
|
rb_uint32_t overrun;
|
||||||
|
rb_uint32_t trapno;
|
||||||
|
rb_int32_t status;
|
||||||
|
rb_int32_t svint;
|
||||||
|
rb_uint64_t svptr;
|
||||||
|
rb_uint64_t utime;
|
||||||
|
rb_uint64_t stime;
|
||||||
|
rb_uint64_t addr;
|
||||||
|
rb_uint8_t pad[48];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define SIGFDIOV_COUNT 16
|
||||||
|
static void
|
||||||
|
signalfd_handler(rb_fde_t *F, void *data)
|
||||||
|
{
|
||||||
|
static struct our_signalfd_siginfo fdsig[SIGFDIOV_COUNT];
|
||||||
|
static struct iovec iov[SIGFDIOV_COUNT];
|
||||||
|
struct ev_entry *ev;
|
||||||
|
int ret, x;
|
||||||
|
|
||||||
|
for(x = 0; x < SIGFDIOV_COUNT; x++)
|
||||||
|
{
|
||||||
|
iov[x].iov_base = &fdsig[x];
|
||||||
|
iov[x].iov_len = sizeof(struct our_signalfd_siginfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
ret = readv(rb_get_fd(F), iov, SIGFDIOV_COUNT);
|
||||||
|
if(ret == 0 || (ret < 0 && !rb_ignore_errno(errno)))
|
||||||
|
{
|
||||||
|
rb_close(F);
|
||||||
|
rb_epoll_init_event();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
rb_setselect(F, RB_SELECT_READ, signalfd_handler, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(x = 0; x < ret / (int)sizeof(struct signalfd_siginfo); x++)
|
||||||
|
{
|
||||||
|
ev = (struct ev_entry *)fdsig[x].svptr;
|
||||||
|
if(ev == NULL)
|
||||||
|
continue;
|
||||||
|
rb_run_event(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_epoll_init_event(void)
|
||||||
|
{
|
||||||
|
sigset_t ss;
|
||||||
|
rb_fde_t *F;
|
||||||
|
int sfd;
|
||||||
|
sigemptyset(&ss);
|
||||||
|
sigaddset(&ss, RTSIGNAL);
|
||||||
|
sigprocmask(SIG_BLOCK, &ss, 0);
|
||||||
|
sigemptyset(&ss);
|
||||||
|
sigaddset(&ss, RTSIGNAL);
|
||||||
|
sfd = signalfd(-1, &ss, 0);
|
||||||
|
if(sfd == -1) {
|
||||||
|
can_do_event = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
F = rb_open(sfd, RB_FD_UNKNOWN, "signalfd");
|
||||||
|
rb_set_nb(F);
|
||||||
|
signalfd_handler(F, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_epoll_sched_event(struct ev_entry *event, int when)
|
||||||
|
{
|
||||||
|
timer_t *id;
|
||||||
|
struct sigevent ev;
|
||||||
|
struct itimerspec ts;
|
||||||
|
|
||||||
|
memset(&ev, 0, sizeof(&ev));
|
||||||
|
event->comm_ptr = rb_malloc(sizeof(timer_t));
|
||||||
|
id = event->comm_ptr;
|
||||||
|
ev.sigev_notify = SIGEV_SIGNAL;
|
||||||
|
ev.sigev_signo = RTSIGNAL;
|
||||||
|
ev.sigev_value.sival_ptr = event;
|
||||||
|
|
||||||
|
if (timer_create(CLOCK_REALTIME, &ev, id) < 0)
|
||||||
|
{
|
||||||
|
rb_lib_log("timer_create: %s\n", strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(&ts, 0, sizeof(ts));
|
||||||
|
ts.it_value.tv_sec = when;
|
||||||
|
ts.it_value.tv_nsec = 0;
|
||||||
|
if(event->frequency != 0)
|
||||||
|
ts.it_interval = ts.it_value;
|
||||||
|
|
||||||
|
if(timer_settime(*id, 0, &ts, NULL) < 0)
|
||||||
|
{
|
||||||
|
rb_lib_log("timer_settime: %s\n", strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_epoll_unsched_event(struct ev_entry *event)
|
||||||
|
{
|
||||||
|
timer_delete(*((timer_t *)event->comm_ptr));
|
||||||
|
rb_free(event->comm_ptr);
|
||||||
|
event->comm_ptr = NULL;
|
||||||
|
}
|
||||||
|
#endif /* EPOLL_SCHED_EVENT */
|
||||||
|
|
||||||
|
#else /* epoll not supported here */
|
||||||
|
int
|
||||||
|
rb_init_netio_epoll(void)
|
||||||
|
{
|
||||||
|
return ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_setselect_epoll(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_epoll(long delay)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_epoll(rb_fde_t * F)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(USING_EPOLL) || !defined(EPOLL_SCHED_EVENT)
|
||||||
|
void rb_epoll_init_event(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_epoll_sched_event(struct ev_entry *event, int when)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_epoll_unsched_event(struct ev_entry *event)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_epoll_supports_event(void)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* !USING_EPOLL || !EPOLL_SCHED_EVENT */
|
352
libratbox/src/event.c
Normal file
352
libratbox/src/event.c
Normal file
|
@ -0,0 +1,352 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* event.c: Event functions.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998-2000 Regents of the University of California
|
||||||
|
* Copyright (C) 2001-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* Code borrowed from the squid web cache by Adrian Chadd.
|
||||||
|
* Original header:
|
||||||
|
*
|
||||||
|
* DEBUG: section 41 Event Processing
|
||||||
|
* AUTHOR: Henrik Nordstrom
|
||||||
|
*
|
||||||
|
* SQUID Internet Object Cache http://squid.nlanr.net/Squid/
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Squid is the result of efforts by numerous individuals from the
|
||||||
|
* Internet community. Development is led by Duane Wessels of the
|
||||||
|
* National Laboratory for Applied Network Research and funded by the
|
||||||
|
* National Science Foundation. Squid is Copyrighted (C) 1998 by
|
||||||
|
* the Regents of the University of California. Please see the
|
||||||
|
* COPYRIGHT file for full details. Squid incorporates software
|
||||||
|
* developed and/or copyrighted by other sources. Please see the
|
||||||
|
* CREDITS file for full details.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: event.c 25147 2008-03-28 17:15:47Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <commio-int.h>
|
||||||
|
#include <event-int.h>
|
||||||
|
|
||||||
|
static const char *last_event_ran = NULL;
|
||||||
|
static rb_dlink_list event_list;
|
||||||
|
|
||||||
|
static time_t event_time_min = -1;
|
||||||
|
/* The list of event processes */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
struct ev_entry
|
||||||
|
{
|
||||||
|
rb_dlink_node node;
|
||||||
|
EVH *func;
|
||||||
|
void *arg;
|
||||||
|
const char *name;
|
||||||
|
time_t frequency;
|
||||||
|
time_t when;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct ev_entry *
|
||||||
|
* rb_event_find(EVH *func, void *arg)
|
||||||
|
*
|
||||||
|
* Input: Event function and the argument passed to it
|
||||||
|
* Output: Index to the slow in the event_table
|
||||||
|
* Side Effects: None
|
||||||
|
*/
|
||||||
|
static struct ev_entry *
|
||||||
|
rb_event_find(EVH * func, void *arg)
|
||||||
|
{
|
||||||
|
rb_dlink_node *ptr;
|
||||||
|
struct ev_entry *ev;
|
||||||
|
RB_DLINK_FOREACH(ptr, event_list.head)
|
||||||
|
{
|
||||||
|
ev = ptr->data;
|
||||||
|
if((ev->func == func) && (ev->arg == arg))
|
||||||
|
return ev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct ev_entry *
|
||||||
|
* rb_event_add(const char *name, EVH *func, void *arg, time_t when)
|
||||||
|
*
|
||||||
|
* Input: Name of event, function to call, arguments to pass, and frequency
|
||||||
|
* of the event.
|
||||||
|
* Output: None
|
||||||
|
* Side Effects: Adds the event to the event list.
|
||||||
|
*/
|
||||||
|
struct ev_entry *
|
||||||
|
rb_event_add(const char *name, EVH * func, void *arg, time_t when)
|
||||||
|
{
|
||||||
|
struct ev_entry *ev;
|
||||||
|
ev = rb_malloc(sizeof(struct ev_entry));
|
||||||
|
ev->func = func;
|
||||||
|
ev->name = name;
|
||||||
|
ev->arg = arg;
|
||||||
|
ev->when = rb_current_time() + when;
|
||||||
|
ev->frequency = when;
|
||||||
|
|
||||||
|
if((ev->when < event_time_min) || (event_time_min == -1))
|
||||||
|
{
|
||||||
|
event_time_min = ev->when;
|
||||||
|
}
|
||||||
|
rb_dlinkAdd(ev, &ev->node, &event_list);
|
||||||
|
rb_io_sched_event(ev, when);
|
||||||
|
return ev;
|
||||||
|
}
|
||||||
|
struct ev_entry *
|
||||||
|
rb_event_addonce(const char *name, EVH * func, void *arg, time_t when)
|
||||||
|
{
|
||||||
|
struct ev_entry *ev;
|
||||||
|
ev = rb_malloc(sizeof(struct ev_entry));
|
||||||
|
ev->func = func;
|
||||||
|
ev->name = name;
|
||||||
|
ev->arg = arg;
|
||||||
|
ev->when = rb_current_time() + when;
|
||||||
|
ev->frequency = 0;
|
||||||
|
|
||||||
|
if((ev->when < event_time_min) || (event_time_min == -1))
|
||||||
|
event_time_min = ev->when;
|
||||||
|
|
||||||
|
rb_dlinkAdd(ev, &ev->node, &event_list);
|
||||||
|
rb_io_sched_event(ev, when);
|
||||||
|
return ev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void rb_event_delete(struct ev_entry *ev)
|
||||||
|
*
|
||||||
|
* Input: pointer to ev_entry for the event
|
||||||
|
* Output: None
|
||||||
|
* Side Effects: Removes the event from the event list
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_event_delete(struct ev_entry *ev)
|
||||||
|
{
|
||||||
|
if(ev == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rb_dlinkDelete(&ev->node, &event_list);
|
||||||
|
rb_io_unsched_event(ev);
|
||||||
|
rb_free(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void rb_event_find_delete(EVH *func, void *arg)
|
||||||
|
*
|
||||||
|
* Input: pointer to func and data
|
||||||
|
* Output: None
|
||||||
|
* Side Effects: Removes the event from the event list
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_event_find_delete(EVH *func, void *arg)
|
||||||
|
{
|
||||||
|
rb_event_delete(rb_event_find(func, arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct ev_entry *
|
||||||
|
* rb_event_addish(const char *name, EVH *func, void *arg, time_t delta_isa)
|
||||||
|
*
|
||||||
|
* Input: Name of event, function to call, arguments to pass, and frequency
|
||||||
|
* of the event.
|
||||||
|
* Output: None
|
||||||
|
* Side Effects: Adds the event to the event list within +- 1/3 of the
|
||||||
|
* specified frequency.
|
||||||
|
*/
|
||||||
|
struct ev_entry *
|
||||||
|
rb_event_addish(const char *name, EVH * func, void *arg, time_t delta_ish)
|
||||||
|
{
|
||||||
|
if(delta_ish >= 3.0)
|
||||||
|
{
|
||||||
|
const time_t two_third = (2 * delta_ish) / 3;
|
||||||
|
delta_ish = two_third + ((rand() % 1000) * two_third) / 1000;
|
||||||
|
/*
|
||||||
|
* XXX I hate the above magic, I don't even know if its right.
|
||||||
|
* Grr. -- adrian
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
return rb_event_add(name, func, arg, delta_ish);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_run_event(struct ev_entry *ev)
|
||||||
|
{
|
||||||
|
last_event_ran = ev->name;
|
||||||
|
ev->func(ev->arg);
|
||||||
|
if(!ev->frequency)
|
||||||
|
{
|
||||||
|
rb_io_unsched_event(ev);
|
||||||
|
rb_dlinkDelete(&ev->node, &event_list);
|
||||||
|
rb_free(ev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ev->when = rb_current_time() + ev->frequency;
|
||||||
|
if((ev->when < event_time_min) || (event_time_min == -1))
|
||||||
|
event_time_min = ev->when;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void rb_event_run(void)
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
* Output: None
|
||||||
|
* Side Effects: Runs pending events in the event list
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_event_run(void)
|
||||||
|
{
|
||||||
|
rb_dlink_node *ptr, *next;
|
||||||
|
struct ev_entry *ev;
|
||||||
|
|
||||||
|
if(rb_io_supports_event())
|
||||||
|
return;
|
||||||
|
|
||||||
|
event_time_min = -1;
|
||||||
|
RB_DLINK_FOREACH_SAFE(ptr, next, event_list.head)
|
||||||
|
{
|
||||||
|
ev = ptr->data;
|
||||||
|
if(ev->when <= rb_current_time())
|
||||||
|
{
|
||||||
|
last_event_ran = ev->name;
|
||||||
|
ev->func(ev->arg);
|
||||||
|
|
||||||
|
/* event is scheduled more than once */
|
||||||
|
if(ev->frequency)
|
||||||
|
{
|
||||||
|
ev->when = rb_current_time() + ev->frequency;
|
||||||
|
if((ev->when < event_time_min) || (event_time_min == -1))
|
||||||
|
event_time_min = ev->when;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rb_dlinkDelete(&ev->node, &event_list);
|
||||||
|
rb_free(ev);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if((ev->when < event_time_min) || (event_time_min == -1))
|
||||||
|
event_time_min = ev->when;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_event_io_register_all(void)
|
||||||
|
{
|
||||||
|
rb_dlink_node *ptr;
|
||||||
|
struct ev_entry *ev;
|
||||||
|
int when;
|
||||||
|
if(!rb_io_supports_event())
|
||||||
|
return;
|
||||||
|
|
||||||
|
RB_DLINK_FOREACH(ptr, event_list.head)
|
||||||
|
{
|
||||||
|
ev = ptr->data;
|
||||||
|
when = ev->when - rb_current_time();
|
||||||
|
rb_io_sched_event(ev, when);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* void rb_event_init(void)
|
||||||
|
*
|
||||||
|
* Input: None
|
||||||
|
* Output: None
|
||||||
|
* Side Effects: Initializes the event system.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_event_init(void)
|
||||||
|
{
|
||||||
|
last_event_ran = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_dump_events(void (*func) (char *, void *), void *ptr)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
char buf[512];
|
||||||
|
rb_dlink_node *dptr;
|
||||||
|
struct ev_entry *ev;
|
||||||
|
len = sizeof(buf);
|
||||||
|
if(last_event_ran)
|
||||||
|
{
|
||||||
|
rb_snprintf(buf, len, "Last event to run: %s", last_event_ran);
|
||||||
|
func(buf, ptr);
|
||||||
|
}
|
||||||
|
rb_strlcpy(buf, "Operation Next Execution", len);
|
||||||
|
func(buf, ptr);
|
||||||
|
|
||||||
|
RB_DLINK_FOREACH(dptr, event_list.head)
|
||||||
|
{
|
||||||
|
ev = dptr->data;
|
||||||
|
rb_snprintf(buf, len, "%-28s %-4ld seconds", ev->name,
|
||||||
|
ev->when - (long) rb_current_time());
|
||||||
|
func(buf, ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void rb_set_back_events(time_t by)
|
||||||
|
* Input: Time to set back events by.
|
||||||
|
* Output: None.
|
||||||
|
* Side-effects: Sets back all events by "by" seconds.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_set_back_events(time_t by)
|
||||||
|
{
|
||||||
|
rb_dlink_node *ptr;
|
||||||
|
struct ev_entry *ev;
|
||||||
|
RB_DLINK_FOREACH(ptr, event_list.head)
|
||||||
|
{
|
||||||
|
ev = ptr->data;
|
||||||
|
if(ev->when > by)
|
||||||
|
ev->when -= by;
|
||||||
|
else
|
||||||
|
ev->when = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_event_update(struct ev_entry *ev, time_t freq)
|
||||||
|
{
|
||||||
|
if(ev == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ev->frequency = freq;
|
||||||
|
|
||||||
|
/* update when its scheduled to run if its higher
|
||||||
|
* than the new frequency
|
||||||
|
*/
|
||||||
|
if((rb_current_time() + freq) < ev->when)
|
||||||
|
ev->when = rb_current_time() + freq;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t
|
||||||
|
rb_event_next(void)
|
||||||
|
{
|
||||||
|
return event_time_min;
|
||||||
|
}
|
150
libratbox/src/export-syms.txt
Normal file
150
libratbox/src/export-syms.txt
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
rb_bh_alloc
|
||||||
|
rb_bh_create
|
||||||
|
rb_bh_destroy
|
||||||
|
rb_bh_free
|
||||||
|
rb_bh_gc
|
||||||
|
rb_bh_total_usage
|
||||||
|
rb_bh_usage
|
||||||
|
rb_bh_usage_all
|
||||||
|
rb_init_bh
|
||||||
|
rb_accept_tcp
|
||||||
|
rb_checktimeouts
|
||||||
|
rb_close
|
||||||
|
rb_connect_sockaddr
|
||||||
|
rb_connect_tcp
|
||||||
|
rb_connect_tcp_ssl
|
||||||
|
rb_dump_fd
|
||||||
|
rb_errstr
|
||||||
|
rb_fd_ssl
|
||||||
|
rb_fdlist_init
|
||||||
|
rb_get_fd
|
||||||
|
rb_get_fde
|
||||||
|
rb_get_iotype
|
||||||
|
rb_get_random
|
||||||
|
rb_get_sockerr
|
||||||
|
rb_get_ssl_strerror
|
||||||
|
rb_get_type
|
||||||
|
rb_getmaxconnect
|
||||||
|
rb_ignore_errno
|
||||||
|
rb_inet_ntop
|
||||||
|
rb_inet_ntop_sock
|
||||||
|
rb_inet_pton
|
||||||
|
rb_inet_pton_sock
|
||||||
|
rb_init_netio
|
||||||
|
rb_init_prng
|
||||||
|
rb_listen
|
||||||
|
rb_note
|
||||||
|
rb_open
|
||||||
|
rb_pipe
|
||||||
|
rb_read
|
||||||
|
rb_recv_fd_buf
|
||||||
|
rb_select
|
||||||
|
rb_send_fd_buf
|
||||||
|
rb_set_buffers
|
||||||
|
rb_set_nb
|
||||||
|
rb_set_type
|
||||||
|
rb_setselect
|
||||||
|
rb_settimeout
|
||||||
|
rb_setup_fd
|
||||||
|
rb_setup_ssl_server
|
||||||
|
rb_socket
|
||||||
|
rb_socketpair
|
||||||
|
rb_ssl_listen
|
||||||
|
rb_ssl_start_accepted
|
||||||
|
rb_ssl_start_connected
|
||||||
|
rb_write
|
||||||
|
rb_writev
|
||||||
|
rb_crypt
|
||||||
|
rb_dump_events
|
||||||
|
rb_event_add
|
||||||
|
rb_event_addish
|
||||||
|
rb_event_addonce
|
||||||
|
rb_event_delete
|
||||||
|
rb_event_find_delete
|
||||||
|
rb_event_init
|
||||||
|
rb_event_next
|
||||||
|
rb_event_run
|
||||||
|
rb_event_update
|
||||||
|
rb_run_event
|
||||||
|
rb_helper_child
|
||||||
|
rb_helper_close
|
||||||
|
rb_helper_loop
|
||||||
|
rb_helper_read
|
||||||
|
rb_helper_restart
|
||||||
|
rb_helper_run
|
||||||
|
rb_helper_start
|
||||||
|
rb_helper_write
|
||||||
|
rb_helper_write_queue
|
||||||
|
rb_count_rb_linebuf_memory
|
||||||
|
rb_linebuf_attach
|
||||||
|
rb_linebuf_donebuf
|
||||||
|
rb_linebuf_flush
|
||||||
|
rb_linebuf_get
|
||||||
|
rb_linebuf_init
|
||||||
|
rb_linebuf_newbuf
|
||||||
|
rb_linebuf_parse
|
||||||
|
rb_linebuf_put
|
||||||
|
rb_linebuf_putbuf
|
||||||
|
rb_linebuf_putmsg
|
||||||
|
make_and_lookup
|
||||||
|
make_and_lookup_ip
|
||||||
|
rb_clear_patricia
|
||||||
|
rb_destroy_patricia
|
||||||
|
rb_init_patricia
|
||||||
|
rb_match_exact_string
|
||||||
|
rb_match_ip
|
||||||
|
rb_match_ip_exact
|
||||||
|
rb_match_string
|
||||||
|
rb_new_patricia
|
||||||
|
rb_patricia_lookup
|
||||||
|
rb_patricia_process
|
||||||
|
rb_patricia_remove
|
||||||
|
rb_patricia_search_best
|
||||||
|
rb_patricia_search_best2
|
||||||
|
rb_patricia_search_exact
|
||||||
|
rb_base64_decode
|
||||||
|
rb_base64_encode
|
||||||
|
rb_ctime
|
||||||
|
rb_current_time
|
||||||
|
rb_current_time_tv
|
||||||
|
rb_date
|
||||||
|
rb_lib_die
|
||||||
|
rb_lib_init
|
||||||
|
rb_lib_log
|
||||||
|
rb_lib_loop
|
||||||
|
rb_lib_restart
|
||||||
|
rb_lib_version
|
||||||
|
rb_set_time
|
||||||
|
rb_strtok_r
|
||||||
|
rb_free_rawbuffer
|
||||||
|
rb_init_rawbuffers
|
||||||
|
rb_new_rawbuffer
|
||||||
|
rb_rawbuf_append
|
||||||
|
rb_rawbuf_flush
|
||||||
|
rb_rawbuf_get
|
||||||
|
rb_rawbuf_length
|
||||||
|
rb_free
|
||||||
|
rb_malloc
|
||||||
|
rb_outofmemory
|
||||||
|
rb_realloc
|
||||||
|
rb_strdup
|
||||||
|
rb_strndup
|
||||||
|
rb_snprintf
|
||||||
|
rb_snprintf_append
|
||||||
|
rb_sprintf
|
||||||
|
rb_sprintf_append
|
||||||
|
rb_vsnprintf
|
||||||
|
rb_vsnprintf_append
|
||||||
|
rb_vsprintf
|
||||||
|
rb_vsprintf_append
|
||||||
|
rb_free_rb_dlink_node
|
||||||
|
rb_init_rb_dlink_nodes
|
||||||
|
rb_make_rb_dlink_node
|
||||||
|
rb_string_to_array
|
||||||
|
rb_strlcat
|
||||||
|
rb_strlcpy
|
||||||
|
rb_strnlen
|
||||||
|
rb_gettimeofday
|
||||||
|
rb_sleep
|
||||||
|
rb_spawn_process
|
||||||
|
rb_supports_ssl
|
295
libratbox/src/helper.c
Normal file
295
libratbox/src/helper.c
Normal file
|
@ -0,0 +1,295 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd
|
||||||
|
* helper.c: Starts and deals with ircd helpers
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: helper.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <commio-int.h>
|
||||||
|
|
||||||
|
struct _rb_helper
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
buf_head_t sendq;
|
||||||
|
buf_head_t recvq;
|
||||||
|
rb_fde_t *ifd;
|
||||||
|
rb_fde_t *ofd;
|
||||||
|
pid_t pid;
|
||||||
|
int fork_count;
|
||||||
|
rb_helper_cb *read_cb;
|
||||||
|
rb_helper_cb *error_cb;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* setup all the stuff a new child needs */
|
||||||
|
rb_helper *
|
||||||
|
rb_helper_child(rb_helper_cb *read_cb, rb_helper_cb *error_cb, log_cb *ilog, restart_cb *irestart, die_cb *idie,
|
||||||
|
int maxcon, size_t lb_heap_size, size_t dh_size, size_t fd_heap_size)
|
||||||
|
{
|
||||||
|
rb_helper *helper;
|
||||||
|
int maxfd, x = 0;
|
||||||
|
int ifd, ofd;
|
||||||
|
char *tifd, *tofd, *tmaxfd;
|
||||||
|
|
||||||
|
tifd = getenv("IFD");
|
||||||
|
tofd = getenv("OFD");
|
||||||
|
tmaxfd = getenv("MAXFD");
|
||||||
|
|
||||||
|
if(tifd == NULL || tofd == NULL || tmaxfd == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
helper = rb_malloc(sizeof(rb_helper));
|
||||||
|
ifd = (int)strtol(tifd, NULL, 10);
|
||||||
|
ofd = (int)strtol(tofd, NULL, 10);
|
||||||
|
maxfd = (int)strtol(tmaxfd, NULL, 10);
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
for(x = 0; x < maxfd; x++)
|
||||||
|
{
|
||||||
|
if(x != ifd && x != ofd)
|
||||||
|
close(x);
|
||||||
|
}
|
||||||
|
x = open("/dev/null", O_RDWR);
|
||||||
|
if(ifd != 0 && ofd != 0)
|
||||||
|
dup2(x, 0);
|
||||||
|
if(ifd != 1 && ofd != 1)
|
||||||
|
dup2(x, 1);
|
||||||
|
if(ifd != 2 && ofd != 2)
|
||||||
|
dup2(x, 2);
|
||||||
|
if(x > 2) /* don't undo what we just did */
|
||||||
|
close(x);
|
||||||
|
#else
|
||||||
|
x = 0; /* shut gcc up */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rb_lib_init(ilog, irestart, idie, 0, maxfd, dh_size, fd_heap_size);
|
||||||
|
rb_linebuf_init(lb_heap_size);
|
||||||
|
rb_linebuf_newbuf(&helper->sendq);
|
||||||
|
rb_linebuf_newbuf(&helper->recvq);
|
||||||
|
|
||||||
|
helper->ifd = rb_open(ifd, RB_FD_PIPE, "incoming connection");
|
||||||
|
helper->ofd = rb_open(ofd, RB_FD_PIPE, "outgoing connection");
|
||||||
|
rb_set_nb(helper->ifd);
|
||||||
|
rb_set_nb(helper->ofd);
|
||||||
|
|
||||||
|
helper->read_cb = read_cb;
|
||||||
|
helper->error_cb = error_cb;
|
||||||
|
return helper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* start_fork_helper
|
||||||
|
* starts a new ircd helper
|
||||||
|
* note that this function doesn't start doing reading..thats the job of the caller
|
||||||
|
*/
|
||||||
|
|
||||||
|
rb_helper *
|
||||||
|
rb_helper_start(const char *name, const char *fullpath, rb_helper_cb *read_cb, rb_helper_cb *error_cb)
|
||||||
|
{
|
||||||
|
rb_helper *helper;
|
||||||
|
const char *parv[2];
|
||||||
|
char buf[128];
|
||||||
|
char fx[16], fy[16];
|
||||||
|
rb_fde_t *in_f[2];
|
||||||
|
rb_fde_t *out_f[2];
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
if(access(fullpath, X_OK) == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
helper = rb_malloc(sizeof(rb_helper));
|
||||||
|
|
||||||
|
rb_snprintf(buf, sizeof(buf), "%s helper - read", name);
|
||||||
|
if(rb_pipe(&in_f[0], &in_f[1], buf) < 0)
|
||||||
|
{
|
||||||
|
rb_free(helper);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rb_snprintf(buf, sizeof(buf), "%s helper - write", name);
|
||||||
|
if(rb_pipe(&out_f[0], &out_f[1], buf) < 0)
|
||||||
|
{
|
||||||
|
rb_free(helper);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_snprintf(fx, sizeof(fx), "%d", rb_get_fd(in_f[1]));
|
||||||
|
rb_snprintf(fy, sizeof(fy), "%d", rb_get_fd(out_f[0]));
|
||||||
|
|
||||||
|
rb_set_nb(in_f[0]);
|
||||||
|
rb_set_nb(in_f[1]);
|
||||||
|
rb_set_nb(out_f[0]);
|
||||||
|
rb_set_nb(out_f[1]);
|
||||||
|
|
||||||
|
setenv("IFD", fy, 1);
|
||||||
|
setenv("OFD", fx, 1);
|
||||||
|
setenv("MAXFD", "256", 1);
|
||||||
|
|
||||||
|
rb_snprintf(buf, sizeof(buf), "-ircd %s daemon", name);
|
||||||
|
parv[0] = buf;
|
||||||
|
parv[1] = NULL;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
SetHandleInformation((HANDLE)rb_get_fd(in_f[1]), HANDLE_FLAG_INHERIT, 1);
|
||||||
|
SetHandleInformation((HANDLE)rb_get_fd(out_f[0]), HANDLE_FLAG_INHERIT, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pid = rb_spawn_process(fullpath, (const char **)parv);
|
||||||
|
|
||||||
|
if(pid == -1)
|
||||||
|
{
|
||||||
|
rb_close(in_f[0]);
|
||||||
|
rb_close(in_f[1]);
|
||||||
|
rb_close(out_f[0]);
|
||||||
|
rb_close(out_f[1]);
|
||||||
|
rb_free(helper);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_close(in_f[1]);
|
||||||
|
rb_close(out_f[0]);
|
||||||
|
|
||||||
|
rb_linebuf_newbuf(&helper->sendq);
|
||||||
|
rb_linebuf_newbuf(&helper->recvq);
|
||||||
|
|
||||||
|
helper->ifd = in_f[0];
|
||||||
|
helper->ofd = out_f[1];
|
||||||
|
helper->read_cb = read_cb;
|
||||||
|
helper->error_cb = error_cb;
|
||||||
|
helper->fork_count = 0;
|
||||||
|
helper->pid = pid;
|
||||||
|
|
||||||
|
return helper;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_helper_restart(rb_helper *helper)
|
||||||
|
{
|
||||||
|
helper->error_cb(helper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
rb_helper_write_sendq(rb_fde_t *F, void *helper_ptr)
|
||||||
|
{
|
||||||
|
rb_helper *helper = helper_ptr;
|
||||||
|
int retlen;
|
||||||
|
|
||||||
|
if(rb_linebuf_len(&helper->sendq) > 0)
|
||||||
|
{
|
||||||
|
while((retlen = rb_linebuf_flush(F, &helper->sendq)) > 0)
|
||||||
|
;;
|
||||||
|
if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno))) {
|
||||||
|
rb_helper_restart(helper);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rb_linebuf_len(&helper->sendq) > 0)
|
||||||
|
rb_setselect(helper->ofd, RB_SELECT_WRITE, rb_helper_write_sendq, helper);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_helper_write_queue(rb_helper *helper, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
rb_linebuf_putmsg(&helper->sendq, format, &ap, NULL);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_helper_write_flush(rb_helper *helper)
|
||||||
|
{
|
||||||
|
rb_helper_write_sendq(helper->ofd, helper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_helper_write(rb_helper *helper, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
rb_linebuf_putmsg(&helper->sendq, format, &ap, NULL);
|
||||||
|
va_end(ap);
|
||||||
|
rb_helper_write_flush(helper);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rb_helper_read_cb(rb_fde_t *F, void *data)
|
||||||
|
{
|
||||||
|
rb_helper *helper = (rb_helper *)data;
|
||||||
|
static char buf[32768];
|
||||||
|
int length;
|
||||||
|
if(helper == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while((length = rb_read(helper->ifd, buf, sizeof(buf))) > 0)
|
||||||
|
{
|
||||||
|
rb_linebuf_parse(&helper->recvq, buf, length, 0);
|
||||||
|
helper->read_cb(helper);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(length == 0 || (length < 0 && !rb_ignore_errno(errno)))
|
||||||
|
{
|
||||||
|
rb_helper_restart(helper);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_setselect(helper->ifd, RB_SELECT_READ, rb_helper_read_cb, helper);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_helper_run(rb_helper *helper)
|
||||||
|
{
|
||||||
|
if(helper == NULL)
|
||||||
|
return;
|
||||||
|
rb_helper_read_cb(helper->ifd, helper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_helper_close(rb_helper *helper)
|
||||||
|
{
|
||||||
|
if(helper == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rb_close(helper->ifd);
|
||||||
|
rb_close(helper->ofd);
|
||||||
|
rb_free(helper);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_helper_read(rb_helper *helper, void *buf, size_t bufsize)
|
||||||
|
{
|
||||||
|
return rb_linebuf_get(&helper->recvq, buf, bufsize, LINEBUF_COMPLETE, LINEBUF_PARSED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_helper_loop(rb_helper *helper, long delay)
|
||||||
|
{
|
||||||
|
rb_helper_run(helper);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
rb_lib_loop(delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
399
libratbox/src/kqueue.c
Normal file
399
libratbox/src/kqueue.c
Normal file
|
@ -0,0 +1,399 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* kqueue.c: FreeBSD kqueue compatible network routines.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: kqueue.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <commio-int.h>
|
||||||
|
#include <event-int.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_SYS_EVENT_H) && (HAVE_KEVENT)
|
||||||
|
|
||||||
|
#include <sys/event.h>
|
||||||
|
|
||||||
|
#define KE_LENGTH 128
|
||||||
|
|
||||||
|
/* jlemon goofed up and didn't add EV_SET until fbsd 4.3 */
|
||||||
|
|
||||||
|
#ifndef EV_SET
|
||||||
|
#define EV_SET(kevp, a, b, c, d, e, f) do { \
|
||||||
|
(kevp)->ident = (a); \
|
||||||
|
(kevp)->filter = (b); \
|
||||||
|
(kevp)->flags = (c); \
|
||||||
|
(kevp)->fflags = (d); \
|
||||||
|
(kevp)->data = (e); \
|
||||||
|
(kevp)->udata = (f); \
|
||||||
|
} while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EVFILT_TIMER
|
||||||
|
#define KQUEUE_SCHED_EVENT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void kq_update_events(rb_fde_t *, short, PF *);
|
||||||
|
static int kq;
|
||||||
|
static struct timespec zero_timespec;
|
||||||
|
|
||||||
|
static struct kevent *kqlst; /* kevent buffer */
|
||||||
|
static int kqmax; /* max structs to buffer */
|
||||||
|
static int kqoff; /* offset into the buffer */
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_kqueue(rb_fde_t * F)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
kq_update_events(rb_fde_t * F, short filter, PF * handler)
|
||||||
|
{
|
||||||
|
PF *cur_handler;
|
||||||
|
int kep_flags;
|
||||||
|
|
||||||
|
switch (filter)
|
||||||
|
{
|
||||||
|
case EVFILT_READ:
|
||||||
|
cur_handler = F->read_handler;
|
||||||
|
break;
|
||||||
|
case EVFILT_WRITE:
|
||||||
|
cur_handler = F->write_handler;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* XXX bad! -- adrian */
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((cur_handler == NULL && handler != NULL) || (cur_handler != NULL && handler == NULL))
|
||||||
|
{
|
||||||
|
struct kevent *kep;
|
||||||
|
|
||||||
|
kep = kqlst + kqoff;
|
||||||
|
|
||||||
|
if(handler != NULL)
|
||||||
|
{
|
||||||
|
if(filter == EVFILT_WRITE)
|
||||||
|
kep_flags = (EV_ADD | EV_ONESHOT);
|
||||||
|
else
|
||||||
|
kep_flags = EV_ADD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
kep_flags = EV_DELETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EV_SET(kep, (uintptr_t) F->fd, filter, kep_flags, 0, 0, (void *) F);
|
||||||
|
|
||||||
|
if(++kqoff == kqmax)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = kevent(kq, kqlst, kqoff, NULL, 0, &zero_timespec);
|
||||||
|
/* jdc -- someone needs to do error checking... */
|
||||||
|
if(ret == -1)
|
||||||
|
{
|
||||||
|
rb_lib_log("kq_update_events(): kevent(): %s", strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
kqoff = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
|
||||||
|
/* Public functions */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_init_netio
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to initialise
|
||||||
|
* the network loop code.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rb_init_netio_kqueue(void)
|
||||||
|
{
|
||||||
|
kq = kqueue();
|
||||||
|
if(kq < 0)
|
||||||
|
{
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
kqmax = getdtablesize();
|
||||||
|
kqlst = rb_malloc(sizeof(struct kevent) * kqmax);
|
||||||
|
rb_open(kq, RB_FD_UNKNOWN, "kqueue fd");
|
||||||
|
zero_timespec.tv_sec = 0;
|
||||||
|
zero_timespec.tv_nsec = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_setselect
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to register
|
||||||
|
* and deregister interest in a pending IO state for a given FD.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_setselect_kqueue(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
|
||||||
|
{
|
||||||
|
lrb_assert(IsFDOpen(F));
|
||||||
|
|
||||||
|
if(type & RB_SELECT_READ)
|
||||||
|
{
|
||||||
|
kq_update_events(F, EVFILT_READ, handler);
|
||||||
|
F->read_handler = handler;
|
||||||
|
F->read_data = client_data;
|
||||||
|
}
|
||||||
|
if(type & RB_SELECT_WRITE)
|
||||||
|
{
|
||||||
|
kq_update_events(F, EVFILT_WRITE, handler);
|
||||||
|
F->write_handler = handler;
|
||||||
|
F->write_data = client_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check all connections for new connections and input data that is to be
|
||||||
|
* processed. Also check for connections with data queued and whether we can
|
||||||
|
* write it out.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_select
|
||||||
|
*
|
||||||
|
* Called to do the new-style IO, courtesy of squid (like most of this
|
||||||
|
* new IO code). This routine handles the stuff we've hidden in
|
||||||
|
* rb_setselect and fd_table[] and calls callbacks for IO ready
|
||||||
|
* events.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_kqueue(long delay)
|
||||||
|
{
|
||||||
|
int num, i;
|
||||||
|
static struct kevent ke[KE_LENGTH];
|
||||||
|
struct timespec poll_time;
|
||||||
|
struct timespec *pt;
|
||||||
|
rb_fde_t *F;
|
||||||
|
|
||||||
|
|
||||||
|
if(delay < 0) {
|
||||||
|
pt = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pt = &poll_time;
|
||||||
|
poll_time.tv_sec = delay / 1000;
|
||||||
|
poll_time.tv_nsec = (delay % 1000) * 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
num = kevent(kq, kqlst, kqoff, ke, KE_LENGTH, pt);
|
||||||
|
kqoff = 0;
|
||||||
|
|
||||||
|
if(num >= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(rb_ignore_errno(errno))
|
||||||
|
break;
|
||||||
|
|
||||||
|
rb_set_time();
|
||||||
|
|
||||||
|
return RB_ERROR;
|
||||||
|
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_set_time();
|
||||||
|
|
||||||
|
if(num == 0)
|
||||||
|
return RB_OK; /* No error.. */
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
PF *hdl = NULL;
|
||||||
|
|
||||||
|
if(ke[i].flags & EV_ERROR)
|
||||||
|
{
|
||||||
|
errno = ke[i].data;
|
||||||
|
/* XXX error == bad! -- adrian */
|
||||||
|
continue; /* XXX! */
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ke[i].filter)
|
||||||
|
{
|
||||||
|
|
||||||
|
case EVFILT_READ:
|
||||||
|
F = ke[i].udata;
|
||||||
|
if((hdl = F->read_handler) != NULL)
|
||||||
|
{
|
||||||
|
F->read_handler = NULL;
|
||||||
|
hdl(F, F->read_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVFILT_WRITE:
|
||||||
|
F = ke[i].udata;
|
||||||
|
if((hdl = F->write_handler) != NULL)
|
||||||
|
{
|
||||||
|
F->write_handler = NULL;
|
||||||
|
hdl(F, F->write_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#if defined(EVFILT_TIMER)
|
||||||
|
case EVFILT_TIMER:
|
||||||
|
rb_run_event(ke[i].udata);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
/* Bad! -- adrian */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RB_OK;
|
||||||
|
}
|
||||||
|
static int can_do_event = 0;
|
||||||
|
int
|
||||||
|
rb_kqueue_supports_event(void)
|
||||||
|
{
|
||||||
|
struct kevent kv;
|
||||||
|
struct timespec ts;
|
||||||
|
int xkq;
|
||||||
|
|
||||||
|
if(can_do_event == 1)
|
||||||
|
return 1;
|
||||||
|
if(can_do_event == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
xkq = kqueue();
|
||||||
|
ts.tv_sec = 0;
|
||||||
|
ts.tv_nsec = 1000;
|
||||||
|
|
||||||
|
|
||||||
|
EV_SET(&kv, (uintptr_t) 0x0, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 1, 0);
|
||||||
|
if(kevent(xkq, &kv, 1, NULL, 0, NULL) < 0)
|
||||||
|
{
|
||||||
|
can_do_event = -1;
|
||||||
|
close(xkq);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
close(xkq);
|
||||||
|
can_do_event = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_kqueue_sched_event(struct ev_entry *event, int when)
|
||||||
|
{
|
||||||
|
struct kevent kev;
|
||||||
|
int kep_flags;
|
||||||
|
|
||||||
|
kep_flags = EV_ADD;
|
||||||
|
if(event->frequency == 0)
|
||||||
|
kep_flags |= EV_ONESHOT;
|
||||||
|
EV_SET(&kev, (uintptr_t) event, EVFILT_TIMER, kep_flags, 0, when * 1000, event);
|
||||||
|
if(kevent(kq, &kev, 1, NULL, 0, NULL) < 0)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_kqueue_unsched_event(struct ev_entry *event)
|
||||||
|
{
|
||||||
|
struct kevent kev;
|
||||||
|
EV_SET(&kev, (uintptr_t) event, EVFILT_TIMER, EV_DELETE, 0, 0, event);
|
||||||
|
kevent(kq, &kev, 1, NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_kqueue_init_event(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* kqueue not supported */
|
||||||
|
int
|
||||||
|
rb_init_netio_kqueue(void)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_setselect_kqueue(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_kqueue(long delay)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_kqueue(rb_fde_t * F)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_KEVENT) || !defined(KQUEUE_SCHED_EVENT)
|
||||||
|
void
|
||||||
|
rb_kqueue_init_event(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_kqueue_sched_event(struct ev_entry *event, int when)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_kqueue_unsched_event(struct ev_entry *event)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_kqueue_supports_event(void)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* !HAVE_KEVENT || !KQUEUE_SCHED_EVENT */
|
872
libratbox/src/linebuf.c
Normal file
872
libratbox/src/linebuf.c
Normal file
|
@ -0,0 +1,872 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* linebuf.c: Maintains linebuffers.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001-2002 Adrian Chadd <adrian@creative.net.au>
|
||||||
|
* Copyright (C) 2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: linebuf.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <commio-int.h>
|
||||||
|
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
static rb_bh *rb_linebuf_heap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int bufline_count = 0;
|
||||||
|
|
||||||
|
#ifndef LINEBUF_HEAP_SIZE
|
||||||
|
#define LINEBUF_HEAP_SIZE 2048
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_linebuf_init
|
||||||
|
*
|
||||||
|
* Initialise the linebuf mechanism
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_linebuf_init(size_t heap_size)
|
||||||
|
{
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
rb_linebuf_heap = rb_bh_create(sizeof(buf_line_t), heap_size, "librb_linebuf_heap");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static buf_line_t *
|
||||||
|
rb_linebuf_allocate(void)
|
||||||
|
{
|
||||||
|
buf_line_t *t;
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
t = rb_bh_alloc(rb_linebuf_heap);
|
||||||
|
#else
|
||||||
|
t = rb_malloc(sizeof(buf_line_t));
|
||||||
|
#endif
|
||||||
|
return (t);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rb_linebuf_free(buf_line_t * p)
|
||||||
|
{
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
rb_bh_free(rb_linebuf_heap, p);
|
||||||
|
#else
|
||||||
|
rb_free(p);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_linebuf_new_line
|
||||||
|
*
|
||||||
|
* Create a new line, and link it to the given linebuf.
|
||||||
|
* It will be initially empty.
|
||||||
|
*/
|
||||||
|
static buf_line_t *
|
||||||
|
rb_linebuf_new_line(buf_head_t * bufhead)
|
||||||
|
{
|
||||||
|
buf_line_t *bufline;
|
||||||
|
rb_dlink_node *node;
|
||||||
|
|
||||||
|
bufline = rb_linebuf_allocate();
|
||||||
|
if(bufline == NULL)
|
||||||
|
return NULL;
|
||||||
|
++bufline_count;
|
||||||
|
|
||||||
|
|
||||||
|
node = rb_make_rb_dlink_node();
|
||||||
|
|
||||||
|
/* Stick it at the end of the buf list */
|
||||||
|
rb_dlinkAddTail(bufline, node, &bufhead->list);
|
||||||
|
bufline->refcount++;
|
||||||
|
|
||||||
|
/* And finally, update the allocated size */
|
||||||
|
bufhead->alloclen++;
|
||||||
|
bufhead->numlines++;
|
||||||
|
|
||||||
|
return bufline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_linebuf_done_line
|
||||||
|
*
|
||||||
|
* We've finished with the given line, so deallocate it
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
rb_linebuf_done_line(buf_head_t * bufhead, buf_line_t * bufline, rb_dlink_node * node)
|
||||||
|
{
|
||||||
|
/* Remove it from the linked list */
|
||||||
|
rb_dlinkDestroy(node, &bufhead->list);
|
||||||
|
|
||||||
|
/* Update the allocated size */
|
||||||
|
bufhead->alloclen--;
|
||||||
|
bufhead->len -= bufline->len;
|
||||||
|
lrb_assert(bufhead->len >= 0);
|
||||||
|
bufhead->numlines--;
|
||||||
|
|
||||||
|
bufline->refcount--;
|
||||||
|
lrb_assert(bufline->refcount >= 0);
|
||||||
|
|
||||||
|
if(bufline->refcount == 0)
|
||||||
|
{
|
||||||
|
/* and finally, deallocate the buf */
|
||||||
|
--bufline_count;
|
||||||
|
lrb_assert(bufline_count >= 0);
|
||||||
|
rb_linebuf_free(bufline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* skip to end of line or the crlfs, return the number of bytes ..
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
rb_linebuf_skip_crlf(char *ch, int len)
|
||||||
|
{
|
||||||
|
int orig_len = len;
|
||||||
|
|
||||||
|
/* First, skip until the first non-CRLF */
|
||||||
|
for(; len; len--, ch++)
|
||||||
|
{
|
||||||
|
if(*ch == '\r')
|
||||||
|
break;
|
||||||
|
else if(*ch == '\n')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then, skip until the last CRLF */
|
||||||
|
for(; len; len--, ch++)
|
||||||
|
{
|
||||||
|
if((*ch != '\r') && (*ch != '\n'))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lrb_assert(orig_len > len);
|
||||||
|
return (orig_len - len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_linebuf_newbuf
|
||||||
|
*
|
||||||
|
* Initialise the new buffer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_linebuf_newbuf(buf_head_t * bufhead)
|
||||||
|
{
|
||||||
|
/* not much to do right now :) */
|
||||||
|
memset(bufhead, 0, sizeof(buf_head_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_linebuf_donebuf
|
||||||
|
*
|
||||||
|
* Flush all the lines associated with this buffer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_linebuf_donebuf(buf_head_t * bufhead)
|
||||||
|
{
|
||||||
|
while(bufhead->list.head != NULL)
|
||||||
|
{
|
||||||
|
rb_linebuf_done_line(bufhead, (buf_line_t *) bufhead->list.head->data, bufhead->list.head);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_linebuf_copy_line
|
||||||
|
*
|
||||||
|
* Okay..this functions comments made absolutely no sense.
|
||||||
|
*
|
||||||
|
* Basically what we do is this. Find the first chunk of text
|
||||||
|
* and then scan for a CRLF. If we didn't find it, but we didn't
|
||||||
|
* overflow our buffer..we wait for some more data.
|
||||||
|
* If we found a CRLF, we replace them with a \0 character.
|
||||||
|
* If we overflowed, we copy the most our buffer can handle, terminate
|
||||||
|
* it with a \0 and return.
|
||||||
|
*
|
||||||
|
* The return value is the amount of data we consumed. This could
|
||||||
|
* be different than the size of the linebuffer, as when we discard
|
||||||
|
* the overflow, we don't want to process it again.
|
||||||
|
*
|
||||||
|
* This still sucks in my opinion, but it seems to work.
|
||||||
|
*
|
||||||
|
* -Aaron
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
rb_linebuf_copy_line(buf_head_t * bufhead, buf_line_t * bufline, char *data, int len)
|
||||||
|
{
|
||||||
|
int cpylen = 0; /* how many bytes we've copied */
|
||||||
|
char *ch = data; /* Pointer to where we are in the read data */
|
||||||
|
char *bufch = bufline->buf + bufline->len;
|
||||||
|
int clen = 0; /* how many bytes we've processed,
|
||||||
|
and don't ever want to see again.. */
|
||||||
|
|
||||||
|
/* If its full or terminated, ignore it */
|
||||||
|
|
||||||
|
bufline->raw = 0;
|
||||||
|
lrb_assert(bufline->len < BUF_DATA_SIZE);
|
||||||
|
if(bufline->terminated == 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
clen = cpylen = rb_linebuf_skip_crlf(ch, len);
|
||||||
|
if(clen == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* This is the ~overflow case..This doesn't happen often.. */
|
||||||
|
if(cpylen > (BUF_DATA_SIZE - bufline->len - 1))
|
||||||
|
{
|
||||||
|
memcpy(bufch, ch, (BUF_DATA_SIZE - bufline->len - 1));
|
||||||
|
bufline->buf[BUF_DATA_SIZE - 1] = '\0';
|
||||||
|
bufch = bufline->buf + BUF_DATA_SIZE - 2;
|
||||||
|
while(cpylen && (*bufch == '\r' || *bufch == '\n'))
|
||||||
|
{
|
||||||
|
*bufch = '\0';
|
||||||
|
cpylen--;
|
||||||
|
bufch--;
|
||||||
|
}
|
||||||
|
bufline->terminated = 1;
|
||||||
|
bufline->len = BUF_DATA_SIZE - 1;
|
||||||
|
bufhead->len += BUF_DATA_SIZE - 1;
|
||||||
|
return clen;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(bufch, ch, cpylen);
|
||||||
|
bufch += cpylen;
|
||||||
|
*bufch = '\0';
|
||||||
|
bufch--;
|
||||||
|
|
||||||
|
if(*bufch != '\r' && *bufch != '\n')
|
||||||
|
{
|
||||||
|
/* No linefeed, bail for the next time */
|
||||||
|
bufhead->len += cpylen;
|
||||||
|
bufline->len += cpylen;
|
||||||
|
bufline->terminated = 0;
|
||||||
|
return clen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Yank the CRLF off this, replace with a \0 */
|
||||||
|
while(cpylen && (*bufch == '\r' || *bufch == '\n'))
|
||||||
|
{
|
||||||
|
*bufch = '\0';
|
||||||
|
cpylen--;
|
||||||
|
bufch--;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufline->terminated = 1;
|
||||||
|
bufhead->len += cpylen;
|
||||||
|
bufline->len += cpylen;
|
||||||
|
return clen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_linebuf_copy_raw
|
||||||
|
*
|
||||||
|
* Copy as much data as possible directly into a linebuf,
|
||||||
|
* splitting at \r\n, but without altering any data.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
rb_linebuf_copy_raw(buf_head_t * bufhead, buf_line_t * bufline, char *data, int len)
|
||||||
|
{
|
||||||
|
int cpylen = 0; /* how many bytes we've copied */
|
||||||
|
char *ch = data; /* Pointer to where we are in the read data */
|
||||||
|
char *bufch = bufline->buf + bufline->len;
|
||||||
|
int clen = 0; /* how many bytes we've processed,
|
||||||
|
and don't ever want to see again.. */
|
||||||
|
|
||||||
|
/* If its full or terminated, ignore it */
|
||||||
|
|
||||||
|
bufline->raw = 1;
|
||||||
|
lrb_assert(bufline->len < BUF_DATA_SIZE);
|
||||||
|
if(bufline->terminated == 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
clen = cpylen = rb_linebuf_skip_crlf(ch, len);
|
||||||
|
if(clen == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* This is the overflow case..This doesn't happen often.. */
|
||||||
|
if(cpylen > (BUF_DATA_SIZE - bufline->len - 1))
|
||||||
|
{
|
||||||
|
clen = BUF_DATA_SIZE - bufline->len - 1;
|
||||||
|
memcpy(bufch, ch, clen);
|
||||||
|
bufline->buf[BUF_DATA_SIZE - 1] = '\0';
|
||||||
|
bufch = bufline->buf + BUF_DATA_SIZE - 2;
|
||||||
|
bufline->terminated = 1;
|
||||||
|
bufline->len = BUF_DATA_SIZE - 1;
|
||||||
|
bufhead->len += BUF_DATA_SIZE - 1;
|
||||||
|
return clen;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(bufch, ch, cpylen);
|
||||||
|
bufch += cpylen;
|
||||||
|
*bufch = '\0';
|
||||||
|
bufch--;
|
||||||
|
|
||||||
|
if(*bufch != '\r' && *bufch != '\n')
|
||||||
|
{
|
||||||
|
/* No linefeed, bail for the next time */
|
||||||
|
bufhead->len += cpylen;
|
||||||
|
bufline->len += cpylen;
|
||||||
|
bufline->terminated = 0;
|
||||||
|
return clen;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufline->terminated = 1;
|
||||||
|
bufhead->len += cpylen;
|
||||||
|
bufline->len += cpylen;
|
||||||
|
return clen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_linebuf_parse
|
||||||
|
*
|
||||||
|
* Take a given buffer and break out as many buffers as we can.
|
||||||
|
* If we find a CRLF, we terminate that buffer and create a new one.
|
||||||
|
* If we don't find a CRLF whilst parsing a buffer, we don't mark it
|
||||||
|
* 'finished', so the next loop through we can continue appending ..
|
||||||
|
*
|
||||||
|
* A few notes here, which you'll need to understand before continuing.
|
||||||
|
*
|
||||||
|
* - right now I'm only dealing with single sized buffers. Later on,
|
||||||
|
* I might consider chaining buffers together to get longer "lines"
|
||||||
|
* but seriously, I don't see the advantage right now.
|
||||||
|
*
|
||||||
|
* - This *is* designed to turn into a reference-counter-protected setup
|
||||||
|
* to dodge copious copies.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rb_linebuf_parse(buf_head_t * bufhead, char *data, int len, int raw)
|
||||||
|
{
|
||||||
|
buf_line_t *bufline;
|
||||||
|
int cpylen;
|
||||||
|
int linecnt = 0;
|
||||||
|
|
||||||
|
/* First, if we have a partial buffer, try to squeze data into it */
|
||||||
|
if(bufhead->list.tail != NULL)
|
||||||
|
{
|
||||||
|
/* Check we're doing the partial buffer thing */
|
||||||
|
bufline = bufhead->list.tail->data;
|
||||||
|
lrb_assert(!bufline->flushing);
|
||||||
|
/* just try, the worst it could do is *reject* us .. */
|
||||||
|
if(!raw)
|
||||||
|
cpylen = rb_linebuf_copy_line(bufhead, bufline, data, len);
|
||||||
|
else
|
||||||
|
cpylen = rb_linebuf_copy_raw(bufhead, bufline, data, len);
|
||||||
|
|
||||||
|
if(cpylen == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
linecnt++;
|
||||||
|
/* If we've copied the same as what we've got, quit now */
|
||||||
|
if(cpylen == len)
|
||||||
|
return linecnt; /* all the data done so soon? */
|
||||||
|
|
||||||
|
/* Skip the data and update len .. */
|
||||||
|
len -= cpylen;
|
||||||
|
lrb_assert(len >= 0);
|
||||||
|
data += cpylen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next, the loop */
|
||||||
|
while(len > 0)
|
||||||
|
{
|
||||||
|
/* We obviously need a new buffer, so .. */
|
||||||
|
bufline = rb_linebuf_new_line(bufhead);
|
||||||
|
|
||||||
|
/* And parse */
|
||||||
|
if(!raw)
|
||||||
|
cpylen = rb_linebuf_copy_line(bufhead, bufline, data, len);
|
||||||
|
else
|
||||||
|
cpylen = rb_linebuf_copy_raw(bufhead, bufline, data, len);
|
||||||
|
|
||||||
|
if(cpylen == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
len -= cpylen;
|
||||||
|
lrb_assert(len >= 0);
|
||||||
|
data += cpylen;
|
||||||
|
linecnt++;
|
||||||
|
}
|
||||||
|
return linecnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_linebuf_get
|
||||||
|
*
|
||||||
|
* get the next buffer from our line. For the time being it will copy
|
||||||
|
* data into the given buffer and free the underlying linebuf.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rb_linebuf_get(buf_head_t * bufhead, char *buf, int buflen, int partial, int raw)
|
||||||
|
{
|
||||||
|
buf_line_t *bufline;
|
||||||
|
int cpylen;
|
||||||
|
char *start, *ch;
|
||||||
|
|
||||||
|
/* make sure we have a line */
|
||||||
|
if(bufhead->list.head == NULL)
|
||||||
|
return 0; /* Obviously not.. hrm. */
|
||||||
|
|
||||||
|
bufline = bufhead->list.head->data;
|
||||||
|
|
||||||
|
/* make sure that the buffer was actually *terminated */
|
||||||
|
if(!(partial || bufline->terminated))
|
||||||
|
return 0; /* Wait for more data! */
|
||||||
|
|
||||||
|
if(buflen < bufline->len)
|
||||||
|
cpylen = buflen - 1;
|
||||||
|
else
|
||||||
|
cpylen = bufline->len;
|
||||||
|
|
||||||
|
/* Copy it */
|
||||||
|
start = bufline->buf;
|
||||||
|
|
||||||
|
/* if we left extraneous '\r\n' characters in the string,
|
||||||
|
* and we don't want to read the raw data, clean up the string.
|
||||||
|
*/
|
||||||
|
if(bufline->raw && !raw)
|
||||||
|
{
|
||||||
|
/* skip leading EOL characters */
|
||||||
|
while(cpylen && (*start == '\r' || *start == '\n'))
|
||||||
|
{
|
||||||
|
start++;
|
||||||
|
cpylen--;
|
||||||
|
}
|
||||||
|
/* skip trailing EOL characters */
|
||||||
|
ch = &start[cpylen - 1];
|
||||||
|
while(cpylen && (*ch == '\r' || *ch == '\n'))
|
||||||
|
{
|
||||||
|
ch--;
|
||||||
|
cpylen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buf, start, cpylen);
|
||||||
|
|
||||||
|
/* convert CR/LF to NULL */
|
||||||
|
if(!raw)
|
||||||
|
buf[cpylen] = '\0';
|
||||||
|
|
||||||
|
lrb_assert(cpylen >= 0);
|
||||||
|
|
||||||
|
/* Deallocate the line */
|
||||||
|
rb_linebuf_done_line(bufhead, bufline, bufhead->list.head);
|
||||||
|
|
||||||
|
/* return how much we copied */
|
||||||
|
return cpylen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_linebuf_attach
|
||||||
|
*
|
||||||
|
* attach the lines in a buf_head_t to another buf_head_t
|
||||||
|
* without copying the data (using refcounts).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_linebuf_attach(buf_head_t * bufhead, buf_head_t * new)
|
||||||
|
{
|
||||||
|
rb_dlink_node *ptr;
|
||||||
|
buf_line_t *line;
|
||||||
|
|
||||||
|
RB_DLINK_FOREACH(ptr, new->list.head)
|
||||||
|
{
|
||||||
|
line = ptr->data;
|
||||||
|
rb_dlinkAddTailAlloc(line, &bufhead->list);
|
||||||
|
|
||||||
|
/* Update the allocated size */
|
||||||
|
bufhead->alloclen++;
|
||||||
|
bufhead->len += line->len;
|
||||||
|
bufhead->numlines++;
|
||||||
|
|
||||||
|
line->refcount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_linebuf_putmsg
|
||||||
|
*
|
||||||
|
* Similar to rb_linebuf_put, but designed for use by send.c.
|
||||||
|
*
|
||||||
|
* prefixfmt is used as a format for the varargs, and is inserted first.
|
||||||
|
* Then format/va_args is appended to the buffer.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_linebuf_putmsg(buf_head_t * bufhead, const char *format, va_list * va_args, const char *prefixfmt, ...)
|
||||||
|
{
|
||||||
|
buf_line_t *bufline;
|
||||||
|
int len = 0;
|
||||||
|
va_list prefix_args;
|
||||||
|
|
||||||
|
/* make sure the previous line is terminated */
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if(bufhead->list.tail)
|
||||||
|
{
|
||||||
|
bufline = bufhead->list.tail->data;
|
||||||
|
lrb_assert(bufline->terminated);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Create a new line */
|
||||||
|
bufline = rb_linebuf_new_line(bufhead);
|
||||||
|
|
||||||
|
if(prefixfmt != NULL)
|
||||||
|
{
|
||||||
|
va_start(prefix_args, prefixfmt);
|
||||||
|
len = rb_vsnprintf(bufline->buf, BUF_DATA_SIZE, prefixfmt, prefix_args);
|
||||||
|
va_end(prefix_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(va_args != NULL)
|
||||||
|
{
|
||||||
|
len += rb_vsnprintf((bufline->buf + len), (BUF_DATA_SIZE - len), format, *va_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
bufline->terminated = 1;
|
||||||
|
|
||||||
|
/* Truncate the data if required */
|
||||||
|
if(unlikely(len > 510))
|
||||||
|
{
|
||||||
|
len = 510;
|
||||||
|
bufline->buf[len++] = '\r';
|
||||||
|
bufline->buf[len++] = '\n';
|
||||||
|
}
|
||||||
|
else if(unlikely(len == 0))
|
||||||
|
{
|
||||||
|
bufline->buf[len++] = '\r';
|
||||||
|
bufline->buf[len++] = '\n';
|
||||||
|
bufline->buf[len] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Chop trailing CRLF's .. */
|
||||||
|
while((bufline->buf[len] == '\r') || (bufline->buf[len] == '\n') || (bufline->buf[len] == '\0'))
|
||||||
|
{
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufline->buf[++len] = '\r';
|
||||||
|
bufline->buf[++len] = '\n';
|
||||||
|
bufline->buf[++len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
bufline->len = len;
|
||||||
|
bufhead->len += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_linebuf_putbuf(buf_head_t *bufhead, const char *buffer)
|
||||||
|
{
|
||||||
|
buf_line_t *bufline;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
/* make sure the previous line is terminated */
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if(bufhead->list.tail)
|
||||||
|
{
|
||||||
|
bufline = bufhead->list.tail->data;
|
||||||
|
lrb_assert(bufline->terminated);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Create a new line */
|
||||||
|
bufline = rb_linebuf_new_line(bufhead);
|
||||||
|
|
||||||
|
if(unlikely(buffer != NULL))
|
||||||
|
len = rb_strlcpy(bufline->buf, buffer, BUF_DATA_SIZE);
|
||||||
|
|
||||||
|
bufline->terminated = 1;
|
||||||
|
|
||||||
|
/* Truncate the data if required */
|
||||||
|
if(unlikely(len > 510))
|
||||||
|
{
|
||||||
|
len = 510;
|
||||||
|
bufline->buf[len++] = '\r';
|
||||||
|
bufline->buf[len++] = '\n';
|
||||||
|
}
|
||||||
|
else if(unlikely(len == 0))
|
||||||
|
{
|
||||||
|
bufline->buf[len++] = '\r';
|
||||||
|
bufline->buf[len++] = '\n';
|
||||||
|
bufline->buf[len] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Chop trailing CRLF's .. */
|
||||||
|
while((bufline->buf[len] == '\r') || (bufline->buf[len] == '\n') || (bufline->buf[len] == '\0'))
|
||||||
|
{
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufline->buf[++len] = '\r';
|
||||||
|
bufline->buf[++len] = '\n';
|
||||||
|
bufline->buf[++len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
bufline->len = len;
|
||||||
|
bufhead->len += len;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_linebuf_put(buf_head_t * bufhead, const char *format, ...)
|
||||||
|
{
|
||||||
|
buf_line_t *bufline;
|
||||||
|
int len = 0;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
/* make sure the previous line is terminated */
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if(bufhead->list.tail)
|
||||||
|
{
|
||||||
|
bufline = bufhead->list.tail->data;
|
||||||
|
lrb_assert(bufline->terminated);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Create a new line */
|
||||||
|
bufline = rb_linebuf_new_line(bufhead);
|
||||||
|
|
||||||
|
if(unlikely(format != NULL))
|
||||||
|
{
|
||||||
|
va_start(args, format);
|
||||||
|
len = rb_vsnprintf(bufline->buf, BUF_DATA_SIZE, format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
bufline->terminated = 1;
|
||||||
|
|
||||||
|
/* Truncate the data if required */
|
||||||
|
if(unlikely(len > 510))
|
||||||
|
{
|
||||||
|
len = 510;
|
||||||
|
bufline->buf[len++] = '\r';
|
||||||
|
bufline->buf[len++] = '\n';
|
||||||
|
}
|
||||||
|
else if(unlikely(len == 0))
|
||||||
|
{
|
||||||
|
bufline->buf[len++] = '\r';
|
||||||
|
bufline->buf[len++] = '\n';
|
||||||
|
bufline->buf[len] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Chop trailing CRLF's .. */
|
||||||
|
while((bufline->buf[len] == '\r') || (bufline->buf[len] == '\n') || (bufline->buf[len] == '\0'))
|
||||||
|
{
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufline->buf[++len] = '\r';
|
||||||
|
bufline->buf[++len] = '\n';
|
||||||
|
bufline->buf[++len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
bufline->len = len;
|
||||||
|
bufhead->len += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_linebuf_flush
|
||||||
|
*
|
||||||
|
* Flush data to the buffer. It tries to write as much data as possible
|
||||||
|
* to the given socket. Any return values are passed straight through.
|
||||||
|
* If there is no data in the socket, EWOULDBLOCK is set as an errno
|
||||||
|
* rather than returning 0 (which would map to an EOF..)
|
||||||
|
*
|
||||||
|
* Notes: XXX We *should* have a clue here when a non-full buffer is arrived.
|
||||||
|
* and tag it so that we don't re-schedule another write until
|
||||||
|
* we have a CRLF.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rb_linebuf_flush(rb_fde_t *F, buf_head_t * bufhead)
|
||||||
|
{
|
||||||
|
buf_line_t *bufline;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* autoconf checks for this..but really just want to use it if we have a
|
||||||
|
* native version even if libircd provides a fake version...
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_WRITEV
|
||||||
|
if(!rb_fd_ssl(F))
|
||||||
|
{
|
||||||
|
rb_dlink_node *ptr;
|
||||||
|
int x = 0, y;
|
||||||
|
int xret;
|
||||||
|
static struct rb_iovec vec[RB_UIO_MAXIOV];
|
||||||
|
|
||||||
|
memset(vec, 0, sizeof(vec));
|
||||||
|
/* Check we actually have a first buffer */
|
||||||
|
if(bufhead->list.head == NULL)
|
||||||
|
{
|
||||||
|
/* nope, so we return none .. */
|
||||||
|
errno = EWOULDBLOCK;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = bufhead->list.head;
|
||||||
|
|
||||||
|
bufline = ptr->data;
|
||||||
|
if(!bufline->terminated)
|
||||||
|
{
|
||||||
|
errno = EWOULDBLOCK;
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bufline->flushing)
|
||||||
|
{
|
||||||
|
vec[x].iov_base = bufline->buf + bufhead->writeofs;
|
||||||
|
vec[x++].iov_len = bufline->len - bufhead->writeofs;
|
||||||
|
ptr = ptr->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(ptr == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bufline = ptr->data;
|
||||||
|
if(!bufline->terminated)
|
||||||
|
break;
|
||||||
|
|
||||||
|
vec[x].iov_base = bufline->buf;
|
||||||
|
vec[x].iov_len = bufline->len;
|
||||||
|
ptr = ptr->next;
|
||||||
|
|
||||||
|
} while(++x < RB_UIO_MAXIOV);
|
||||||
|
|
||||||
|
if(x == 0)
|
||||||
|
{
|
||||||
|
errno = EWOULDBLOCK;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
xret = retval = rb_writev(F, vec, x);
|
||||||
|
if(retval <= 0)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
ptr = bufhead->list.head;
|
||||||
|
|
||||||
|
for(y = 0; y < x; y++)
|
||||||
|
{
|
||||||
|
bufline = ptr->data;
|
||||||
|
|
||||||
|
if(bufline->flushing)
|
||||||
|
{
|
||||||
|
if(xret >= bufline->len - bufhead->writeofs)
|
||||||
|
{
|
||||||
|
xret = xret - (bufline->len - bufhead->writeofs);
|
||||||
|
ptr = ptr->next;
|
||||||
|
rb_linebuf_done_line(bufhead, bufline, bufhead->list.head);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(xret >= bufline->len)
|
||||||
|
{
|
||||||
|
xret = xret - bufline->len;
|
||||||
|
ptr = ptr->next;
|
||||||
|
rb_linebuf_done_line(bufhead, bufline, bufhead->list.head);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bufline->flushing = 1;
|
||||||
|
bufhead->writeofs = xret;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* this is the non-writev case */
|
||||||
|
|
||||||
|
/* Check we actually have a first buffer */
|
||||||
|
if(bufhead->list.head == NULL)
|
||||||
|
{
|
||||||
|
/* nope, so we return none .. */
|
||||||
|
errno = EWOULDBLOCK;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufline = bufhead->list.head->data;
|
||||||
|
|
||||||
|
/* And that its actually full .. */
|
||||||
|
if(!bufline->terminated)
|
||||||
|
{
|
||||||
|
errno = EWOULDBLOCK;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check we're flushing the first buffer */
|
||||||
|
if(!bufline->flushing)
|
||||||
|
{
|
||||||
|
bufline->flushing = 1;
|
||||||
|
bufhead->writeofs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now, try writing data */
|
||||||
|
retval = rb_write(F, bufline->buf + bufhead->writeofs, bufline->len - bufhead->writeofs);
|
||||||
|
|
||||||
|
if(retval <= 0)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
/* we've got data, so update the write offset */
|
||||||
|
bufhead->writeofs += retval;
|
||||||
|
|
||||||
|
/* if we've written everything *and* the CRLF, deallocate and update
|
||||||
|
bufhead */
|
||||||
|
if(bufhead->writeofs == bufline->len)
|
||||||
|
{
|
||||||
|
bufhead->writeofs = 0;
|
||||||
|
lrb_assert(bufhead->len >= 0);
|
||||||
|
rb_linebuf_done_line(bufhead, bufline, bufhead->list.head);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return line length */
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* count linebufs for stats z
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_count_rb_linebuf_memory(size_t * count, size_t * rb_linebuf_memory_used)
|
||||||
|
{
|
||||||
|
#ifndef NOBALLOC
|
||||||
|
rb_bh_usage(rb_linebuf_heap, count, NULL, rb_linebuf_memory_used, NULL);
|
||||||
|
#else
|
||||||
|
*count = 0;
|
||||||
|
*rb_linebuf_memory_used = 0;
|
||||||
|
#endif
|
||||||
|
}
|
106
libratbox/src/nossl.c
Normal file
106
libratbox/src/nossl.c
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* libratbox: a library used by ircd-ratbox and other things
|
||||||
|
* nossl.c: ssl stub code
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007-2008 ircd-ratbox development team
|
||||||
|
* Copyright (C) 2007-2008 Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: commio.c 24808 2008-01-02 08:17:05Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
|
||||||
|
#ifndef HAVE_OPENSSL
|
||||||
|
|
||||||
|
#include <commio-int.h>
|
||||||
|
#include <commio-ssl.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_init_ssl(void)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_ssl_listen(rb_fde_t *F, int backlog)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rb_init_prng(const char *path, prng_seed_t seed_type)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_get_random(void *buf, size_t length)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
rb_get_ssl_strerror(rb_fde_t *F)
|
||||||
|
{
|
||||||
|
static const char *nosupport = "SSL/TLS not supported";
|
||||||
|
return nosupport;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_ssl_start_accepted(rb_fde_t *new_F, ACCB *cb, void *data, int timeout)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_ssl_start_connected(rb_fde_t *F, CNCB *callback, void *data, int timeout)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_connect_tcp_ssl(rb_fde_t *F, struct sockaddr *dest,
|
||||||
|
struct sockaddr *clocal, int socklen, CNCB *callback, void *data, int timeout)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_supports_ssl(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_ssl_shutdown(rb_fde_t * F)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* !HAVE_OPENSSL */
|
||||||
|
|
581
libratbox/src/openssl.c
Normal file
581
libratbox/src/openssl.c
Normal file
|
@ -0,0 +1,581 @@
|
||||||
|
/*
|
||||||
|
* libratbox: a library used by ircd-ratbox and other things
|
||||||
|
* openssl.c: openssl related code
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007-2008 ircd-ratbox development team
|
||||||
|
* Copyright (C) 2007-2008 Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: commio.c 24808 2008-01-02 08:17:05Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENSSL
|
||||||
|
|
||||||
|
#include <commio-int.h>
|
||||||
|
#include <commio-ssl.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/dh.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
|
static SSL_CTX *ssl_server_ctx;
|
||||||
|
static SSL_CTX *ssl_client_ctx;
|
||||||
|
|
||||||
|
static unsigned long get_last_err(void)
|
||||||
|
{
|
||||||
|
unsigned long t_err, err = 0;
|
||||||
|
err = ERR_get_error();
|
||||||
|
if(err == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while((t_err = ERR_get_error()) > 0)
|
||||||
|
err = t_err;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_ssl_shutdown(rb_fde_t * F)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if(F == NULL || F->ssl == NULL)
|
||||||
|
return;
|
||||||
|
SSL_set_shutdown((SSL *) F->ssl, SSL_RECEIVED_SHUTDOWN);
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if(SSL_shutdown((SSL *) F->ssl))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
get_last_err();
|
||||||
|
SSL_free((SSL *) F->ssl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rb_ssl_timeout(rb_fde_t * fd, void *notused)
|
||||||
|
{
|
||||||
|
rb_close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
rb_ssl_tryaccept(rb_fde_t * F, void *data)
|
||||||
|
{
|
||||||
|
int ssl_err;
|
||||||
|
lrb_assert(F->accept != NULL);
|
||||||
|
|
||||||
|
if(!SSL_is_init_finished((SSL *) F->ssl))
|
||||||
|
{
|
||||||
|
if((ssl_err = SSL_accept((SSL *) F->ssl)) <= 0)
|
||||||
|
{
|
||||||
|
switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err))
|
||||||
|
{
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
if(rb_ignore_errno(errno))
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
{
|
||||||
|
F->ssl_errno = get_last_err();
|
||||||
|
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE,
|
||||||
|
rb_ssl_tryaccept, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
F->ssl_errno = get_last_err();
|
||||||
|
F->accept->callback(F, RB_ERROR_SSL, NULL, 0, F->accept->data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rb_settimeout(F, 0, NULL, NULL);
|
||||||
|
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL);
|
||||||
|
|
||||||
|
F->accept->callback(F, RB_OK, (struct sockaddr *) &F->accept->S, F->accept->addrlen,
|
||||||
|
F->accept->data);
|
||||||
|
rb_free(F->accept);
|
||||||
|
F->accept = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_ssl_start_accepted(rb_fde_t * new_F, ACCB * cb, void *data, int timeout)
|
||||||
|
{
|
||||||
|
int ssl_err;
|
||||||
|
|
||||||
|
new_F->type |= RB_FD_SSL;
|
||||||
|
new_F->ssl = SSL_new(ssl_server_ctx);
|
||||||
|
new_F->accept = rb_malloc(sizeof(struct acceptdata));
|
||||||
|
|
||||||
|
new_F->accept->callback = cb;
|
||||||
|
new_F->accept->data = data;
|
||||||
|
rb_settimeout(new_F, timeout, rb_ssl_timeout, NULL);
|
||||||
|
|
||||||
|
new_F->accept->addrlen = 0;
|
||||||
|
SSL_set_fd((SSL *) new_F->ssl, rb_get_fd(new_F));
|
||||||
|
if((ssl_err = SSL_accept((SSL *) new_F->ssl)) <= 0)
|
||||||
|
{
|
||||||
|
switch (ssl_err = SSL_get_error((SSL *) new_F->ssl, ssl_err))
|
||||||
|
{
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
if(rb_ignore_errno(errno))
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
{
|
||||||
|
new_F->ssl_errno = get_last_err();
|
||||||
|
rb_setselect(new_F, RB_SELECT_READ | RB_SELECT_WRITE,
|
||||||
|
rb_ssl_tryaccept, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
new_F->ssl_errno = get_last_err();
|
||||||
|
new_F->accept->callback(new_F, RB_ERROR_SSL, NULL, 0, new_F->accept->data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rb_ssl_tryaccept(new_F, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_ssl_accept_setup(rb_fde_t * F, int new_fd, struct sockaddr *st, int addrlen)
|
||||||
|
{
|
||||||
|
rb_fde_t *new_F;
|
||||||
|
int ssl_err;
|
||||||
|
|
||||||
|
new_F = rb_find_fd(new_fd);
|
||||||
|
new_F->type |= RB_FD_SSL;
|
||||||
|
new_F->ssl = SSL_new(ssl_server_ctx);
|
||||||
|
new_F->accept = rb_malloc(sizeof(struct acceptdata));
|
||||||
|
|
||||||
|
new_F->accept->callback = F->accept->callback;
|
||||||
|
new_F->accept->data = F->accept->data;
|
||||||
|
rb_settimeout(new_F, 10, rb_ssl_timeout, NULL);
|
||||||
|
memcpy(&new_F->accept->S, st, addrlen);
|
||||||
|
new_F->accept->addrlen = addrlen;
|
||||||
|
|
||||||
|
SSL_set_fd((SSL *) new_F->ssl, new_fd);
|
||||||
|
if((ssl_err = SSL_accept((SSL *) new_F->ssl)) <= 0)
|
||||||
|
{
|
||||||
|
switch (ssl_err = SSL_get_error((SSL *) new_F->ssl, ssl_err))
|
||||||
|
{
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
if(rb_ignore_errno(errno))
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
{
|
||||||
|
F->ssl_errno = get_last_err();
|
||||||
|
rb_setselect(new_F, RB_SELECT_READ | RB_SELECT_WRITE,
|
||||||
|
rb_ssl_tryaccept, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
F->ssl_errno = get_last_err();
|
||||||
|
F->accept->callback(F, RB_ERROR_SSL, NULL, 0, F->accept->data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rb_ssl_tryaccept(new_F, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
rb_ssl_read_or_write(int r_or_w, rb_fde_t * F, void *rbuf, const void *wbuf, size_t count)
|
||||||
|
{
|
||||||
|
ssize_t ret;
|
||||||
|
unsigned long err;
|
||||||
|
SSL *ssl = F->ssl;
|
||||||
|
|
||||||
|
if(r_or_w == 0)
|
||||||
|
ret = (ssize_t)SSL_read(ssl, rbuf, (int) count);
|
||||||
|
else
|
||||||
|
ret = (ssize_t)SSL_write(ssl, wbuf, (int) count);
|
||||||
|
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
switch (SSL_get_error(ssl, ret))
|
||||||
|
{
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
errno = EAGAIN;
|
||||||
|
return RB_RW_SSL_NEED_READ;
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
errno = EAGAIN;
|
||||||
|
return RB_RW_SSL_NEED_WRITE;
|
||||||
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
|
return 0;
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
err = get_last_err();
|
||||||
|
if(err == 0)
|
||||||
|
{
|
||||||
|
F->ssl_errno = 0;
|
||||||
|
return RB_RW_IO_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err = get_last_err();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
F->ssl_errno = err;
|
||||||
|
if(err > 0)
|
||||||
|
{
|
||||||
|
errno = EIO; /* not great but... */
|
||||||
|
return RB_RW_SSL_ERROR;
|
||||||
|
}
|
||||||
|
return RB_RW_IO_ERROR;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
rb_ssl_read(rb_fde_t * F, void *buf, size_t count)
|
||||||
|
{
|
||||||
|
return rb_ssl_read_or_write(0, F, buf, NULL, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
rb_ssl_write(rb_fde_t * F, const void *buf, size_t count)
|
||||||
|
{
|
||||||
|
return rb_ssl_read_or_write(1, F, NULL, buf, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_init_ssl(void)
|
||||||
|
{
|
||||||
|
int ret = 1;
|
||||||
|
SSL_load_error_strings();
|
||||||
|
SSL_library_init();
|
||||||
|
ssl_server_ctx = SSL_CTX_new(SSLv23_server_method());
|
||||||
|
if(ssl_server_ctx == NULL)
|
||||||
|
{
|
||||||
|
rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s",
|
||||||
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
/* Disable SSLv2, make the client use our settings */
|
||||||
|
SSL_CTX_set_options(ssl_server_ctx, SSL_OP_NO_SSLv2 | SSL_OP_CIPHER_SERVER_PREFERENCE);
|
||||||
|
|
||||||
|
ssl_client_ctx = SSL_CTX_new(TLSv1_client_method());
|
||||||
|
|
||||||
|
if(ssl_client_ctx == NULL)
|
||||||
|
{
|
||||||
|
rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL client context: %s",
|
||||||
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile)
|
||||||
|
{
|
||||||
|
FILE *param;
|
||||||
|
DH *dh;
|
||||||
|
unsigned long err;
|
||||||
|
if(cert == NULL)
|
||||||
|
{
|
||||||
|
rb_lib_log("rb_setup_ssl_server: No certificate file");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!SSL_CTX_use_certificate_file(ssl_server_ctx, cert, SSL_FILETYPE_PEM))
|
||||||
|
{
|
||||||
|
err = ERR_get_error();
|
||||||
|
rb_lib_log("rb_setup_ssl_server: Error loading certificate file [%s]: %s", cert,
|
||||||
|
ERR_error_string(err, NULL));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(keyfile == NULL)
|
||||||
|
{
|
||||||
|
rb_lib_log("rb_setup_ssl_server: No key file");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(!SSL_CTX_use_PrivateKey_file(ssl_server_ctx, keyfile, SSL_FILETYPE_PEM))
|
||||||
|
{
|
||||||
|
err = ERR_get_error();
|
||||||
|
rb_lib_log("rb_setup_ssl_server: Error loading keyfile [%s]: %s", keyfile,
|
||||||
|
ERR_error_string(err, NULL));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dhfile != NULL)
|
||||||
|
{
|
||||||
|
/* DH parameters aren't necessary, but they are nice..if they didn't pass one..that is their problem */
|
||||||
|
param = fopen(dhfile, "r");
|
||||||
|
if(param != NULL)
|
||||||
|
{
|
||||||
|
dh = PEM_read_DHparams(param, NULL, NULL, NULL);
|
||||||
|
if(dh == NULL)
|
||||||
|
{
|
||||||
|
err = ERR_get_error();
|
||||||
|
rb_lib_log
|
||||||
|
("rb_setup_ssl_server: Error loading DH params file [%s]: %s",
|
||||||
|
param, ERR_error_string(err, NULL));
|
||||||
|
fclose(param);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SSL_CTX_set_tmp_dh(ssl_server_ctx, dh);
|
||||||
|
fclose(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_ssl_listen(rb_fde_t * F, int backlog)
|
||||||
|
{
|
||||||
|
F->type = RB_FD_SOCKET | RB_FD_LISTEN | RB_FD_SSL;
|
||||||
|
return listen(F->fd, backlog);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ssl_connect
|
||||||
|
{
|
||||||
|
CNCB *callback;
|
||||||
|
void *data;
|
||||||
|
int timeout;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
rb_ssl_connect_realcb(rb_fde_t * F, int status, struct ssl_connect *sconn)
|
||||||
|
{
|
||||||
|
F->connect->callback = sconn->callback;
|
||||||
|
F->connect->data = sconn->data;
|
||||||
|
rb_free(sconn);
|
||||||
|
rb_connect_callback(F, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rb_ssl_tryconn_timeout_cb(rb_fde_t * F, void *data)
|
||||||
|
{
|
||||||
|
rb_ssl_connect_realcb(F, RB_ERR_TIMEOUT, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rb_ssl_tryconn_cb(rb_fde_t * F, void *data)
|
||||||
|
{
|
||||||
|
struct ssl_connect *sconn = data;
|
||||||
|
int ssl_err;
|
||||||
|
if(!SSL_is_init_finished((SSL *) F->ssl))
|
||||||
|
{
|
||||||
|
if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0)
|
||||||
|
{
|
||||||
|
switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err))
|
||||||
|
{
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
if(rb_ignore_errno(errno))
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
{
|
||||||
|
F->ssl_errno = get_last_err();
|
||||||
|
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE,
|
||||||
|
rb_ssl_tryconn_cb, sconn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
F->ssl_errno = get_last_err();
|
||||||
|
rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rb_ssl_connect_realcb(F, RB_OK, sconn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rb_ssl_tryconn(rb_fde_t * F, int status, void *data)
|
||||||
|
{
|
||||||
|
struct ssl_connect *sconn = data;
|
||||||
|
int ssl_err;
|
||||||
|
if(status != RB_OK)
|
||||||
|
{
|
||||||
|
rb_ssl_connect_realcb(F, status, sconn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
F->type |= RB_FD_SSL;
|
||||||
|
F->ssl = SSL_new(ssl_client_ctx);
|
||||||
|
SSL_set_fd((SSL *) F->ssl, F->fd);
|
||||||
|
|
||||||
|
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
|
||||||
|
if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0)
|
||||||
|
{
|
||||||
|
switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err))
|
||||||
|
{
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
if(rb_ignore_errno(errno))
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
{
|
||||||
|
F->ssl_errno = get_last_err();
|
||||||
|
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE,
|
||||||
|
rb_ssl_tryconn_cb, sconn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
F->ssl_errno = get_last_err();
|
||||||
|
rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rb_ssl_connect_realcb(F, RB_OK, sconn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_connect_tcp_ssl(rb_fde_t * F, struct sockaddr *dest,
|
||||||
|
struct sockaddr *clocal, int socklen, CNCB * callback, void *data, int timeout)
|
||||||
|
{
|
||||||
|
struct ssl_connect *sconn;
|
||||||
|
if(F == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sconn = rb_malloc(sizeof(struct ssl_connect));
|
||||||
|
sconn->data = data;
|
||||||
|
sconn->callback = callback;
|
||||||
|
sconn->timeout = timeout;
|
||||||
|
rb_connect_tcp(F, dest, clocal, socklen, rb_ssl_tryconn, sconn, timeout);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_ssl_start_connected(rb_fde_t * F, CNCB * callback, void *data, int timeout)
|
||||||
|
{
|
||||||
|
struct ssl_connect *sconn;
|
||||||
|
int ssl_err;
|
||||||
|
if(F == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sconn = rb_malloc(sizeof(struct ssl_connect));
|
||||||
|
sconn->data = data;
|
||||||
|
sconn->callback = callback;
|
||||||
|
sconn->timeout = timeout;
|
||||||
|
F->connect = rb_malloc(sizeof(struct conndata));
|
||||||
|
F->connect->callback = callback;
|
||||||
|
F->connect->data = data;
|
||||||
|
F->type |= RB_FD_SSL;
|
||||||
|
F->ssl = SSL_new(ssl_client_ctx);
|
||||||
|
|
||||||
|
SSL_set_fd((SSL *) F->ssl, F->fd);
|
||||||
|
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
|
||||||
|
if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0)
|
||||||
|
{
|
||||||
|
switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err))
|
||||||
|
{
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
if(rb_ignore_errno(errno))
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
{
|
||||||
|
F->ssl_errno = get_last_err();
|
||||||
|
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE,
|
||||||
|
rb_ssl_tryconn_cb, sconn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
F->ssl_errno = get_last_err();
|
||||||
|
rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rb_ssl_connect_realcb(F, RB_OK, sconn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_init_prng(const char *path, prng_seed_t seed_type)
|
||||||
|
{
|
||||||
|
if(seed_type == RB_PRNG_DEFAULT)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
RAND_screen();
|
||||||
|
#endif
|
||||||
|
return RAND_status();
|
||||||
|
}
|
||||||
|
if(path == NULL)
|
||||||
|
return RAND_status();
|
||||||
|
|
||||||
|
switch (seed_type)
|
||||||
|
{
|
||||||
|
case RB_PRNG_EGD:
|
||||||
|
if(RAND_egd(path) == -1)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
case RB_PRNG_FILE:
|
||||||
|
if(RAND_load_file(path, -1) == -1)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
#ifdef WIN32
|
||||||
|
case RB_PRNGWIN32:
|
||||||
|
RAND_screen();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RAND_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_get_random(void *buf, size_t length)
|
||||||
|
{
|
||||||
|
if(RAND_status())
|
||||||
|
{
|
||||||
|
if(RAND_bytes(buf, length) > 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(RAND_pseudo_bytes(buf, length) >= 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
rb_get_ssl_strerror(rb_fde_t * F)
|
||||||
|
{
|
||||||
|
return ERR_error_string(F->ssl_errno, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_supports_ssl(void)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_OPESSL */
|
1121
libratbox/src/patricia.c
Normal file
1121
libratbox/src/patricia.c
Normal file
File diff suppressed because it is too large
Load diff
262
libratbox/src/poll.c
Normal file
262
libratbox/src/poll.c
Normal file
|
@ -0,0 +1,262 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* s_bsd_poll.c: POSIX poll() compatible network routines.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: poll.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <commio-int.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_POLL) && (HAVE_SYS_POLL_H)
|
||||||
|
#include <sys/poll.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* I hate linux -- adrian */
|
||||||
|
#ifndef POLLRDNORM
|
||||||
|
#define POLLRDNORM POLLIN
|
||||||
|
#endif
|
||||||
|
#ifndef POLLWRNORM
|
||||||
|
#define POLLWRNORM POLLOUT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct _pollfd_list
|
||||||
|
{
|
||||||
|
struct pollfd *pollfds;
|
||||||
|
int maxindex; /* highest FD number */
|
||||||
|
int allocated; /* number of pollfds allocated */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _pollfd_list pollfd_list_t;
|
||||||
|
|
||||||
|
static pollfd_list_t pollfd_list;
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_poll(rb_fde_t * F)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_init_netio
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to initialise
|
||||||
|
* the network loop code.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rb_init_netio_poll(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
pollfd_list.pollfds = rb_malloc(rb_getmaxconnect() * (sizeof(struct pollfd)));
|
||||||
|
pollfd_list.allocated = rb_getmaxconnect();
|
||||||
|
for (fd = 0; fd < rb_getmaxconnect(); fd++)
|
||||||
|
{
|
||||||
|
pollfd_list.pollfds[fd].fd = -1;
|
||||||
|
}
|
||||||
|
pollfd_list.maxindex = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
resize_pollarray(int fd)
|
||||||
|
{
|
||||||
|
if(unlikely(fd >= pollfd_list.allocated))
|
||||||
|
{
|
||||||
|
int x, old_value = pollfd_list.allocated;
|
||||||
|
pollfd_list.allocated += 1024;
|
||||||
|
pollfd_list.pollfds =
|
||||||
|
rb_realloc(pollfd_list.pollfds,
|
||||||
|
pollfd_list.allocated * (sizeof(struct pollfd)));
|
||||||
|
memset(&pollfd_list.pollfds[old_value + 1], 0, sizeof(struct pollfd) * 1024);
|
||||||
|
for (x = old_value + 1; x < pollfd_list.allocated; x++)
|
||||||
|
{
|
||||||
|
pollfd_list.pollfds[x].fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_setselect
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to register
|
||||||
|
* and deregister interest in a pending IO state for a given FD.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_setselect_poll(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
|
||||||
|
{
|
||||||
|
if(F == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(type & RB_SELECT_READ)
|
||||||
|
{
|
||||||
|
F->read_handler = handler;
|
||||||
|
F->read_data = client_data;
|
||||||
|
if(handler != NULL)
|
||||||
|
F->pflags |= POLLRDNORM;
|
||||||
|
else
|
||||||
|
F->pflags &= ~POLLRDNORM;
|
||||||
|
}
|
||||||
|
if(type & RB_SELECT_WRITE)
|
||||||
|
{
|
||||||
|
F->write_handler = handler;
|
||||||
|
F->write_data = client_data;
|
||||||
|
if(handler != NULL)
|
||||||
|
F->pflags |= POLLWRNORM;
|
||||||
|
else
|
||||||
|
F->pflags &= ~POLLWRNORM;
|
||||||
|
}
|
||||||
|
resize_pollarray(F->fd);
|
||||||
|
|
||||||
|
if(F->pflags <= 0)
|
||||||
|
{
|
||||||
|
pollfd_list.pollfds[F->fd].events = 0;
|
||||||
|
pollfd_list.pollfds[F->fd].fd = -1;
|
||||||
|
if(F->fd == pollfd_list.maxindex)
|
||||||
|
{
|
||||||
|
while (pollfd_list.maxindex >= 0
|
||||||
|
&& pollfd_list.pollfds[pollfd_list.maxindex].fd == -1)
|
||||||
|
pollfd_list.maxindex--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pollfd_list.pollfds[F->fd].events = F->pflags;
|
||||||
|
pollfd_list.pollfds[F->fd].fd = F->fd;
|
||||||
|
if(F->fd > pollfd_list.maxindex)
|
||||||
|
pollfd_list.maxindex = F->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* int rb_select(unsigned long delay)
|
||||||
|
* Input: The maximum time to delay.
|
||||||
|
* Output: Returns -1 on error, 0 on success.
|
||||||
|
* Side-effects: Deregisters future interest in IO and calls the handlers
|
||||||
|
* if an event occurs for an FD.
|
||||||
|
* Comments: Check all connections for new connections and input data
|
||||||
|
* that is to be processed. Also check for connections with data queued
|
||||||
|
* and whether we can write it out.
|
||||||
|
* Called to do the new-style IO, courtesy of squid (like most of this
|
||||||
|
* new IO code). This routine handles the stuff we've hidden in
|
||||||
|
* rb_setselect and fd_table[] and calls callbacks for IO ready
|
||||||
|
* events.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_poll(long delay)
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
int fd;
|
||||||
|
int ci;
|
||||||
|
PF *hdl;
|
||||||
|
void *data;
|
||||||
|
struct pollfd *pfd;
|
||||||
|
int revents;
|
||||||
|
|
||||||
|
num = poll(pollfd_list.pollfds, pollfd_list.maxindex + 1, delay);
|
||||||
|
rb_set_time();
|
||||||
|
if(num < 0)
|
||||||
|
{
|
||||||
|
if(!rb_ignore_errno(errno))
|
||||||
|
return RB_OK;
|
||||||
|
else
|
||||||
|
return RB_ERROR;
|
||||||
|
}
|
||||||
|
if(num == 0)
|
||||||
|
return RB_OK;
|
||||||
|
|
||||||
|
/* XXX we *could* optimise by falling out after doing num fds ... */
|
||||||
|
for (ci = 0; ci < pollfd_list.maxindex + 1; ci++)
|
||||||
|
{
|
||||||
|
rb_fde_t *F;
|
||||||
|
pfd = &pollfd_list.pollfds[ci];
|
||||||
|
|
||||||
|
revents = pfd->revents;
|
||||||
|
fd = pfd->fd;
|
||||||
|
if(revents == 0 || fd == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
F = rb_find_fd(fd);
|
||||||
|
if(F == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
|
||||||
|
{
|
||||||
|
hdl = F->read_handler;
|
||||||
|
data = F->read_data;
|
||||||
|
F->read_handler = NULL;
|
||||||
|
F->read_data = NULL;
|
||||||
|
if(hdl)
|
||||||
|
hdl(F, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(IsFDOpen(F) && (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)))
|
||||||
|
{
|
||||||
|
hdl = F->write_handler;
|
||||||
|
data = F->write_data;
|
||||||
|
F->write_handler = NULL;
|
||||||
|
F->write_data = NULL;
|
||||||
|
if(hdl)
|
||||||
|
hdl(F, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(F->read_handler == NULL)
|
||||||
|
rb_setselect_poll(F, RB_SELECT_READ, NULL, NULL);
|
||||||
|
if(F->write_handler == NULL)
|
||||||
|
rb_setselect_poll(F, RB_SELECT_WRITE, NULL, NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* poll not supported */
|
||||||
|
int
|
||||||
|
rb_init_netio_poll(void)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_setselect_poll(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_poll(long delay)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_poll(rb_fde_t * F)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
193
libratbox/src/ports.c
Normal file
193
libratbox/src/ports.c
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* ports.c: Solaris ports compatible network routines.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
|
||||||
|
* Copyright (C) 2002-2004 ircd-ratbox development team
|
||||||
|
* Copyright (C) 2005 Edward Brocklesby.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: ports.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <commio-int.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_PORT_H) && (HAVE_PORT_CREATE)
|
||||||
|
|
||||||
|
#include <port.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define PE_LENGTH 128
|
||||||
|
|
||||||
|
static void pe_update_events(rb_fde_t *, short, PF *);
|
||||||
|
static int pe;
|
||||||
|
static struct timespec zero_timespec;
|
||||||
|
|
||||||
|
static port_event_t *pelst; /* port buffer */
|
||||||
|
static int pemax; /* max structs to buffer */
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_ports(int fd)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
pe_update_events(rb_fde_t * F, short filter, PF * handler)
|
||||||
|
{
|
||||||
|
PF *cur_handler = NULL;
|
||||||
|
|
||||||
|
if (filter == POLLRDNORM)
|
||||||
|
cur_handler = F->read_handler;
|
||||||
|
else if (filter == POLLWRNORM)
|
||||||
|
cur_handler = F->write_handler;
|
||||||
|
|
||||||
|
if (!cur_handler && handler)
|
||||||
|
port_associate(pe, PORT_SOURCE_FD, F->fd, filter, F);
|
||||||
|
else if (cur_handler && !handler)
|
||||||
|
port_dissociate(pe, PORT_SOURCE_FD, F->fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
|
||||||
|
/* Public functions */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_init_netio
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to initialise
|
||||||
|
* the network loop code.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rb_init_netio_ports(void)
|
||||||
|
{
|
||||||
|
if((pe = port_create()) < 0) {
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
pemax = getdtablesize();
|
||||||
|
pelst = rb_malloc(sizeof(port_event_t) * pemax);
|
||||||
|
zero_timespec.tv_sec = 0;
|
||||||
|
zero_timespec.tv_nsec = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_setselect
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to register
|
||||||
|
* and deregister interest in a pending IO state for a given FD.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler,
|
||||||
|
void *client_data)
|
||||||
|
{
|
||||||
|
lrb_assert(IsFDOpen(F));
|
||||||
|
|
||||||
|
/* Update the list, even though we're not using it .. */
|
||||||
|
if(type & RB_SELECT_READ) {
|
||||||
|
pe_update_events(F, POLLRDNORM, handler);
|
||||||
|
F->read_handler = handler;
|
||||||
|
F->read_data = client_data;
|
||||||
|
}
|
||||||
|
if(type & RB_SELECT_WRITE) {
|
||||||
|
pe_update_events(F, POLLWRNORM, handler);
|
||||||
|
F->write_handler = handler;
|
||||||
|
F->write_data = client_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_select
|
||||||
|
*
|
||||||
|
* Called to do the new-style IO, courtesy of squid (like most of this
|
||||||
|
* new IO code). This routine handles the stuff we've hidden in
|
||||||
|
* rb_setselect and fd_table[] and calls callbacks for IO ready
|
||||||
|
* events.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_ports(long delay)
|
||||||
|
{
|
||||||
|
int i, fd;
|
||||||
|
uint nget = 1;
|
||||||
|
struct timespec poll_time;
|
||||||
|
struct timer_data *tdata;
|
||||||
|
|
||||||
|
poll_time.tv_sec = delay / 1000;
|
||||||
|
poll_time.tv_nsec = (delay % 1000) * 1000000;
|
||||||
|
|
||||||
|
i = port_getn(pe, pelst, pemax, &nget, &poll_time);
|
||||||
|
rb_set_time();
|
||||||
|
|
||||||
|
if (i == -1)
|
||||||
|
return RB_OK;
|
||||||
|
|
||||||
|
for (i = 0; i < nget; i++) {
|
||||||
|
switch(pelst[i].portev_source) {
|
||||||
|
case PORT_SOURCE_FD:
|
||||||
|
fd = pelst[i].portev_object;
|
||||||
|
PF *hdl = NULL;
|
||||||
|
rb_fde_t *F = rb_find_fd(fd);
|
||||||
|
|
||||||
|
if ((pelst[i].portev_events & POLLRDNORM) && (hdl = F->read_handler)) {
|
||||||
|
F->read_handler = NULL;
|
||||||
|
hdl(F, F->read_data);
|
||||||
|
}
|
||||||
|
if ((pelst[i].portev_events & POLLWRNORM) && (hdl = F->write_handler)) {
|
||||||
|
F->write_handler = NULL;
|
||||||
|
hdl(F, F->write_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ports not supported */
|
||||||
|
int
|
||||||
|
rb_init_netio_ports(void)
|
||||||
|
{
|
||||||
|
return ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_setselect_ports(rb_fde_t *F, unsigned int type, PF * handler, void *client_data)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_ports(long delay)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_ports(rb_fde_t *F)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
406
libratbox/src/ratbox_lib.c
Normal file
406
libratbox/src/ratbox_lib.c
Normal file
|
@ -0,0 +1,406 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* ratbox_lib.c: libircd initialization functions at the like
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005,2006 ircd-ratbox development team
|
||||||
|
* Copyright (C) 2005,2006 Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: ratbox_lib.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <commio-int.h>
|
||||||
|
|
||||||
|
static log_cb *rb_log;
|
||||||
|
static restart_cb *rb_restart;
|
||||||
|
static die_cb *rb_die;
|
||||||
|
|
||||||
|
static struct timeval rb_time;
|
||||||
|
static char errbuf[512];
|
||||||
|
|
||||||
|
/* this doesn't do locales...oh well i guess */
|
||||||
|
|
||||||
|
static const char *months[] = {
|
||||||
|
"January", "February", "March", "April",
|
||||||
|
"May", "June", "July", "August",
|
||||||
|
"September", "October", "November", "December"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *weekdays[] = {
|
||||||
|
"Sunday", "Monday", "Tuesday", "Wednesday",
|
||||||
|
"Thursday", "Friday", "Saturday"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *s_month[] = {
|
||||||
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
|
||||||
|
"Aug", "Sep", "Oct", "Nov", "Dec"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *s_weekdays[] = {
|
||||||
|
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
||||||
|
};
|
||||||
|
|
||||||
|
char *
|
||||||
|
rb_ctime(const time_t t, char *buf, size_t len)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
struct tm *tp;
|
||||||
|
static char timex[128];
|
||||||
|
size_t tlen;
|
||||||
|
#if defined(HAVE_GMTIME_R)
|
||||||
|
struct tm tmr;
|
||||||
|
tp = gmtime_r(&t, &tmr);
|
||||||
|
#else
|
||||||
|
tp = gmtime(&t);
|
||||||
|
#endif
|
||||||
|
if(unlikely(tp == NULL))
|
||||||
|
{
|
||||||
|
strcpy(buf, "");
|
||||||
|
return(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(buf == NULL)
|
||||||
|
{
|
||||||
|
p = timex;
|
||||||
|
tlen = sizeof(timex);
|
||||||
|
} else {
|
||||||
|
p = buf;
|
||||||
|
tlen = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_snprintf(p, tlen, "%s %s %d %02u:%02u:%02u %d",
|
||||||
|
s_weekdays[tp->tm_wday], s_month[tp->tm_mon],
|
||||||
|
tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec,
|
||||||
|
tp->tm_year + 1900);
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* I hate this..but its sort of ircd standard now.. */
|
||||||
|
char *
|
||||||
|
rb_date(const time_t t, char *buf, size_t len)
|
||||||
|
{
|
||||||
|
struct tm *gm;
|
||||||
|
#if defined(HAVE_GMTIME_R)
|
||||||
|
struct tm gmbuf;
|
||||||
|
gm = gmtime_r(&t, &gmbuf);
|
||||||
|
#else
|
||||||
|
gm = gmtime(&t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(unlikely(gm == NULL))
|
||||||
|
{
|
||||||
|
rb_strlcpy(buf, "", len);
|
||||||
|
return(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_snprintf(buf, len, "%s %s %d %d -- %02u:%02u:%02u +00:00",
|
||||||
|
weekdays[gm->tm_wday], months[gm->tm_mon], gm->tm_mday,
|
||||||
|
gm->tm_year + 1900, gm->tm_hour, gm->tm_min, gm->tm_sec);
|
||||||
|
return(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t
|
||||||
|
rb_current_time(void)
|
||||||
|
{
|
||||||
|
return rb_time.tv_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct timeval *
|
||||||
|
rb_current_time_tv(void)
|
||||||
|
{
|
||||||
|
return &rb_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_lib_log(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
if(rb_log == NULL)
|
||||||
|
return;
|
||||||
|
va_start(args, format);
|
||||||
|
rb_vsnprintf(errbuf, sizeof(errbuf), format, args);
|
||||||
|
va_end(args);
|
||||||
|
rb_log(errbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_lib_die(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
if(rb_die == NULL)
|
||||||
|
abort();
|
||||||
|
va_start(args, format);
|
||||||
|
rb_vsnprintf(errbuf, sizeof(errbuf), format, args);
|
||||||
|
va_end(args);
|
||||||
|
rb_die(errbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_lib_restart(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
if(rb_restart == NULL)
|
||||||
|
abort();
|
||||||
|
va_start(args, format);
|
||||||
|
rb_vsnprintf(errbuf, sizeof(errbuf), format, args);
|
||||||
|
va_end(args);
|
||||||
|
rb_restart(errbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_set_time(void)
|
||||||
|
{
|
||||||
|
struct timeval newtime;
|
||||||
|
|
||||||
|
if(unlikely(rb_gettimeofday(&newtime, NULL) == -1))
|
||||||
|
{
|
||||||
|
rb_lib_log("Clock Failure (%s)", strerror(errno));
|
||||||
|
rb_lib_restart("Clock Failure");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newtime.tv_sec < rb_time.tv_sec)
|
||||||
|
rb_set_back_events(rb_time.tv_sec - newtime.tv_sec);
|
||||||
|
|
||||||
|
memcpy(&rb_time, &newtime, sizeof(struct timeval));
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
rb_lib_version(void)
|
||||||
|
{
|
||||||
|
static const char *id = "$Rev: 25038 $";
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_lib_init(log_cb *ilog, restart_cb *irestart, die_cb *idie, int closeall, int maxcon, size_t dh_size, size_t fd_heap_size)
|
||||||
|
{
|
||||||
|
rb_set_time();
|
||||||
|
rb_log = ilog;
|
||||||
|
rb_restart = irestart;
|
||||||
|
rb_die = idie;
|
||||||
|
rb_event_init();
|
||||||
|
rb_init_bh();
|
||||||
|
rb_fdlist_init(closeall, maxcon, fd_heap_size);
|
||||||
|
rb_init_netio();
|
||||||
|
rb_init_rb_dlink_nodes(dh_size);
|
||||||
|
if(rb_io_supports_event())
|
||||||
|
{
|
||||||
|
rb_io_init_event();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_lib_loop(long delay)
|
||||||
|
{
|
||||||
|
time_t next;
|
||||||
|
rb_set_time();
|
||||||
|
|
||||||
|
if(rb_io_supports_event())
|
||||||
|
{
|
||||||
|
if(delay == 0)
|
||||||
|
delay = -1;
|
||||||
|
while(1)
|
||||||
|
rb_select(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(delay == 0)
|
||||||
|
{
|
||||||
|
if((next = rb_event_next()) > 0)
|
||||||
|
{
|
||||||
|
next -= rb_current_time();
|
||||||
|
if(next <= 0)
|
||||||
|
next = 1000;
|
||||||
|
else
|
||||||
|
next *= 1000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
next = -1;
|
||||||
|
rb_select(next);
|
||||||
|
} else
|
||||||
|
rb_select(delay);
|
||||||
|
rb_event_run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_STRTOK_R
|
||||||
|
char *
|
||||||
|
rb_strtok_r (char *s, const char *delim, char **save)
|
||||||
|
{
|
||||||
|
char *token;
|
||||||
|
|
||||||
|
if (s == NULL)
|
||||||
|
s = *save;
|
||||||
|
|
||||||
|
/* Scan leading delimiters. */
|
||||||
|
s += strspn(s, delim);
|
||||||
|
|
||||||
|
if (*s == '\0')
|
||||||
|
{
|
||||||
|
*save = s;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
token = s;
|
||||||
|
s = strpbrk(token, delim);
|
||||||
|
|
||||||
|
if (s == NULL)
|
||||||
|
*save = (token + strlen(token));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*s = '\0';
|
||||||
|
*save = s + 1;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
char
|
||||||
|
*rb_strtok_r(char *s, const char *delim, char **save)
|
||||||
|
{
|
||||||
|
return strtok_r(s, delim, save);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static const char base64_table[] =
|
||||||
|
{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||||
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||||
|
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char base64_pad = '=';
|
||||||
|
|
||||||
|
static const short base64_reverse_table[256] = {
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
|
||||||
|
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||||
|
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
||||||
|
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||||
|
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned char *
|
||||||
|
rb_base64_encode(const unsigned char *str, int length)
|
||||||
|
{
|
||||||
|
const unsigned char *current = str;
|
||||||
|
unsigned char *p;
|
||||||
|
unsigned char *result;
|
||||||
|
|
||||||
|
if ((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = rb_malloc(((length + 2) / 3) * 5);
|
||||||
|
p = result;
|
||||||
|
|
||||||
|
while (length > 2)
|
||||||
|
{
|
||||||
|
*p++ = base64_table[current[0] >> 2];
|
||||||
|
*p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
|
||||||
|
*p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
|
||||||
|
*p++ = base64_table[current[2] & 0x3f];
|
||||||
|
|
||||||
|
current += 3;
|
||||||
|
length -= 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length != 0) {
|
||||||
|
*p++ = base64_table[current[0] >> 2];
|
||||||
|
if (length > 1) {
|
||||||
|
*p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
|
||||||
|
*p++ = base64_table[(current[1] & 0x0f) << 2];
|
||||||
|
*p++ = base64_pad;
|
||||||
|
} else {
|
||||||
|
*p++ = base64_table[(current[0] & 0x03) << 4];
|
||||||
|
*p++ = base64_pad;
|
||||||
|
*p++ = base64_pad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *
|
||||||
|
rb_base64_decode(const unsigned char *str, int length, int *ret)
|
||||||
|
{
|
||||||
|
const unsigned char *current = str;
|
||||||
|
int ch, i = 0, j = 0, k;
|
||||||
|
unsigned char *result;
|
||||||
|
|
||||||
|
result = rb_malloc(length + 1);
|
||||||
|
|
||||||
|
while ((ch = *current++) != '\0' && length-- > 0) {
|
||||||
|
if (ch == base64_pad) break;
|
||||||
|
|
||||||
|
ch = base64_reverse_table[ch];
|
||||||
|
if (ch < 0) continue;
|
||||||
|
|
||||||
|
switch(i % 4) {
|
||||||
|
case 0:
|
||||||
|
result[j] = ch << 2;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result[j++] |= ch >> 4;
|
||||||
|
result[j] = (ch & 0x0f) << 4;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result[j++] |= ch >>2;
|
||||||
|
result[j] = (ch & 0x03) << 6;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result[j++] |= ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
k = j;
|
||||||
|
|
||||||
|
if (ch == base64_pad) {
|
||||||
|
switch(i % 4) {
|
||||||
|
case 1:
|
||||||
|
free(result);
|
||||||
|
return NULL;
|
||||||
|
case 2:
|
||||||
|
k++;
|
||||||
|
case 3:
|
||||||
|
result[k++] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result[j] = '\0';
|
||||||
|
*ret = j;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
302
libratbox/src/rawbuf.c
Normal file
302
libratbox/src/rawbuf.c
Normal file
|
@ -0,0 +1,302 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slight useful ircd
|
||||||
|
* rawbuf.c: raw buffer (non-line oriented buffering)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
* Copyright (C) 2007 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <commio-int.h>
|
||||||
|
#define RAWBUF_SIZE 1024
|
||||||
|
|
||||||
|
struct _rawbuf
|
||||||
|
{
|
||||||
|
rb_dlink_node node;
|
||||||
|
rb_uint8_t data[RAWBUF_SIZE];
|
||||||
|
int len;
|
||||||
|
rb_uint8_t flushing;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _rawbuf_head
|
||||||
|
{
|
||||||
|
rb_dlink_list list;
|
||||||
|
int len;
|
||||||
|
int written;
|
||||||
|
};
|
||||||
|
|
||||||
|
static rb_bh *rawbuf_heap;
|
||||||
|
|
||||||
|
|
||||||
|
static rawbuf_t *
|
||||||
|
rb_rawbuf_alloc(void)
|
||||||
|
{
|
||||||
|
rawbuf_t *t;
|
||||||
|
t = rb_bh_alloc(rawbuf_heap);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rawbuf_t *
|
||||||
|
rb_rawbuf_newbuf(rawbuf_head_t * rb)
|
||||||
|
{
|
||||||
|
rawbuf_t *buf;
|
||||||
|
buf = rb_rawbuf_alloc();
|
||||||
|
rb_dlinkAddTail(buf, &buf->node, &rb->list);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rb_rawbuf_done(rawbuf_head_t * rb, rawbuf_t * buf)
|
||||||
|
{
|
||||||
|
rawbuf_t *ptr = buf;
|
||||||
|
rb_dlinkDelete(&buf->node, &rb->list);
|
||||||
|
rb_bh_free(rawbuf_heap, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rb_rawbuf_flush_writev(rawbuf_head_t * rb, rb_fde_t *F)
|
||||||
|
{
|
||||||
|
rb_dlink_node *ptr, *next;
|
||||||
|
rawbuf_t *buf;
|
||||||
|
int x = 0, y = 0;
|
||||||
|
int xret, retval;
|
||||||
|
struct rb_iovec vec[RB_UIO_MAXIOV];
|
||||||
|
memset(vec, 0, sizeof(vec));
|
||||||
|
|
||||||
|
if(rb->list.head == NULL)
|
||||||
|
{
|
||||||
|
errno = EAGAIN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
RB_DLINK_FOREACH(ptr, rb->list.head)
|
||||||
|
{
|
||||||
|
if(x >= RB_UIO_MAXIOV)
|
||||||
|
break;
|
||||||
|
|
||||||
|
buf = ptr->data;
|
||||||
|
if(buf->flushing)
|
||||||
|
{
|
||||||
|
vec[x].iov_base = buf->data + rb->written;
|
||||||
|
vec[x++].iov_len = buf->len - rb->written;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
vec[x].iov_base = buf->data;
|
||||||
|
vec[x++].iov_len = buf->len;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(x == 0)
|
||||||
|
{
|
||||||
|
errno = EAGAIN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
xret = retval = rb_writev(F, vec, x);
|
||||||
|
if(retval <= 0)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
RB_DLINK_FOREACH_SAFE(ptr, next, rb->list.head)
|
||||||
|
{
|
||||||
|
buf = ptr->data;
|
||||||
|
if(y++ >= x)
|
||||||
|
break;
|
||||||
|
if(buf->flushing)
|
||||||
|
{
|
||||||
|
if(xret >= buf->len - rb->written)
|
||||||
|
{
|
||||||
|
xret -= buf->len - rb->written;
|
||||||
|
rb->len -= buf->len - rb->written;
|
||||||
|
rb_rawbuf_done(rb, buf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(xret >= buf->len)
|
||||||
|
{
|
||||||
|
xret -= buf->len;
|
||||||
|
rb->len -= buf->len;
|
||||||
|
rb_rawbuf_done(rb, buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf->flushing = 1;
|
||||||
|
rb->written = xret;
|
||||||
|
rb->len -= xret;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_rawbuf_flush(rawbuf_head_t * rb, rb_fde_t *F)
|
||||||
|
{
|
||||||
|
rawbuf_t *buf;
|
||||||
|
int retval;
|
||||||
|
if(rb->list.head == NULL)
|
||||||
|
{
|
||||||
|
errno = EAGAIN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!rb_fd_ssl(F))
|
||||||
|
return rb_rawbuf_flush_writev(rb, F);
|
||||||
|
|
||||||
|
buf = rb->list.head->data;
|
||||||
|
if(!buf->flushing)
|
||||||
|
{
|
||||||
|
buf->flushing = 1;
|
||||||
|
rb->written = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = rb_write(F, buf->data + rb->written, buf->len - rb->written);
|
||||||
|
if(retval <= 0)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
rb->written += retval;
|
||||||
|
if(rb->written == buf->len)
|
||||||
|
{
|
||||||
|
rb->written = 0;
|
||||||
|
rb_dlinkDelete(&buf->node, &rb->list);
|
||||||
|
rb_bh_free(rawbuf_heap, buf);
|
||||||
|
}
|
||||||
|
rb->len -= retval;
|
||||||
|
lrb_assert(rb->len >= 0);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_rawbuf_append(rawbuf_head_t * rb, void *data, int len)
|
||||||
|
{
|
||||||
|
rawbuf_t *buf = NULL;
|
||||||
|
int clen;
|
||||||
|
void *ptr;
|
||||||
|
if(rb->list.tail != NULL)
|
||||||
|
buf = rb->list.tail->data;
|
||||||
|
|
||||||
|
if(buf != NULL && buf->len < RAWBUF_SIZE && !buf->flushing)
|
||||||
|
{
|
||||||
|
buf = (rawbuf_t *) rb->list.tail->data;
|
||||||
|
clen = RAWBUF_SIZE - buf->len;
|
||||||
|
ptr = (void *) (buf->data + buf->len);
|
||||||
|
if(len < clen)
|
||||||
|
clen = len;
|
||||||
|
|
||||||
|
memcpy(ptr, data, clen);
|
||||||
|
buf->len += clen;
|
||||||
|
rb->len += clen;
|
||||||
|
len -= clen;
|
||||||
|
if(len == 0)
|
||||||
|
return;
|
||||||
|
data += clen;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
buf = rb_rawbuf_newbuf(rb);
|
||||||
|
|
||||||
|
if(len >= RAWBUF_SIZE)
|
||||||
|
clen = RAWBUF_SIZE;
|
||||||
|
else
|
||||||
|
clen = len;
|
||||||
|
|
||||||
|
memcpy(buf->data, data, clen);
|
||||||
|
buf->len += clen;
|
||||||
|
len -= clen;
|
||||||
|
data += clen;
|
||||||
|
rb->len += clen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_rawbuf_get(rawbuf_head_t * rb, void *data, int len)
|
||||||
|
{
|
||||||
|
rawbuf_t *buf;
|
||||||
|
int cpylen;
|
||||||
|
void *ptr;
|
||||||
|
if(rb->list.head == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
buf = rb->list.head->data;
|
||||||
|
|
||||||
|
if(buf->flushing)
|
||||||
|
ptr = (void *) (buf->data + rb->written);
|
||||||
|
else
|
||||||
|
ptr = buf->data;
|
||||||
|
|
||||||
|
if(len > buf->len)
|
||||||
|
cpylen = buf->len;
|
||||||
|
else
|
||||||
|
cpylen = len;
|
||||||
|
|
||||||
|
memcpy(data, ptr, cpylen);
|
||||||
|
|
||||||
|
if(cpylen == buf->len)
|
||||||
|
{
|
||||||
|
rb->written = 0;
|
||||||
|
rb_rawbuf_done(rb, buf);
|
||||||
|
rb->len -= len;
|
||||||
|
return cpylen;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->flushing = 1;
|
||||||
|
buf->len -= cpylen;
|
||||||
|
rb->len -= cpylen;
|
||||||
|
rb->written += cpylen;
|
||||||
|
return cpylen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_rawbuf_length(rawbuf_head_t * rb)
|
||||||
|
{
|
||||||
|
if(rb_dlink_list_length(&rb->list) == 0 && rb->len != 0)
|
||||||
|
lrb_assert(1 == 0);
|
||||||
|
return rb->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
rawbuf_head_t *
|
||||||
|
rb_new_rawbuffer(void)
|
||||||
|
{
|
||||||
|
return rb_malloc(sizeof(rawbuf_head_t));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_free_rawbuffer(rawbuf_head_t * rb)
|
||||||
|
{
|
||||||
|
rb_dlink_node *ptr, *next;
|
||||||
|
RB_DLINK_FOREACH_SAFE(ptr, next, rb->list.head)
|
||||||
|
{
|
||||||
|
rb_rawbuf_done(rb, ptr->data);
|
||||||
|
}
|
||||||
|
rb_free(rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_init_rawbuffers(int heap_size)
|
||||||
|
{
|
||||||
|
if(rawbuf_heap == NULL)
|
||||||
|
rawbuf_heap = rb_bh_create(sizeof(rawbuf_t), heap_size, "librb_rawbuf_heap");
|
||||||
|
}
|
42
libratbox/src/rb_memory.c
Normal file
42
libratbox/src/rb_memory.c
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* memory.c: Memory utilities.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: rb_memory.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_outofmemory(void)
|
||||||
|
{
|
||||||
|
static int was_here = 0;
|
||||||
|
|
||||||
|
if(was_here)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
was_here = 1;
|
||||||
|
|
||||||
|
rb_lib_log("Out of memory: restarting server...");
|
||||||
|
rb_lib_restart("Out of Memory");
|
||||||
|
}
|
||||||
|
|
264
libratbox/src/select.c
Normal file
264
libratbox/src/select.c
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* select.c: select() compatible network routines.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: select.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <commio-int.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_SELECT)
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Note that this is only a single list - multiple lists is kinda pointless
|
||||||
|
* under select because the list size is a function of the highest FD :-)
|
||||||
|
* -- adrian
|
||||||
|
*/
|
||||||
|
|
||||||
|
static fd_set select_readfds;
|
||||||
|
static fd_set select_writefds;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* You know, I'd rather have these local to rb_select but for some
|
||||||
|
* reason my gcc decides that I can't modify them at all..
|
||||||
|
* -- adrian
|
||||||
|
*/
|
||||||
|
static fd_set tmpreadfds;
|
||||||
|
static fd_set tmpwritefds;
|
||||||
|
|
||||||
|
static int rb_maxfd = -1;
|
||||||
|
static void select_update_selectfds(rb_fde_t *F, short event, PF * handler);
|
||||||
|
|
||||||
|
/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
|
||||||
|
/* Private functions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set and clear entries in the select array ..
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
select_update_selectfds(rb_fde_t *F, short event, PF * handler)
|
||||||
|
{
|
||||||
|
/* Update the read / write set */
|
||||||
|
if(event & RB_SELECT_READ)
|
||||||
|
{
|
||||||
|
if(handler)
|
||||||
|
{
|
||||||
|
FD_SET(F->fd, &select_readfds);
|
||||||
|
F->pflags |= RB_SELECT_READ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FD_CLR(F->fd, &select_readfds);
|
||||||
|
F->pflags &= ~RB_SELECT_READ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(event & RB_SELECT_WRITE)
|
||||||
|
{
|
||||||
|
if(handler)
|
||||||
|
{
|
||||||
|
FD_SET(F->fd, &select_writefds);
|
||||||
|
F->pflags |= RB_SELECT_WRITE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FD_CLR(F->fd, &select_writefds);
|
||||||
|
F->pflags &= ~RB_SELECT_WRITE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(F->pflags & (RB_SELECT_READ|RB_SELECT_WRITE))
|
||||||
|
{
|
||||||
|
if(F->fd > rb_maxfd)
|
||||||
|
{
|
||||||
|
rb_maxfd = F->fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(F->fd <= rb_maxfd)
|
||||||
|
{
|
||||||
|
while(rb_maxfd >= 0 && !FD_ISSET(rb_maxfd, &select_readfds) && !FD_ISSET(rb_maxfd, &select_writefds))
|
||||||
|
rb_maxfd--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
|
||||||
|
/* Public functions */
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_select(rb_fde_t *F)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_init_netio
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to initialise
|
||||||
|
* the network loop code.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rb_init_netio_select(void)
|
||||||
|
{
|
||||||
|
FD_ZERO(&select_readfds);
|
||||||
|
FD_ZERO(&select_writefds);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_setselect
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to register
|
||||||
|
* and deregister interest in a pending IO state for a given FD.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_setselect_select(rb_fde_t *F, unsigned int type, PF * handler,
|
||||||
|
void *client_data)
|
||||||
|
{
|
||||||
|
lrb_assert(IsFDOpen(F));
|
||||||
|
|
||||||
|
if(type & RB_SELECT_READ)
|
||||||
|
{
|
||||||
|
F->read_handler = handler;
|
||||||
|
F->read_data = client_data;
|
||||||
|
select_update_selectfds(F, RB_SELECT_READ, handler);
|
||||||
|
}
|
||||||
|
if(type & RB_SELECT_WRITE)
|
||||||
|
{
|
||||||
|
F->write_handler = handler;
|
||||||
|
F->write_data = client_data;
|
||||||
|
select_update_selectfds(F, RB_SELECT_WRITE, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check all connections for new connections and input data that is to be
|
||||||
|
* processed. Also check for connections with data queued and whether we can
|
||||||
|
* write it out.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_select
|
||||||
|
*
|
||||||
|
* Do IO events
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_select(long delay)
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
int fd;
|
||||||
|
PF *hdl;
|
||||||
|
rb_fde_t *F;
|
||||||
|
struct timeval to;
|
||||||
|
|
||||||
|
/* Copy over the read/write sets so we don't have to rebuild em */
|
||||||
|
memcpy(&tmpreadfds, &select_readfds, sizeof(fd_set));
|
||||||
|
memcpy(&tmpwritefds, &select_writefds, sizeof(fd_set));
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
to.tv_sec = 0;
|
||||||
|
to.tv_usec = delay * 1000;
|
||||||
|
num = select(rb_maxfd + 1, &tmpreadfds, &tmpwritefds, NULL, &to);
|
||||||
|
if(num >= 0)
|
||||||
|
break;
|
||||||
|
if(rb_ignore_errno(errno))
|
||||||
|
continue;
|
||||||
|
rb_set_time();
|
||||||
|
/* error! */
|
||||||
|
return -1;
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
rb_set_time();
|
||||||
|
|
||||||
|
if(num == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* XXX we *could* optimise by falling out after doing num fds ... */
|
||||||
|
for (fd = 0; fd < rb_maxfd + 1; fd++)
|
||||||
|
{
|
||||||
|
F = rb_find_fd(fd);
|
||||||
|
if(F == NULL)
|
||||||
|
continue;
|
||||||
|
if(FD_ISSET(fd, &tmpreadfds))
|
||||||
|
{
|
||||||
|
hdl = F->read_handler;
|
||||||
|
F->read_handler = NULL;
|
||||||
|
if(hdl)
|
||||||
|
hdl(F, F->read_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!IsFDOpen(F))
|
||||||
|
continue; /* Read handler closed us..go on */
|
||||||
|
|
||||||
|
if(FD_ISSET(fd, &tmpwritefds))
|
||||||
|
{
|
||||||
|
hdl = F->write_handler;
|
||||||
|
F->write_handler = NULL;
|
||||||
|
if(hdl)
|
||||||
|
hdl(F, F->write_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(F->read_handler == NULL)
|
||||||
|
select_update_selectfds(F, RB_SELECT_READ, NULL);
|
||||||
|
if(F->write_handler == NULL)
|
||||||
|
select_update_selectfds(F, RB_SELECT_WRITE, NULL);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* select not supported..what sort of garbage is this? */
|
||||||
|
int
|
||||||
|
rb_init_netio_select(void)
|
||||||
|
{
|
||||||
|
return ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_setselect_select(rb_fde_t *F, unsigned int type, PF * handler, void *client_data)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_select(long delay)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_select(rb_fde_t *F)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
509
libratbox/src/sigio.c
Normal file
509
libratbox/src/sigio.c
Normal file
|
@ -0,0 +1,509 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* sigio.c: Linux Realtime SIGIO compatible network routines.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
|
||||||
|
* Copyright (C) 2002 Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
* Copyright (C) 2002 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: sigio.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE 1 /* Needed for F_SETSIG */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <commio-int.h>
|
||||||
|
#include <event-int.h>
|
||||||
|
#include <fcntl.h> /* Yes this needs to be before the ifdef */
|
||||||
|
|
||||||
|
#if defined(HAVE_SYS_POLL_H) && (HAVE_POLL) && (F_SETSIG)
|
||||||
|
#define USING_SIGIO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USING_SIGIO
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
|
||||||
|
#if defined(USE_TIMER_CREATE)
|
||||||
|
#define SIGIO_SCHED_EVENT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RTSIGIO SIGRTMIN
|
||||||
|
#define RTSIGTIM (SIGRTMIN+1)
|
||||||
|
|
||||||
|
|
||||||
|
struct _pollfd_list
|
||||||
|
{
|
||||||
|
struct pollfd *pollfds;
|
||||||
|
int maxindex; /* highest FD number */
|
||||||
|
int allocated;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _pollfd_list pollfd_list_t;
|
||||||
|
|
||||||
|
pollfd_list_t pollfd_list;
|
||||||
|
static int can_do_event = 0;
|
||||||
|
static int sigio_is_screwed = 0; /* We overflowed our sigio queue */
|
||||||
|
static sigset_t our_sigset;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_init_netio
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to initialise
|
||||||
|
* the network loop code.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rb_init_netio_sigio(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
pollfd_list.pollfds = rb_malloc(rb_getmaxconnect() * (sizeof(struct pollfd)));
|
||||||
|
pollfd_list.allocated = rb_getmaxconnect();
|
||||||
|
for (fd = 0; fd < rb_getmaxconnect(); fd++)
|
||||||
|
{
|
||||||
|
pollfd_list.pollfds[fd].fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pollfd_list.maxindex = 0;
|
||||||
|
|
||||||
|
sigio_is_screwed = 1; /* Start off with poll first.. */
|
||||||
|
|
||||||
|
sigemptyset(&our_sigset);
|
||||||
|
sigaddset(&our_sigset, RTSIGIO);
|
||||||
|
sigaddset(&our_sigset, SIGIO);
|
||||||
|
#ifdef SIGIO_SCHED_EVENT
|
||||||
|
sigaddset(&our_sigset, RTSIGTIM);
|
||||||
|
#endif
|
||||||
|
sigprocmask(SIG_BLOCK, &our_sigset, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
resize_pollarray(int fd)
|
||||||
|
{
|
||||||
|
if(unlikely(fd >= pollfd_list.allocated))
|
||||||
|
{
|
||||||
|
int x, old_value = pollfd_list.allocated;
|
||||||
|
pollfd_list.allocated += 1024;
|
||||||
|
pollfd_list.pollfds =
|
||||||
|
rb_realloc(pollfd_list.pollfds,
|
||||||
|
pollfd_list.allocated * (sizeof(struct pollfd)));
|
||||||
|
memset(&pollfd_list.pollfds[old_value + 1], 0, sizeof(struct pollfd) * 1024);
|
||||||
|
for (x = old_value + 1; x < pollfd_list.allocated; x++)
|
||||||
|
{
|
||||||
|
pollfd_list.pollfds[x].fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void setup_sigio_fd(int fd)
|
||||||
|
*
|
||||||
|
* Input: File descriptor
|
||||||
|
* Output: None
|
||||||
|
* Side Effect: Sets the FD up for SIGIO
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_sigio(rb_fde_t * F)
|
||||||
|
{
|
||||||
|
int flags = 0;
|
||||||
|
int fd = F->fd;
|
||||||
|
flags = fcntl(fd, F_GETFL, 0);
|
||||||
|
if(flags == -1)
|
||||||
|
return 0;
|
||||||
|
/* if set async, clear it so we can reset it in the kernel :/ */
|
||||||
|
if(flags & O_ASYNC)
|
||||||
|
{
|
||||||
|
flags &= ~O_ASYNC;
|
||||||
|
fcntl(fd, F_SETFL, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
flags |= O_ASYNC | O_NONBLOCK;
|
||||||
|
|
||||||
|
if(fcntl(fd, F_SETFL, flags) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(fcntl(fd, F_SETSIG, RTSIGIO) == -1)
|
||||||
|
return 0;
|
||||||
|
if(fcntl(fd, F_SETOWN, getpid()) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_setselect
|
||||||
|
*
|
||||||
|
* This is a needed exported function which will be called to register
|
||||||
|
* and deregister interest in a pending IO state for a given FD.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_setselect_sigio(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
|
||||||
|
{
|
||||||
|
if(F == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(type & RB_SELECT_READ)
|
||||||
|
{
|
||||||
|
F->read_handler = handler;
|
||||||
|
F->read_data = client_data;
|
||||||
|
if(handler != NULL)
|
||||||
|
F->pflags |= POLLRDNORM;
|
||||||
|
else
|
||||||
|
F->pflags &= ~POLLRDNORM;
|
||||||
|
}
|
||||||
|
if(type & RB_SELECT_WRITE)
|
||||||
|
{
|
||||||
|
F->write_handler = handler;
|
||||||
|
F->write_data = client_data;
|
||||||
|
if(handler != NULL)
|
||||||
|
F->pflags |= POLLWRNORM;
|
||||||
|
else
|
||||||
|
F->pflags &= ~POLLWRNORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
resize_pollarray(F->fd);
|
||||||
|
|
||||||
|
if(F->pflags <= 0)
|
||||||
|
{
|
||||||
|
pollfd_list.pollfds[F->fd].events = 0;
|
||||||
|
pollfd_list.pollfds[F->fd].fd = -1;
|
||||||
|
if(F->fd == pollfd_list.maxindex)
|
||||||
|
{
|
||||||
|
while (pollfd_list.maxindex >= 0
|
||||||
|
&& pollfd_list.pollfds[pollfd_list.maxindex].fd == -1)
|
||||||
|
pollfd_list.maxindex--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pollfd_list.pollfds[F->fd].events = F->pflags;
|
||||||
|
pollfd_list.pollfds[F->fd].fd = F->fd;
|
||||||
|
if(F->fd > pollfd_list.maxindex)
|
||||||
|
pollfd_list.maxindex = F->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* int rb_select(long delay)
|
||||||
|
* Input: The maximum time to delay.
|
||||||
|
* Output: Returns -1 on error, 0 on success.
|
||||||
|
* Side-effects: Deregisters future interest in IO and calls the handlers
|
||||||
|
* if an event occurs for an FD.
|
||||||
|
* Comments: Check all connections for new connections and input data
|
||||||
|
* that is to be processed. Also check for connections with data queued
|
||||||
|
* and whether we can write it out.
|
||||||
|
* Called to do the new-style IO, courtesy of squid (like most of this
|
||||||
|
* new IO code). This routine handles the stuff we've hidden in
|
||||||
|
* rb_setselect and fd_table[] and calls callbacks for IO ready
|
||||||
|
* events.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rb_select_sigio(long delay)
|
||||||
|
{
|
||||||
|
int num = 0;
|
||||||
|
int revents = 0;
|
||||||
|
int sig;
|
||||||
|
int fd;
|
||||||
|
int ci;
|
||||||
|
PF *hdl;
|
||||||
|
rb_fde_t *F;
|
||||||
|
void *data;
|
||||||
|
struct siginfo si;
|
||||||
|
|
||||||
|
struct timespec timeout;
|
||||||
|
if(rb_sigio_supports_event() || delay >= 0)
|
||||||
|
{
|
||||||
|
timeout.tv_sec = (delay / 1000);
|
||||||
|
timeout.tv_nsec = (delay % 1000) * 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if(!sigio_is_screwed)
|
||||||
|
{
|
||||||
|
if(can_do_event || delay < 0)
|
||||||
|
{
|
||||||
|
sig = sigwaitinfo(&our_sigset, &si);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sig = sigtimedwait(&our_sigset, &si, &timeout);
|
||||||
|
|
||||||
|
if(sig > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(sig == SIGIO)
|
||||||
|
{
|
||||||
|
rb_lib_log
|
||||||
|
("Kernel RT Signal queue overflowed. Is ulimit -i too small(or perhaps /proc/sys/kernel/rtsig-max on old kernels)");
|
||||||
|
sigio_is_screwed = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef SIGIO_SCHED_EVENT
|
||||||
|
if(sig == RTSIGTIM && can_do_event)
|
||||||
|
{
|
||||||
|
struct ev_entry *ev = (struct ev_entry *) si.si_ptr;
|
||||||
|
if(ev == NULL)
|
||||||
|
continue;
|
||||||
|
rb_run_event(ev);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
fd = si.si_fd;
|
||||||
|
pollfd_list.pollfds[fd].revents |= si.si_band;
|
||||||
|
revents = pollfd_list.pollfds[fd].revents;
|
||||||
|
num++;
|
||||||
|
F = rb_find_fd(fd);
|
||||||
|
if(F == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
|
||||||
|
{
|
||||||
|
hdl = F->read_handler;
|
||||||
|
data = F->read_data;
|
||||||
|
F->read_handler = NULL;
|
||||||
|
F->read_data = NULL;
|
||||||
|
if(hdl)
|
||||||
|
hdl(F, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
|
||||||
|
{
|
||||||
|
hdl = F->write_handler;
|
||||||
|
data = F->write_data;
|
||||||
|
F->write_handler = NULL;
|
||||||
|
F->write_data = NULL;
|
||||||
|
if(hdl)
|
||||||
|
hdl(F, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!sigio_is_screwed) /* We don't need to proceed */
|
||||||
|
{
|
||||||
|
rb_set_time();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal(RTSIGIO, SIG_IGN);
|
||||||
|
signal(RTSIGIO, SIG_DFL);
|
||||||
|
sigio_is_screwed = 0;
|
||||||
|
|
||||||
|
|
||||||
|
num = poll(pollfd_list.pollfds, pollfd_list.maxindex + 1, delay);
|
||||||
|
rb_set_time();
|
||||||
|
if(num < 0)
|
||||||
|
{
|
||||||
|
if(!rb_ignore_errno(errno))
|
||||||
|
return RB_OK;
|
||||||
|
else
|
||||||
|
return RB_ERROR;
|
||||||
|
}
|
||||||
|
if(num == 0)
|
||||||
|
return RB_OK;
|
||||||
|
|
||||||
|
/* XXX we *could* optimise by falling out after doing num fds ... */
|
||||||
|
for (ci = 0; ci < pollfd_list.maxindex + 1; ci++)
|
||||||
|
{
|
||||||
|
if(((revents = pollfd_list.pollfds[ci].revents) == 0)
|
||||||
|
|| (pollfd_list.pollfds[ci].fd) == -1)
|
||||||
|
continue;
|
||||||
|
fd = pollfd_list.pollfds[ci].fd;
|
||||||
|
F = rb_find_fd(fd);
|
||||||
|
if(F == NULL)
|
||||||
|
continue;
|
||||||
|
if(revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
|
||||||
|
{
|
||||||
|
hdl = F->read_handler;
|
||||||
|
data = F->read_data;
|
||||||
|
F->read_handler = NULL;
|
||||||
|
F->read_data = NULL;
|
||||||
|
if(hdl)
|
||||||
|
hdl(F, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(IsFDOpen(F) && (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)))
|
||||||
|
{
|
||||||
|
hdl = F->write_handler;
|
||||||
|
data = F->write_data;
|
||||||
|
F->write_handler = NULL;
|
||||||
|
F->write_data = NULL;
|
||||||
|
if(hdl)
|
||||||
|
hdl(F, data);
|
||||||
|
}
|
||||||
|
if(F->read_handler == NULL)
|
||||||
|
rb_setselect_sigio(F, RB_SELECT_READ, NULL, NULL);
|
||||||
|
if(F->write_handler == NULL)
|
||||||
|
rb_setselect_sigio(F, RB_SELECT_WRITE, NULL, NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(SIGIO_SCHED_EVENT)
|
||||||
|
void
|
||||||
|
rb_sigio_init_event(void)
|
||||||
|
{
|
||||||
|
rb_sigio_supports_event();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_sigio_supports_event(void)
|
||||||
|
{
|
||||||
|
timer_t timer;
|
||||||
|
struct sigevent ev;
|
||||||
|
if(can_do_event == 1)
|
||||||
|
return 1;
|
||||||
|
if(can_do_event == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ev.sigev_signo = SIGVTALRM;
|
||||||
|
ev.sigev_notify = SIGEV_SIGNAL;
|
||||||
|
if(timer_create(CLOCK_REALTIME, &ev, &timer) != 0)
|
||||||
|
{
|
||||||
|
can_do_event = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
timer_delete(timer);
|
||||||
|
can_do_event = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_sigio_sched_event(struct ev_entry *event, int when)
|
||||||
|
{
|
||||||
|
timer_t *id;
|
||||||
|
struct sigevent ev;
|
||||||
|
struct itimerspec ts;
|
||||||
|
if(can_do_event <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memset(&ev, 0, sizeof(&ev));
|
||||||
|
event->comm_ptr = rb_malloc(sizeof(timer_t));
|
||||||
|
id = event->comm_ptr;
|
||||||
|
ev.sigev_notify = SIGEV_SIGNAL;
|
||||||
|
ev.sigev_signo = RTSIGTIM;
|
||||||
|
ev.sigev_value.sival_ptr = event;
|
||||||
|
|
||||||
|
if(timer_create(CLOCK_REALTIME, &ev, id) < 0)
|
||||||
|
{
|
||||||
|
rb_lib_log("timer_create: %s\n", strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(&ts, 0, sizeof(ts));
|
||||||
|
ts.it_value.tv_sec = when;
|
||||||
|
ts.it_value.tv_nsec = 0;
|
||||||
|
if(event->frequency != 0)
|
||||||
|
ts.it_interval = ts.it_value;
|
||||||
|
|
||||||
|
if(timer_settime(*id, 0, &ts, NULL) < 0)
|
||||||
|
{
|
||||||
|
rb_lib_log("timer_settime: %s\n", strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_sigio_unsched_event(struct ev_entry *event)
|
||||||
|
{
|
||||||
|
if(can_do_event <= 0)
|
||||||
|
return;
|
||||||
|
timer_delete(*((timer_t *) event->comm_ptr));
|
||||||
|
rb_free(event->comm_ptr);
|
||||||
|
event->comm_ptr = NULL;
|
||||||
|
}
|
||||||
|
#endif /* SIGIO_SCHED_EVENT */
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_init_netio_sigio(void)
|
||||||
|
{
|
||||||
|
return ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_setselect_sigio(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_sigio(long delay)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_sigio(rb_fde_t * F)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(USING_SIGIO) || !defined(SIGIO_SCHED_EVENT)
|
||||||
|
void
|
||||||
|
rb_sigio_init_event(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_sigio_sched_event(struct ev_entry *event, int when)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_sigio_unsched_event(struct ev_entry *event)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_sigio_supports_event(void)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* !USING_SIGIO || !SIGIO_SCHED_EVENT */
|
633
libratbox/src/snprintf.c
Normal file
633
libratbox/src/snprintf.c
Normal file
|
@ -0,0 +1,633 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Modified and hacked into libratbox by Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
* The original headers are below..
|
||||||
|
* Note that this implementation does not process floating point numbers so
|
||||||
|
* you will likely need to fall back to using sprintf yourself to do those...
|
||||||
|
* $Id: snprintf.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* linux/lib/vsprintf.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
|
||||||
|
/*
|
||||||
|
* Wirzenius wrote this portably, Torvalds fucked it up :-)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
|
||||||
|
* - changed to provide snprintf and vsnprintf functions
|
||||||
|
* So Feb 1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de>
|
||||||
|
* - scnprintf and vscnprintf
|
||||||
|
*/
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
|
||||||
|
static int skip_atoi(const char **s)
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
while (isdigit(**s))
|
||||||
|
i = i*10 + *((*s)++) - '0';
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decimal conversion is by far the most typical, and is used
|
||||||
|
* for /proc and /sys data. This directly impacts e.g. top performance
|
||||||
|
* with many processes running. We optimize it for speed
|
||||||
|
* using code from
|
||||||
|
* http://www.cs.uiowa.edu/~jones/bcd/decimal.html
|
||||||
|
* (with permission from the author, Douglas W. Jones). */
|
||||||
|
|
||||||
|
/* Formats correctly any integer in [0,99999].
|
||||||
|
* Outputs from one to five digits depending on input.
|
||||||
|
* On i386 gcc 4.1.2 -O2: ~250 bytes of code. */
|
||||||
|
static char* put_dec_trunc(char *buf, unsigned q)
|
||||||
|
{
|
||||||
|
unsigned d3, d2, d1, d0;
|
||||||
|
d1 = (q>>4) & 0xf;
|
||||||
|
d2 = (q>>8) & 0xf;
|
||||||
|
d3 = (q>>12);
|
||||||
|
|
||||||
|
d0 = 6*(d3 + d2 + d1) + (q & 0xf);
|
||||||
|
q = (d0 * 0xcd) >> 11;
|
||||||
|
d0 = d0 - 10*q;
|
||||||
|
*buf++ = d0 + '0'; /* least significant digit */
|
||||||
|
d1 = q + 9*d3 + 5*d2 + d1;
|
||||||
|
if (d1 != 0) {
|
||||||
|
q = (d1 * 0xcd) >> 11;
|
||||||
|
d1 = d1 - 10*q;
|
||||||
|
*buf++ = d1 + '0'; /* next digit */
|
||||||
|
|
||||||
|
d2 = q + 2*d2;
|
||||||
|
if ((d2 != 0) || (d3 != 0)) {
|
||||||
|
q = (d2 * 0xd) >> 7;
|
||||||
|
d2 = d2 - 10*q;
|
||||||
|
*buf++ = d2 + '0'; /* next digit */
|
||||||
|
|
||||||
|
d3 = q + 4*d3;
|
||||||
|
if (d3 != 0) {
|
||||||
|
q = (d3 * 0xcd) >> 11;
|
||||||
|
d3 = d3 - 10*q;
|
||||||
|
*buf++ = d3 + '0'; /* next digit */
|
||||||
|
if (q != 0)
|
||||||
|
*buf++ = q + '0'; /* most sign. digit */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
/* Same with if's removed. Always emits five digits */
|
||||||
|
static char* put_dec_full(char *buf, unsigned q)
|
||||||
|
{
|
||||||
|
/* BTW, if q is in [0,9999], 8-bit ints will be enough, */
|
||||||
|
/* but anyway, gcc produces better code with full-sized ints */
|
||||||
|
unsigned d3, d2, d1, d0;
|
||||||
|
d1 = (q>>4) & 0xf;
|
||||||
|
d2 = (q>>8) & 0xf;
|
||||||
|
d3 = (q>>12);
|
||||||
|
|
||||||
|
/* Possible ways to approx. divide by 10 */
|
||||||
|
/* gcc -O2 replaces multiply with shifts and adds */
|
||||||
|
// (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386)
|
||||||
|
// (x * 0x67) >> 10: 1100111
|
||||||
|
// (x * 0x34) >> 9: 110100 - same
|
||||||
|
// (x * 0x1a) >> 8: 11010 - same
|
||||||
|
// (x * 0x0d) >> 7: 1101 - same, shortest code (on i386)
|
||||||
|
|
||||||
|
d0 = 6*(d3 + d2 + d1) + (q & 0xf);
|
||||||
|
q = (d0 * 0xcd) >> 11;
|
||||||
|
d0 = d0 - 10*q;
|
||||||
|
*buf++ = d0 + '0';
|
||||||
|
d1 = q + 9*d3 + 5*d2 + d1;
|
||||||
|
q = (d1 * 0xcd) >> 11;
|
||||||
|
d1 = d1 - 10*q;
|
||||||
|
*buf++ = d1 + '0';
|
||||||
|
|
||||||
|
d2 = q + 2*d2;
|
||||||
|
q = (d2 * 0xd) >> 7;
|
||||||
|
d2 = d2 - 10*q;
|
||||||
|
*buf++ = d2 + '0';
|
||||||
|
|
||||||
|
d3 = q + 4*d3;
|
||||||
|
q = (d3 * 0xcd) >> 11; /* - shorter code */
|
||||||
|
/* q = (d3 * 0x67) >> 10; - would also work */
|
||||||
|
d3 = d3 - 10*q;
|
||||||
|
*buf++ = d3 + '0';
|
||||||
|
*buf++ = q + '0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* put_dec(char *buf, unsigned long long int num)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
unsigned rem;
|
||||||
|
if (num < 100000)
|
||||||
|
return put_dec_trunc(buf, num);
|
||||||
|
rem = num % 100000;
|
||||||
|
num = num / 100000;
|
||||||
|
buf = put_dec_full(buf, rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZEROPAD 1 /* pad with zero */
|
||||||
|
#define SIGN 2 /* unsigned/signed long */
|
||||||
|
#define PLUS 4 /* show plus */
|
||||||
|
#define SPACE 8 /* space if plus */
|
||||||
|
#define LEFT 16 /* left justified */
|
||||||
|
#define SPECIAL 32 /* 0x */
|
||||||
|
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
|
||||||
|
|
||||||
|
static char *number(char *buf, char *end, unsigned long long int num, int base, int size, int precision, int type)
|
||||||
|
{
|
||||||
|
char sign,tmp[66];
|
||||||
|
const char *digits;
|
||||||
|
/* we are called with base 8, 10 or 16, only, thus don't need "g..." */
|
||||||
|
static const char small_digits[] = "0123456789abcdefx"; /* "ghijklmnopqrstuvwxyz"; */
|
||||||
|
static const char large_digits[] = "0123456789ABCDEFX"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
|
||||||
|
int need_pfx = ((type & SPECIAL) && base != 10);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
digits = (type & LARGE) ? large_digits : small_digits;
|
||||||
|
if (type & LEFT)
|
||||||
|
type &= ~ZEROPAD;
|
||||||
|
if (base < 2 || base > 36)
|
||||||
|
return NULL;
|
||||||
|
sign = 0;
|
||||||
|
if (type & SIGN) {
|
||||||
|
if ((signed long long int) num < 0) {
|
||||||
|
sign = '-';
|
||||||
|
num = - (signed long long int) num;
|
||||||
|
size--;
|
||||||
|
} else if (type & PLUS) {
|
||||||
|
sign = '+';
|
||||||
|
size--;
|
||||||
|
} else if (type & SPACE) {
|
||||||
|
sign = ' ';
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (need_pfx) {
|
||||||
|
size--;
|
||||||
|
if (base == 16)
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generate full string in tmp[], in reverse order */
|
||||||
|
i = 0;
|
||||||
|
if (num == 0)
|
||||||
|
tmp[i++] = '0';
|
||||||
|
/* Generic code, for any base:
|
||||||
|
else do {
|
||||||
|
tmp[i++] = digits[do_div(num,base)];
|
||||||
|
} while (num != 0);
|
||||||
|
*/
|
||||||
|
else if (base != 10) { /* 8 or 16 */
|
||||||
|
int mask = base - 1;
|
||||||
|
int shift = 3;
|
||||||
|
if (base == 16) shift = 4;
|
||||||
|
do {
|
||||||
|
tmp[i++] = digits[((unsigned char)num) & mask];
|
||||||
|
num >>= shift;
|
||||||
|
} while (num);
|
||||||
|
} else { /* base 10 */
|
||||||
|
i = put_dec(tmp, num) - tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* printing 100 using %2d gives "100", not "00" */
|
||||||
|
if (i > precision)
|
||||||
|
precision = i;
|
||||||
|
/* leading space padding */
|
||||||
|
size -= precision;
|
||||||
|
if (!(type & (ZEROPAD+LEFT))) {
|
||||||
|
while(--size >= 0) {
|
||||||
|
if (buf < end)
|
||||||
|
*buf = ' ';
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* sign */
|
||||||
|
if (sign) {
|
||||||
|
if (buf < end)
|
||||||
|
*buf = sign;
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
/* "0x" / "0" prefix */
|
||||||
|
if (need_pfx) {
|
||||||
|
if (buf < end)
|
||||||
|
*buf = '0';
|
||||||
|
++buf;
|
||||||
|
if (base == 16) {
|
||||||
|
if (buf < end)
|
||||||
|
*buf = digits[16]; /* for arbitrary base: digits[33]; */
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* zero or space padding */
|
||||||
|
if (!(type & LEFT)) {
|
||||||
|
char c = (type & ZEROPAD) ? '0' : ' ';
|
||||||
|
while (--size >= 0) {
|
||||||
|
if (buf < end)
|
||||||
|
*buf = c;
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* hmm even more zero padding? */
|
||||||
|
while (i <= --precision) {
|
||||||
|
if (buf < end)
|
||||||
|
*buf = '0';
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
/* actual digits of result */
|
||||||
|
while (--i >= 0) {
|
||||||
|
if (buf < end)
|
||||||
|
*buf = tmp[i];
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
/* trailing space padding */
|
||||||
|
while (--size >= 0) {
|
||||||
|
if (buf < end)
|
||||||
|
*buf = ' ';
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vsnprintf - Format a string and place it in a buffer
|
||||||
|
* @buf: The buffer to place the result into
|
||||||
|
* @size: The size of the buffer, including the trailing null space
|
||||||
|
* @fmt: The format string to use
|
||||||
|
* @args: Arguments for the format string
|
||||||
|
*
|
||||||
|
* The return value is the number of characters which would
|
||||||
|
* be generated for the given input, excluding the trailing
|
||||||
|
* '\0', as per ISO C99. If you want to have the exact
|
||||||
|
* number of characters written into @buf as return value
|
||||||
|
* (not including the trailing '\0'), use vscnprintf(). If the
|
||||||
|
* return is greater than or equal to @size, the resulting
|
||||||
|
* string is truncated.
|
||||||
|
*
|
||||||
|
* Call this function if you are already dealing with a va_list.
|
||||||
|
* You probably want snprintf() instead.
|
||||||
|
*/
|
||||||
|
int rb_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
unsigned long long int num;
|
||||||
|
int i, base;
|
||||||
|
char *str, *end, c;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
int flags; /* flags to number() */
|
||||||
|
|
||||||
|
int field_width; /* width of output field */
|
||||||
|
int precision; /* min. # of digits for integers; max
|
||||||
|
number of chars for from string */
|
||||||
|
int qualifier; /* 'h', 'l', or 'L' for integer fields */
|
||||||
|
/* 'z' support added 23/7/1999 S.H. */
|
||||||
|
/* 'z' changed to 'Z' --davidm 1/25/99 */
|
||||||
|
/* 't' added for ptrdiff_t */
|
||||||
|
|
||||||
|
/* Reject out-of-range values early. Large positive sizes are
|
||||||
|
used for unknown buffer sizes. */
|
||||||
|
if (unlikely((int) size < 0)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = buf;
|
||||||
|
end = buf + size;
|
||||||
|
|
||||||
|
/* Make sure end is always >= buf */
|
||||||
|
if (end < buf) {
|
||||||
|
end = ((void *)-1);
|
||||||
|
size = end - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; *fmt ; ++fmt) {
|
||||||
|
if (*fmt != '%') {
|
||||||
|
if (str < end)
|
||||||
|
*str = *fmt;
|
||||||
|
++str;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process flags */
|
||||||
|
flags = 0;
|
||||||
|
repeat:
|
||||||
|
++fmt; /* this also skips first '%' */
|
||||||
|
switch (*fmt) {
|
||||||
|
case '-': flags |= LEFT; goto repeat;
|
||||||
|
case '+': flags |= PLUS; goto repeat;
|
||||||
|
case ' ': flags |= SPACE; goto repeat;
|
||||||
|
case '#': flags |= SPECIAL; goto repeat;
|
||||||
|
case '0': flags |= ZEROPAD; goto repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get field width */
|
||||||
|
field_width = -1;
|
||||||
|
if (isdigit(*fmt))
|
||||||
|
field_width = skip_atoi(&fmt);
|
||||||
|
else if (*fmt == '*') {
|
||||||
|
++fmt;
|
||||||
|
/* it's the next argument */
|
||||||
|
field_width = va_arg(args, int);
|
||||||
|
if (field_width < 0) {
|
||||||
|
field_width = -field_width;
|
||||||
|
flags |= LEFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the precision */
|
||||||
|
precision = -1;
|
||||||
|
if (*fmt == '.') {
|
||||||
|
++fmt;
|
||||||
|
if (isdigit(*fmt))
|
||||||
|
precision = skip_atoi(&fmt);
|
||||||
|
else if (*fmt == '*') {
|
||||||
|
++fmt;
|
||||||
|
/* it's the next argument */
|
||||||
|
precision = va_arg(args, int);
|
||||||
|
}
|
||||||
|
if (precision < 0)
|
||||||
|
precision = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the conversion qualifier */
|
||||||
|
qualifier = -1;
|
||||||
|
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
|
||||||
|
*fmt =='Z' || *fmt == 'z' || *fmt == 't') {
|
||||||
|
qualifier = *fmt;
|
||||||
|
++fmt;
|
||||||
|
if (qualifier == 'l' && *fmt == 'l') {
|
||||||
|
qualifier = 'L';
|
||||||
|
++fmt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* default base */
|
||||||
|
base = 10;
|
||||||
|
|
||||||
|
switch (*fmt) {
|
||||||
|
case 'c':
|
||||||
|
if (!(flags & LEFT)) {
|
||||||
|
while (--field_width > 0) {
|
||||||
|
if (str < end)
|
||||||
|
*str = ' ';
|
||||||
|
++str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c = (unsigned char) va_arg(args, int);
|
||||||
|
if (str < end)
|
||||||
|
*str = c;
|
||||||
|
++str;
|
||||||
|
while (--field_width > 0) {
|
||||||
|
if (str < end)
|
||||||
|
*str = ' ';
|
||||||
|
++str;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
s = va_arg(args, char *);
|
||||||
|
if (s == NULL) {
|
||||||
|
abort(); /* prefer blowing up vs corrupt data */
|
||||||
|
}
|
||||||
|
len = rb_strnlen(s, precision);
|
||||||
|
|
||||||
|
if (!(flags & LEFT)) {
|
||||||
|
while (len < field_width--) {
|
||||||
|
if (str < end)
|
||||||
|
*str = ' ';
|
||||||
|
++str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
if (str < end)
|
||||||
|
*str = *s;
|
||||||
|
++str; ++s;
|
||||||
|
}
|
||||||
|
while (len < field_width--) {
|
||||||
|
if (str < end)
|
||||||
|
*str = ' ';
|
||||||
|
++str;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
if (field_width == -1) {
|
||||||
|
field_width = 2*sizeof(void *);
|
||||||
|
flags |= ZEROPAD;
|
||||||
|
}
|
||||||
|
str = number(str, end,
|
||||||
|
(unsigned long) va_arg(args, void *),
|
||||||
|
16, field_width, precision, flags);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
/* FIXME:
|
||||||
|
* What does C99 say about the overflow case here? */
|
||||||
|
if (qualifier == 'l') {
|
||||||
|
long * ip = va_arg(args, long *);
|
||||||
|
*ip = (str - buf);
|
||||||
|
} else if (qualifier == 'Z' || qualifier == 'z') {
|
||||||
|
size_t * ip = va_arg(args, size_t *);
|
||||||
|
*ip = (str - buf);
|
||||||
|
} else {
|
||||||
|
int * ip = va_arg(args, int *);
|
||||||
|
*ip = (str - buf);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case '%':
|
||||||
|
if (str < end)
|
||||||
|
*str = '%';
|
||||||
|
++str;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* integer number formats - set up the flags and "break" */
|
||||||
|
case 'o':
|
||||||
|
base = 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'X':
|
||||||
|
flags |= LARGE;
|
||||||
|
case 'x':
|
||||||
|
base = 16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
case 'i':
|
||||||
|
flags |= SIGN;
|
||||||
|
case 'u':
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (str < end)
|
||||||
|
*str = '%';
|
||||||
|
++str;
|
||||||
|
if (*fmt) {
|
||||||
|
if (str < end)
|
||||||
|
*str = *fmt;
|
||||||
|
++str;
|
||||||
|
} else {
|
||||||
|
--fmt;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (qualifier == 'L')
|
||||||
|
num = va_arg(args, long long int);
|
||||||
|
else if (qualifier == 'l') {
|
||||||
|
num = va_arg(args, unsigned long);
|
||||||
|
if (flags & SIGN)
|
||||||
|
num = (signed long) num;
|
||||||
|
} else if (qualifier == 'Z' || qualifier == 'z') {
|
||||||
|
num = va_arg(args, size_t);
|
||||||
|
} else if (qualifier == 't') {
|
||||||
|
num = va_arg(args, ptrdiff_t);
|
||||||
|
} else if (qualifier == 'h') {
|
||||||
|
num = (unsigned short) va_arg(args, int);
|
||||||
|
if (flags & SIGN)
|
||||||
|
num = (signed short) num;
|
||||||
|
} else {
|
||||||
|
num = va_arg(args, unsigned int);
|
||||||
|
if (flags & SIGN)
|
||||||
|
num = (signed int) num;
|
||||||
|
}
|
||||||
|
str = number(str, end, num, base,
|
||||||
|
field_width, precision, flags);
|
||||||
|
}
|
||||||
|
if (size > 0) {
|
||||||
|
if (str < end)
|
||||||
|
*str = '\0';
|
||||||
|
else
|
||||||
|
end[-1] = '\0';
|
||||||
|
}
|
||||||
|
/* the trailing null byte doesn't count towards the total */
|
||||||
|
return str-buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snprintf - Format a string and place it in a buffer
|
||||||
|
* @buf: The buffer to place the result into
|
||||||
|
* @size: The size of the buffer, including the trailing null space
|
||||||
|
* @fmt: The format string to use
|
||||||
|
* @...: Arguments for the format string
|
||||||
|
*
|
||||||
|
* The return value is the number of characters which would be
|
||||||
|
* generated for the given input, excluding the trailing null,
|
||||||
|
* as per ISO C99. If the return is greater than or equal to
|
||||||
|
* @size, the resulting string is truncated.
|
||||||
|
*/
|
||||||
|
int rb_snprintf(char * buf, size_t size, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
i=rb_vsnprintf(buf,size,fmt,args);
|
||||||
|
va_end(args);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vsprintf - Format a string and place it in a buffer
|
||||||
|
* @buf: The buffer to place the result into
|
||||||
|
* @fmt: The format string to use
|
||||||
|
* @args: Arguments for the format string
|
||||||
|
*
|
||||||
|
* The function returns the number of characters written
|
||||||
|
* into @buf. Use vsnprintf() or vscnprintf() in order to avoid
|
||||||
|
* buffer overflows.
|
||||||
|
*
|
||||||
|
* Call this function if you are already dealing with a va_list.
|
||||||
|
* You probably want sprintf() instead.
|
||||||
|
*/
|
||||||
|
int rb_vsprintf(char *buf, const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
return rb_vsnprintf(buf, INT_MAX, fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sprintf - Format a string and place it in a buffer
|
||||||
|
* @buf: The buffer to place the result into
|
||||||
|
* @fmt: The format string to use
|
||||||
|
* @...: Arguments for the format string
|
||||||
|
*
|
||||||
|
* The function returns the number of characters written
|
||||||
|
* into @buf. Use snprintf() or scnprintf() in order to avoid
|
||||||
|
* buffer overflows.
|
||||||
|
*/
|
||||||
|
int rb_sprintf(char * buf, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
i=rb_vsnprintf(buf, INT_MAX, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_vsprintf_append()
|
||||||
|
* appends sprintf formatted string to the end of the buffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_vsprintf_append(char *str, const char *format, va_list ap)
|
||||||
|
{
|
||||||
|
size_t x = strlen(str);
|
||||||
|
return(rb_vsprintf(str+x, format, ap) + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_sprintf_append()
|
||||||
|
* appends sprintf formatted string to the end of the buffer
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rb_sprintf_append(char *str, const char *format, ...)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
x = rb_vsprintf_append(str, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_vsnprintf_append()
|
||||||
|
* appends sprintf formatted string to the end of the buffer but not
|
||||||
|
* exceeding len
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_vsnprintf_append(char *str, size_t len, const char *format, va_list ap)
|
||||||
|
{
|
||||||
|
size_t x = strlen(str);
|
||||||
|
return(rb_vsnprintf(str+x, len - x, format, ap) + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rb_snprintf_append()
|
||||||
|
* appends snprintf formatted string to the end of the buffer but not
|
||||||
|
* exceeding len
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_snprintf_append(char *str, size_t len, const char *format, ...)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
x = rb_vsnprintf_append(str, len, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return(x);
|
||||||
|
}
|
||||||
|
|
203
libratbox/src/tools.c
Normal file
203
libratbox/src/tools.c
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* tools.c: Various functions needed here and there.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: tools.c 25040 2008-01-23 16:11:34Z androsyn $
|
||||||
|
*
|
||||||
|
* Here is the original header:
|
||||||
|
*
|
||||||
|
* Useful stuff, ripped from places ..
|
||||||
|
* adrian chadd <adrian@creative.net.au>
|
||||||
|
*
|
||||||
|
* The TOOLS_C define builds versions of the functions in tools.h
|
||||||
|
* so that they end up in the resulting object files. If its not
|
||||||
|
* defined, tools.h will build inlined versions of the functions
|
||||||
|
* on supported compilers
|
||||||
|
*/
|
||||||
|
#define _GNU_SOURCE 1
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <rb_tools.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_rb_dlink_nodes
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static rb_bh *dnode_heap;
|
||||||
|
void
|
||||||
|
rb_init_rb_dlink_nodes(size_t dh_size)
|
||||||
|
{
|
||||||
|
|
||||||
|
dnode_heap = rb_bh_create(sizeof(rb_dlink_node), dh_size, "librb_dnode_heap");
|
||||||
|
if(dnode_heap == NULL)
|
||||||
|
rb_outofmemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* make_rb_dlink_node
|
||||||
|
*
|
||||||
|
* inputs - NONE
|
||||||
|
* output - pointer to new rb_dlink_node
|
||||||
|
* side effects - NONE
|
||||||
|
*/
|
||||||
|
rb_dlink_node *
|
||||||
|
rb_make_rb_dlink_node(void)
|
||||||
|
{
|
||||||
|
return(rb_bh_alloc(dnode_heap));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* free_rb_dlink_node
|
||||||
|
*
|
||||||
|
* inputs - pointer to rb_dlink_node
|
||||||
|
* output - NONE
|
||||||
|
* side effects - free given rb_dlink_node
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rb_free_rb_dlink_node(rb_dlink_node * ptr)
|
||||||
|
{
|
||||||
|
assert(ptr != NULL);
|
||||||
|
rb_bh_free(dnode_heap, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rb_string_to_array()
|
||||||
|
* Changes a given buffer into an array of parameters.
|
||||||
|
* Taken from ircd-ratbox.
|
||||||
|
*
|
||||||
|
* inputs - string to parse, array to put in
|
||||||
|
* outputs - number of parameters
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rb_string_to_array(char *string, char **parv, int maxpara)
|
||||||
|
{
|
||||||
|
char *p, *xbuf = string;
|
||||||
|
int x = 0;
|
||||||
|
|
||||||
|
parv[x] = NULL;
|
||||||
|
|
||||||
|
if(string == NULL || string[0] == '\0')
|
||||||
|
return x;
|
||||||
|
|
||||||
|
while (*xbuf == ' ') /* skip leading spaces */
|
||||||
|
xbuf++;
|
||||||
|
if(*xbuf == '\0') /* ignore all-space args */
|
||||||
|
return x;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(*xbuf == ':') /* Last parameter */
|
||||||
|
{
|
||||||
|
xbuf++;
|
||||||
|
parv[x++] = xbuf;
|
||||||
|
parv[x] = NULL;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parv[x++] = xbuf;
|
||||||
|
parv[x] = NULL;
|
||||||
|
if((p = strchr(xbuf, ' ')) != NULL)
|
||||||
|
{
|
||||||
|
*p++ = '\0';
|
||||||
|
xbuf = p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
while (*xbuf == ' ')
|
||||||
|
xbuf++;
|
||||||
|
if(*xbuf == '\0')
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
while (x < maxpara - 1);
|
||||||
|
|
||||||
|
if(*p == ':')
|
||||||
|
p++;
|
||||||
|
|
||||||
|
parv[x++] = p;
|
||||||
|
parv[x] = NULL;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_STRLCAT
|
||||||
|
size_t
|
||||||
|
rb_strlcat(char *dest, const char *src, size_t count)
|
||||||
|
{
|
||||||
|
size_t dsize = strlen(dest);
|
||||||
|
size_t len = strlen(src);
|
||||||
|
size_t res = dsize + len;
|
||||||
|
|
||||||
|
dest += dsize;
|
||||||
|
count -= dsize;
|
||||||
|
if (len >= count)
|
||||||
|
len = count-1;
|
||||||
|
memcpy(dest, src, len);
|
||||||
|
dest[len] = 0;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
size_t
|
||||||
|
rb_strlcat(char *dest, const char *src, size_t count)
|
||||||
|
{
|
||||||
|
return strlcat(dest, src, count);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_STRLCPY
|
||||||
|
size_t
|
||||||
|
rb_strlcpy(char *dest, const char *src, size_t size)
|
||||||
|
{
|
||||||
|
size_t ret = strlen(src);
|
||||||
|
|
||||||
|
if (size) {
|
||||||
|
size_t len = (ret >= size) ? size-1 : ret;
|
||||||
|
memcpy(dest, src, len);
|
||||||
|
dest[len] = '\0';
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
size_t
|
||||||
|
rb_strlcpy(char *dest, const char *src, size_t size)
|
||||||
|
{
|
||||||
|
return strlcpy(dest, src, size);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HAVE_STRNLEN
|
||||||
|
size_t
|
||||||
|
rb_strnlen(const char *s, size_t count)
|
||||||
|
{
|
||||||
|
const char *sc;
|
||||||
|
for (sc = s; count-- && *sc != '\0'; ++sc)
|
||||||
|
;;
|
||||||
|
return sc - s;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
size_t
|
||||||
|
rb_strnlen(const char *s, size_t count)
|
||||||
|
{
|
||||||
|
return strnlen(s, count);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
102
libratbox/src/unix.c
Normal file
102
libratbox/src/unix.c
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* unix.c: various unix type functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 2005 ircd-ratbox development team
|
||||||
|
* Copyright (C) 2005 Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: unix.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
|
||||||
|
#ifndef WINDOWS
|
||||||
|
#if defined(HAVE_SPAWN_H) && defined(HAVE_POSIX_SPAWN)
|
||||||
|
#include <spawn.h>
|
||||||
|
extern char **environ;
|
||||||
|
pid_t
|
||||||
|
rb_spawn_process(const char *path, const char **argv)
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
const void *arghack = argv;
|
||||||
|
posix_spawnattr_t spattr;
|
||||||
|
posix_spawnattr_init(&spattr);
|
||||||
|
#ifdef POSIX_SPAWN_USEVFORK
|
||||||
|
posix_spawnattr_setflags(&spattr, POSIX_SPAWN_USEVFORK);
|
||||||
|
#endif
|
||||||
|
if(posix_spawn(&pid, path, NULL, &spattr, arghack, environ))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
pid_t
|
||||||
|
rb_spawn_process(const char *path, const char **argv)
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
if(!(pid = vfork()))
|
||||||
|
{
|
||||||
|
execv(path, (const void *)argv); /* make gcc shut up */
|
||||||
|
_exit(1); /* if we're still here, we're screwed */
|
||||||
|
}
|
||||||
|
return(pid);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_GETTIMEOFDAY
|
||||||
|
int
|
||||||
|
rb_gettimeofday(struct timeval *tv, void *tz)
|
||||||
|
{
|
||||||
|
if(tv == NULL)
|
||||||
|
{
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tv->tv_usec = 0;
|
||||||
|
if(time(&tv->tv_sec) == -1)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int
|
||||||
|
rb_gettimeofday(struct timeval *tv, void *tz)
|
||||||
|
{
|
||||||
|
return(gettimeofday(tv, tz));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_sleep(unsigned int seconds, unsigned int useconds)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_NANOSLEEP
|
||||||
|
struct timespec tv;
|
||||||
|
tv.tv_nsec = (useconds * 1000);
|
||||||
|
tv.tv_sec = seconds;
|
||||||
|
nanosleep(&tv, NULL);
|
||||||
|
#else
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = seconds;
|
||||||
|
tv.tv_usec = useconds;
|
||||||
|
select(0, NULL, NULL, NULL, &tv);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* !WINDOWS */
|
||||||
|
|
||||||
|
|
519
libratbox/src/win32.c
Normal file
519
libratbox/src/win32.c
Normal file
|
@ -0,0 +1,519 @@
|
||||||
|
/*
|
||||||
|
* ircd-ratbox: A slightly useful ircd.
|
||||||
|
* win32.c: select() compatible network routines.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
|
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
|
||||||
|
* Copyright (C) 2005-2006 Aaron Sethman <androsyn@ratbox.org>
|
||||||
|
* Copyright (C) 2002-2006 ircd-ratbox development team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
* USA
|
||||||
|
*
|
||||||
|
* $Id: win32.c 25038 2008-01-23 16:03:08Z androsyn $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libratbox_config.h>
|
||||||
|
#include <ratbox_lib.h>
|
||||||
|
#include <commio-int.h>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
|
||||||
|
static HWND hwnd;
|
||||||
|
|
||||||
|
#define WM_SOCKET WM_USER
|
||||||
|
/*
|
||||||
|
* having gettimeofday is nice...
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
unsigned __int64 ft_i64;
|
||||||
|
FILETIME ft_val;
|
||||||
|
} FT_t;
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define Const64(x) x##LL
|
||||||
|
#else
|
||||||
|
#define Const64(x) x##i64
|
||||||
|
#endif
|
||||||
|
/* Number of 100 nanosecond units from 1/1/1601 to 1/1/1970 */
|
||||||
|
#define EPOCH_BIAS Const64(116444736000000000)
|
||||||
|
|
||||||
|
pid_t
|
||||||
|
getpid()
|
||||||
|
{
|
||||||
|
return GetCurrentProcessId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_gettimeofday(struct timeval *tp, void *not_used)
|
||||||
|
{
|
||||||
|
FT_t ft;
|
||||||
|
|
||||||
|
/* this returns time in 100-nanosecond units (i.e. tens of usecs) */
|
||||||
|
GetSystemTimeAsFileTime(&ft.ft_val);
|
||||||
|
|
||||||
|
/* seconds since epoch */
|
||||||
|
tp->tv_sec = (long) ((ft.ft_i64 - EPOCH_BIAS) / Const64(10000000));
|
||||||
|
|
||||||
|
/* microseconds remaining */
|
||||||
|
tp->tv_usec = (long) ((ft.ft_i64 / Const64(10)) % Const64(1000000));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pid_t
|
||||||
|
rb_spawn_process(const char *path, const char **argv)
|
||||||
|
{
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
STARTUPINFO si;
|
||||||
|
char cmd[MAX_PATH];
|
||||||
|
memset(&pi, 0, sizeof(pi));
|
||||||
|
memset(&si, 0, sizeof(si));
|
||||||
|
rb_strlcpy(cmd, path, sizeof(cmd));
|
||||||
|
if(CreateProcess(cmd, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) == FALSE)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return (pi.dwProcessId);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t
|
||||||
|
waitpid(int pid, int *status, int flags)
|
||||||
|
{
|
||||||
|
DWORD timeout = (flags & WNOHANG) ? 0 : INFINITE;
|
||||||
|
HANDLE hProcess;
|
||||||
|
DWORD waitcode;
|
||||||
|
|
||||||
|
hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
|
||||||
|
if(hProcess)
|
||||||
|
{
|
||||||
|
waitcode = WaitForSingleObject(hProcess, timeout);
|
||||||
|
if(waitcode == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if(waitcode == WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
if(GetExitCodeProcess(hProcess, &waitcode))
|
||||||
|
{
|
||||||
|
*status = (int) ((waitcode & 0xff) << 8);
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errno = ECHILD;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
setenv(const char *name, const char *value, int overwrite)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
int len;
|
||||||
|
if(!overwrite)
|
||||||
|
{
|
||||||
|
if((buf = getenv(name)) != NULL)
|
||||||
|
{
|
||||||
|
if(strlen(buf) > 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(name == NULL || value == NULL)
|
||||||
|
return -1;
|
||||||
|
len = strlen(name) + strlen(value) + 5;
|
||||||
|
buf = rb_malloc(len);
|
||||||
|
rb_snprintf(buf, len, "%s=%s", name, value);
|
||||||
|
len = putenv(buf);
|
||||||
|
rb_free(buf);
|
||||||
|
return (len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
kill(int pid, int sig)
|
||||||
|
{
|
||||||
|
HANDLE hProcess;
|
||||||
|
hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
|
||||||
|
int ret = -1;
|
||||||
|
if(hProcess)
|
||||||
|
{
|
||||||
|
switch (sig)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if(TerminateProcess(hProcess, sig))
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errno = EINVAL;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_pass_fd_to_process(int fd, pid_t process, rb_fde_t *F)
|
||||||
|
{
|
||||||
|
WSAPROTOCOL_INFO info;
|
||||||
|
WSADuplicateSocket((SOCKET)fd, process, &info);
|
||||||
|
rb_write(F, &info, sizeof(info));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static LRESULT CALLBACK
|
||||||
|
rb_process_events(HWND nhwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
|
||||||
|
{
|
||||||
|
rb_fde_t *F;
|
||||||
|
PF *hdl;
|
||||||
|
void *data;
|
||||||
|
switch (umsg)
|
||||||
|
{
|
||||||
|
case WM_SOCKET:
|
||||||
|
{
|
||||||
|
F = rb_find_fd(wparam);
|
||||||
|
|
||||||
|
if(F != NULL && IsFDOpen(F))
|
||||||
|
{
|
||||||
|
switch (WSAGETSELECTEVENT(lparam))
|
||||||
|
{
|
||||||
|
case FD_ACCEPT:
|
||||||
|
case FD_CLOSE:
|
||||||
|
case FD_READ:
|
||||||
|
{
|
||||||
|
if((hdl = F->read_handler) != NULL)
|
||||||
|
{
|
||||||
|
F->read_handler = NULL;
|
||||||
|
data = F->read_data;
|
||||||
|
F->read_data = NULL;
|
||||||
|
hdl(F, data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case FD_CONNECT:
|
||||||
|
case FD_WRITE:
|
||||||
|
{
|
||||||
|
if((hdl = F->write_handler) != NULL)
|
||||||
|
{
|
||||||
|
F->write_handler = NULL;
|
||||||
|
data = F->write_data;
|
||||||
|
F->write_data = NULL;
|
||||||
|
hdl(F, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case WM_DESTROY:
|
||||||
|
{
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return DefWindowProc(nhwnd, umsg, wparam, lparam);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_init_netio_win32(void)
|
||||||
|
{
|
||||||
|
/* this muchly sucks, but i'm too lazy to do overlapped i/o, maybe someday... -androsyn */
|
||||||
|
WNDCLASS wc;
|
||||||
|
static const char *classname = "ircd-ratbox-class";
|
||||||
|
|
||||||
|
wc.style = 0;
|
||||||
|
wc.lpfnWndProc = (WNDPROC) rb_process_events;
|
||||||
|
wc.cbClsExtra = 0;
|
||||||
|
wc.cbWndExtra = 0;
|
||||||
|
wc.hIcon = NULL;
|
||||||
|
wc.hCursor = NULL;
|
||||||
|
wc.hbrBackground = NULL;
|
||||||
|
wc.lpszMenuName = NULL;
|
||||||
|
wc.lpszClassName = classname;
|
||||||
|
wc.hInstance = GetModuleHandle(NULL);
|
||||||
|
|
||||||
|
if(!RegisterClass(&wc))
|
||||||
|
rb_lib_die("cannot register window class");
|
||||||
|
|
||||||
|
hwnd = CreateWindow(classname, classname, WS_POPUP, CW_USEDEFAULT,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
|
(HWND) NULL, (HMENU) NULL, wc.hInstance, NULL);
|
||||||
|
if(!hwnd)
|
||||||
|
rb_lib_die("could not create window");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_sleep(unsigned int seconds, unsigned int useconds)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = seconds;
|
||||||
|
tv.tv_usec = useconds;
|
||||||
|
select(0, NULL, NULL, NULL, &tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_win32(rb_fde_t * F)
|
||||||
|
{
|
||||||
|
if(F == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
SetHandleInformation((HANDLE) F->fd, HANDLE_FLAG_INHERIT, 0);
|
||||||
|
switch (F->type)
|
||||||
|
{
|
||||||
|
case RB_FD_SOCKET:
|
||||||
|
{
|
||||||
|
u_long nonb = 1;
|
||||||
|
if(ioctlsocket((SOCKET) F->fd, FIONBIO, &nonb) == -1)
|
||||||
|
{
|
||||||
|
rb_get_errno();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_setselect_win32(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
|
||||||
|
{
|
||||||
|
int old_flags = F->pflags;
|
||||||
|
|
||||||
|
lrb_assert(IsFDOpen(F));
|
||||||
|
|
||||||
|
/* Update the list, even though we're not using it .. */
|
||||||
|
if(type & RB_SELECT_READ)
|
||||||
|
{
|
||||||
|
if(handler != NULL)
|
||||||
|
F->pflags |= FD_CLOSE | FD_READ | FD_ACCEPT;
|
||||||
|
else
|
||||||
|
F->pflags &= ~(FD_CLOSE | FD_READ | FD_ACCEPT);
|
||||||
|
F->read_handler = handler;
|
||||||
|
F->read_data = client_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type & RB_SELECT_WRITE)
|
||||||
|
{
|
||||||
|
if(handler != NULL)
|
||||||
|
F->pflags |= FD_WRITE | FD_CONNECT;
|
||||||
|
else
|
||||||
|
F->pflags &= ~(FD_WRITE | FD_CONNECT);
|
||||||
|
F->write_handler = handler;
|
||||||
|
F->write_data = client_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(old_flags == 0 && F->pflags == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(F->pflags != old_flags)
|
||||||
|
{
|
||||||
|
WSAAsyncSelect(F->fd, hwnd, WM_SOCKET, F->pflags);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int has_set_timer = 0;
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_win32(long delay)
|
||||||
|
{
|
||||||
|
MSG msg;
|
||||||
|
if(has_set_timer == 0)
|
||||||
|
{
|
||||||
|
/* XXX should probably have this handle all the events
|
||||||
|
* instead of busy looping
|
||||||
|
*/
|
||||||
|
SetTimer(hwnd, 0, delay, NULL);
|
||||||
|
has_set_timer = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetMessage(&msg, NULL, 0, 0) == FALSE)
|
||||||
|
{
|
||||||
|
rb_lib_die("GetMessage failed..byebye");
|
||||||
|
}
|
||||||
|
rb_set_time();
|
||||||
|
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
return RB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef strerror
|
||||||
|
#undef strerror
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char *
|
||||||
|
wsock_strerror(int error)
|
||||||
|
{
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "Success";
|
||||||
|
case WSAEINTR:
|
||||||
|
return "Interrupted system call";
|
||||||
|
case WSAEBADF:
|
||||||
|
return "Bad file number";
|
||||||
|
case WSAEACCES:
|
||||||
|
return "Permission denied";
|
||||||
|
case WSAEFAULT:
|
||||||
|
return "Bad address";
|
||||||
|
case WSAEINVAL:
|
||||||
|
return "Invalid argument";
|
||||||
|
case WSAEMFILE:
|
||||||
|
return "Too many open sockets";
|
||||||
|
case WSAEWOULDBLOCK:
|
||||||
|
return "Operation would block";
|
||||||
|
case WSAEINPROGRESS:
|
||||||
|
return "Operation now in progress";
|
||||||
|
case WSAEALREADY:
|
||||||
|
return "Operation already in progress";
|
||||||
|
case WSAENOTSOCK:
|
||||||
|
return "Socket operation on non-socket";
|
||||||
|
case WSAEDESTADDRREQ:
|
||||||
|
return "Destination address required";
|
||||||
|
case WSAEMSGSIZE:
|
||||||
|
return "Message too long";
|
||||||
|
case WSAEPROTOTYPE:
|
||||||
|
return "Protocol wrong type for socket";
|
||||||
|
case WSAENOPROTOOPT:
|
||||||
|
return "Bad protocol option";
|
||||||
|
case WSAEPROTONOSUPPORT:
|
||||||
|
return "Protocol not supported";
|
||||||
|
case WSAESOCKTNOSUPPORT:
|
||||||
|
return "Socket type not supported";
|
||||||
|
case WSAEOPNOTSUPP:
|
||||||
|
return "Operation not supported on socket";
|
||||||
|
case WSAEPFNOSUPPORT:
|
||||||
|
return "Protocol family not supported";
|
||||||
|
case WSAEAFNOSUPPORT:
|
||||||
|
return "Address family not supported";
|
||||||
|
case WSAEADDRINUSE:
|
||||||
|
return "Address already in use";
|
||||||
|
case WSAEADDRNOTAVAIL:
|
||||||
|
return "Can't assign requested address";
|
||||||
|
case WSAENETDOWN:
|
||||||
|
return "Network is down";
|
||||||
|
case WSAENETUNREACH:
|
||||||
|
return "Network is unreachable";
|
||||||
|
case WSAENETRESET:
|
||||||
|
return "Net connection reset";
|
||||||
|
case WSAECONNABORTED:
|
||||||
|
return "Software caused connection abort";
|
||||||
|
case WSAECONNRESET:
|
||||||
|
return "Connection reset by peer";
|
||||||
|
case WSAENOBUFS:
|
||||||
|
return "No buffer space available";
|
||||||
|
case WSAEISCONN:
|
||||||
|
return "Socket is already connected";
|
||||||
|
case WSAENOTCONN:
|
||||||
|
return "Socket is not connected";
|
||||||
|
case WSAESHUTDOWN:
|
||||||
|
return "Can't send after socket shutdown";
|
||||||
|
case WSAETOOMANYREFS:
|
||||||
|
return "Too many references, can't splice";
|
||||||
|
case WSAETIMEDOUT:
|
||||||
|
return "Connection timed out";
|
||||||
|
case WSAECONNREFUSED:
|
||||||
|
return "Connection refused";
|
||||||
|
case WSAELOOP:
|
||||||
|
return "Too many levels of symbolic links";
|
||||||
|
case WSAENAMETOOLONG:
|
||||||
|
return "File name too long";
|
||||||
|
case WSAEHOSTDOWN:
|
||||||
|
return "Host is down";
|
||||||
|
case WSAEHOSTUNREACH:
|
||||||
|
return "No route to host";
|
||||||
|
case WSAENOTEMPTY:
|
||||||
|
return "Directory not empty";
|
||||||
|
case WSAEPROCLIM:
|
||||||
|
return "Too many processes";
|
||||||
|
case WSAEUSERS:
|
||||||
|
return "Too many users";
|
||||||
|
case WSAEDQUOT:
|
||||||
|
return "Disc quota exceeded";
|
||||||
|
case WSAESTALE:
|
||||||
|
return "Stale NFS file handle";
|
||||||
|
case WSAEREMOTE:
|
||||||
|
return "Too many levels of remote in path";
|
||||||
|
case WSASYSNOTREADY:
|
||||||
|
return "Network system is unavailable";
|
||||||
|
case WSAVERNOTSUPPORTED:
|
||||||
|
return "Winsock version out of range";
|
||||||
|
case WSANOTINITIALISED:
|
||||||
|
return "WSAStartup not yet called";
|
||||||
|
case WSAEDISCON:
|
||||||
|
return "Graceful shutdown in progress";
|
||||||
|
case WSAHOST_NOT_FOUND:
|
||||||
|
return "Host not found";
|
||||||
|
case WSANO_DATA:
|
||||||
|
return "No host data of that type was found";
|
||||||
|
default:
|
||||||
|
return strerror(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else /* win32 not supported */
|
||||||
|
int
|
||||||
|
rb_init_netio_win32(void)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_setselect_win32(rb_fde_t * F, unsigned int type, PF * handler, void *client_data)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_select_win32(long delay)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_setup_fd_win32(rb_fde_t * F)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif /* WIN32 */
|
Loading…
Reference in a new issue