Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfa38fa5ed |
@@ -1,9 +0,0 @@
|
||||
*~
|
||||
*.[oa]
|
||||
*.exe
|
||||
*.gch
|
||||
mod_*.so
|
||||
uhub-admin
|
||||
adcrush
|
||||
uhub
|
||||
revision.h*
|
||||
@@ -1,3 +0,0 @@
|
||||
[submodule "thirdparty/sqlite"]
|
||||
path = thirdparty/sqlite
|
||||
url = git://github.com/janvidar/sqlite.git
|
||||
@@ -1,9 +0,0 @@
|
||||
Authors of uhub
|
||||
===============
|
||||
|
||||
Jan Vidar Krey, Design and implementation
|
||||
E_zombie, Centos/RedHat customization scripts and heavy load testing
|
||||
FleetCommand, Hub topic
|
||||
MiMic, Implemented user commands
|
||||
tehnick, Debian and Ubuntu packaging.
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
GMAKE=gmake
|
||||
|
||||
all:
|
||||
@${GMAKE} ${.TARGETS}
|
||||
|
||||
${.TARGETS}: all
|
||||
|
||||
@@ -1,674 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. 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
|
||||
them 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 prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. 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.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey 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;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If 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 convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU 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 that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
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.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
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.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
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
|
||||
state 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program 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, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU 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 Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
@@ -1,185 +0,0 @@
|
||||
0.3.2:
|
||||
- Fixed bugs in the kqueue network backend (OSX/BSD)
|
||||
- Rewrote the configuration backend code.
|
||||
- Added support for escaping characters in the configuration files.
|
||||
- Updated the !broadcast command to send private messages instead of main chat messages.
|
||||
- Adding support for redirecting clients to other hubs when they fail to log in.
|
||||
- Fix some out of memory related crashes.
|
||||
- Fixed minor memory leaks.
|
||||
|
||||
|
||||
0.3.1:
|
||||
- Fixed bug where !getip did not work.
|
||||
- Added flood control configuration options.
|
||||
- Added configuration options to disallow old/obsolete ADC clients.
|
||||
- Fixed crash bugs, an freezes.
|
||||
- SSL/TLS fix for tls_require configuration option.
|
||||
- Fixed disconnect messages, so that clients can interpret them.
|
||||
- Fixed bugs where share limits could be circumvented.
|
||||
- Added support for listening to multiple ports.
|
||||
- kqueue backend for Mac OS X, and BSD systems.
|
||||
|
||||
|
||||
0.3.0:
|
||||
- More user commands: ban, broadcast, mute, rules, history, myip, whoip, log
|
||||
- Experimental SSL support
|
||||
- Large rewrite of the network stack in order to support SSL.
|
||||
- Added rule file for defining hub rules.
|
||||
- Many crash fixes and other important bug fixes.
|
||||
- Optimizations: O(1) timeout scheduler
|
||||
- New sid allocation code.
|
||||
- Added configurable server_listen_backlog (default 50).
|
||||
- Added init.d scripts for RedHat/CentOS
|
||||
|
||||
|
||||
0.2.8:
|
||||
- Fix bug #13: getsockname() failure, use sockaddr from accept() instead.
|
||||
- Fix bug #10: Improve logging, ensure logs are machine readable.
|
||||
- Fix bug #12: asserts in adc_msg_parse -> enabled strict utf8 parsing.
|
||||
|
||||
|
||||
0.2.7:
|
||||
- Fixed a nasty crash (bug #11), Thanks Toast for finding it.
|
||||
- Fix bug #9 - net_get_peer_address() failure on CentOS/Xen configurations.
|
||||
- Write a log message if an operator reloads the config file.
|
||||
- Don't print OK or ERROR when using '-s' or '-S' show the configuration.
|
||||
- Cleanup credential string handling
|
||||
- Made sure "!help" only display accessible commands.
|
||||
- Cleanup in-hub command parsing
|
||||
- Fix a possible crash if multiple INF messages are sent during login.
|
||||
- Rewrote the mainloop to not use a timer.
|
||||
|
||||
|
||||
0.2.6:
|
||||
- Better "!uptime" command formatting.
|
||||
- Better "!stats"; can display peak and current bandwidth usage.
|
||||
- Added "+myip" command.
|
||||
- Ensure super users and hub owners also have the operator flag set.
|
||||
- Bug #1: Disconnecting users due to excessive "send queue".
|
||||
- Bug #5: Always provide IP-address for all users, not just for active clients.
|
||||
- Better send queue priorities.
|
||||
- Dump configuration does not quote integer and boolean settings.
|
||||
- Sources hosted by GitHub.com, and bug tracker on bugs.extatic.org
|
||||
- Minor optimizations.
|
||||
|
||||
|
||||
0.2.5-3487:
|
||||
- Fixed out of memory situations, used when uhub operates on a limited heap.
|
||||
- Code cleanups, reduced heap memory footprint.
|
||||
- Fixed bug throwing users out due to exessive send queue when logging into a large hub.
|
||||
- Added some simple hub commands (!stats, !uptime, !version, !help, etc).
|
||||
|
||||
|
||||
0.2.4-3470:
|
||||
- Added option chat_is_privileged, which makes chat for privileged users only.
|
||||
- Started working on hub commands.
|
||||
- Fixed a double free() related crash / abort.
|
||||
- Fixed several send() -> EPIPE related crashes.
|
||||
|
||||
|
||||
0.2.3-3429:
|
||||
- Fixed one crash bug (jump to NULL).
|
||||
- Fixed IPv6 dual stack issues on Winsock, but needs Vista or later to compile.
|
||||
- Disable IPv6 if dual stack is not supported (WinXP with IPv6).
|
||||
- Fixed bind issue for IPv4 addresses.
|
||||
- Made sure no chat message could have PM context flag, unless set by the hub.
|
||||
- Ignore empty INF update messages.
|
||||
|
||||
|
||||
0.2.2-3393:
|
||||
- Fixed a crash related to hub login.
|
||||
- Added some fixes for older versions of libevent
|
||||
- Added option to log messages through syslog.
|
||||
- Added low bandwidth mode for really big hubs.
|
||||
- Started writing a benchmark tool for the hub.
|
||||
- Fix bug: reload configuration reset uptime.
|
||||
- Experimental support for NetBSD 3.1.
|
||||
|
||||
|
||||
0.2.1-3321:
|
||||
- Added more robust configuration file parsing.
|
||||
- Use defaults if config file is not found, unless a file is specified.
|
||||
- Added user class super user (above operator, below admin).
|
||||
- Added NAT override for clients behind the same NAT as the hub.
|
||||
- Fixed a bug summarizing shared size and files for the PING extension.
|
||||
- Fixed bugs related to hub limits.
|
||||
|
||||
|
||||
0.2.0-3293:
|
||||
- Fixed multiple crash bugs.
|
||||
- Fully compatible with ADC/1.0.
|
||||
- Protocol extensions: 'TIGR' and 'PING'
|
||||
- Added support for configuring min/max share size, slots, concurrent hubs, not very well tested.
|
||||
- Made all status message strings configurable.
|
||||
- Various BSD issues fixed. Should perform equally well as Linux.
|
||||
- Allow ignored configuration options (used when deprecating configuration options).
|
||||
- Added command line options for checking configuration.
|
||||
- A windows port is more or less done (MinGW)
|
||||
- Lots of new auto tests added.
|
||||
|
||||
|
||||
0.1.6-2608:
|
||||
- Changes required for the ADC/0.14 specification.
|
||||
- Stability fixes.
|
||||
- Win32 fixes, it compiles and runs, but not quite ported yet.
|
||||
- Added CMAKE files, which can be used instead of GNU make.
|
||||
- Made sure all messages are terminated when created.
|
||||
- Use length of messages, instead of strlen() to determine them.
|
||||
- Added more asserts for messages. Spotted a few errors as a result of that.
|
||||
- Added support for more sophisticated memory allocation debugging.
|
||||
|
||||
|
||||
0.1.5-2462
|
||||
- Fixed double free (crash).
|
||||
- Fixed password challenge/response coding error (crash).
|
||||
- Changes required for the new ADC/0.13 specification.
|
||||
- Fixed IPv6 netmask matching (banning)
|
||||
- Added UDP server, needed for auto-configure extension (AUT0)
|
||||
- Send 'ping' messages periodically if nothing heard from clients.
|
||||
- Print IP when client disconnects.
|
||||
- Lots of automatic testcases added, fix many bugs in the process.
|
||||
- GCC 2.95 compile fixes.
|
||||
|
||||
|
||||
0.1.4-2301:
|
||||
- uHub now requires and utilizes libevent. This allows for greater code
|
||||
portability, and less code complexity.
|
||||
- Various FreeBSD/OpenBSD/NetBSD fixes have been applied.
|
||||
- Can now log files other than stderr.
|
||||
- Added several automatic testcases.
|
||||
- The application should now be much more stable, and never consume much CPU.
|
||||
- Fixed several small annoying bugs.
|
||||
|
||||
|
||||
0.1.3-2147:
|
||||
- Changed license to GPL3
|
||||
- Fixed several crashes
|
||||
- Major code cleanups
|
||||
- Refactored event handling
|
||||
- Log file format change (minor)
|
||||
- Automatic regression testing of code base (via exotic).
|
||||
- Memory handling debug infrastructure.
|
||||
|
||||
|
||||
0.1.2-2020:
|
||||
- Fix infinite loops
|
||||
- Don't log users leaving unless they are logged in.
|
||||
- Fix private messages in chat only hubs.
|
||||
- Operators/admins override chat only hub settings.
|
||||
- Fix client/server protocol support negotiation handling
|
||||
- IP banning should now work (IPv6 is not tested yet).
|
||||
|
||||
|
||||
0.1.1-1956:
|
||||
- Fixed memory leaks in ACL handling
|
||||
- Prevent unneeded malloc's in command handling when buffers are big enough.
|
||||
- Code cleanups and more doxygen style comments added.
|
||||
- Fixed crashes and infinite loops
|
||||
- FreeBSD compile fixes
|
||||
- Timestamp log messages.
|
||||
- Log network/bandwidth statistics
|
||||
|
||||
|
||||
0.1.0-1840:
|
||||
- First public release
|
||||
|
||||
-354
@@ -1,354 +0,0 @@
|
||||
##
|
||||
## Makefile for uhub (Use GNU make)
|
||||
## Copyright (C) 2007-2010, Jan Vidar Krey <janvidar@extatic.org>
|
||||
#
|
||||
|
||||
-include Makefile.private
|
||||
|
||||
CC = gcc
|
||||
LD := $(CC)
|
||||
MV := mv
|
||||
RANLIB := ranlib
|
||||
CFLAGS += -pipe -Wall
|
||||
USE_SSL ?= YES
|
||||
USE_PLUGINS ?= YES
|
||||
USE_BIGENDIAN ?= AUTO
|
||||
BITS ?= AUTO
|
||||
SILENT ?= YES
|
||||
TERSE ?= NO
|
||||
STACK_PROTECT ?= NO
|
||||
NEED_LIBDL ?= NO
|
||||
|
||||
ifeq ($(OS), Windows_NT)
|
||||
WINDOWS ?= YES
|
||||
OPSYS ?= Windows
|
||||
else
|
||||
OPSYS ?= $(shell uname)
|
||||
endif
|
||||
|
||||
ifeq ($(OPSYS),SunOS)
|
||||
LDLIBS += -lsocket -lnsl
|
||||
endif
|
||||
|
||||
ifeq ($(OPSYS),Haiku)
|
||||
LDLIBS += -lnetwork
|
||||
endif
|
||||
|
||||
ifeq ($(OPSYS),Linux)
|
||||
NEED_LIBDL = YES
|
||||
endif
|
||||
|
||||
CFLAGS += -I./src/
|
||||
|
||||
ifeq ($(OPSYS),Windows)
|
||||
USE_BIGENDIAN := NO
|
||||
LDLIBS += -lws2_32
|
||||
UHUB_CONF_DIR ?= c:/uhub/
|
||||
UHUB_PREFIX ?= c:/uhub/
|
||||
CFLAGS += -mno-cygwin
|
||||
LDFLAGS += -mno-cygwin
|
||||
BIN_EXT ?= .exe
|
||||
else
|
||||
DESTDIR ?= /
|
||||
UHUB_CONF_DIR ?= $(DESTDIR)/etc/uhub
|
||||
UHUB_PREFIX ?= $(DESTDIR)/usr/local
|
||||
UHUB_MOD_DIR ?= $(DESTDIR)/var/lib/uhub
|
||||
CFLAGS += -I/usr/local/include
|
||||
LDFLAGS += -L/usr/local/lib
|
||||
BIN_EXT ?=
|
||||
endif
|
||||
|
||||
ifeq ($(SILENT),YES)
|
||||
MSG_CC=@echo " CC:" $(notdir $<) &&
|
||||
MSG_LD=@echo " LD:" $(notdir $@) &&
|
||||
MSG_AR=@echo " AR:" $(notdir $@) &&
|
||||
else
|
||||
MSG_CC=
|
||||
MSG_LD=
|
||||
MSG_AR=
|
||||
endif
|
||||
|
||||
ifeq ($(TERSE), YES)
|
||||
MSG_CC=@
|
||||
MSG_LD=@
|
||||
MSG_AR=@
|
||||
MSG_CLEAN=-n ""
|
||||
else
|
||||
MSG_CLEAN="Clean as a whistle"
|
||||
endif
|
||||
|
||||
ifeq ($(RELEASE),YES)
|
||||
CFLAGS += -O3 -DNDEBUG
|
||||
else
|
||||
CFLAGS += -ggdb -DDEBUG
|
||||
endif
|
||||
|
||||
ifeq ($(STACK_PROTECT),YES)
|
||||
CFLAGS += -fstack-protector-all
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(PROFILING),YES)
|
||||
CFLAGS += -pg
|
||||
LDFLAGS += -pg
|
||||
endif
|
||||
|
||||
ifeq ($(FUNCTRACE),YES)
|
||||
CFLAGS += -finstrument-functions
|
||||
CFLAGS += -DDEBUG_FUNCTION_TRACE
|
||||
endif
|
||||
|
||||
ifneq ($(BITS), AUTO)
|
||||
ifeq ($(BITS), 64)
|
||||
CFLAGS += -m64
|
||||
LDFLAGS += -m64
|
||||
else
|
||||
ifeq ($(BITS), 32)
|
||||
CFLAGS += -m32
|
||||
LDFLAGS += -m32
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(USE_BIGENDIAN),AUTO)
|
||||
ifeq ($(shell perl -e 'print pack("L", 0x554E4958)'),UNIX)
|
||||
CFLAGS += -DARCH_BIGENDIAN
|
||||
endif
|
||||
else
|
||||
ifeq ($(USE_BIGENDIAN),YES)
|
||||
CFLAGS += -DARCH_BIGENDIAN
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(USE_SSL),YES)
|
||||
CFLAGS += -DSSL_SUPPORT
|
||||
LDLIBS += -lssl -lcrypto
|
||||
endif
|
||||
|
||||
ifeq ($(NEED_LIBDL),YES)
|
||||
LDLIBS += -ldl
|
||||
endif
|
||||
|
||||
GIT_VERSION=$(shell git describe --tags 2>/dev/null || echo "")
|
||||
GIT_REVISION=$(shell git show --abbrev-commit 2>/dev/null | head -n 1 | cut -f 2 -d " " || echo "")
|
||||
OLD_REVISION=$(shell grep GIT_REVISION revision.h 2>/dev/null | cut -f 3 -d " " | tr -d "\"")
|
||||
|
||||
# Sources
|
||||
libuhub_SOURCES := \
|
||||
src/core/auth.c \
|
||||
src/core/commands.c \
|
||||
src/core/config.c \
|
||||
src/core/eventqueue.c \
|
||||
src/core/hub.c \
|
||||
src/core/hubevent.c \
|
||||
src/core/hubio.c \
|
||||
src/core/inf.c \
|
||||
src/core/netevent.c \
|
||||
src/core/probe.c \
|
||||
src/core/route.c \
|
||||
src/core/user.c \
|
||||
src/core/usermanager.c \
|
||||
src/core/plugincallback.c \
|
||||
src/core/plugininvoke.c \
|
||||
src/core/pluginloader.c \
|
||||
src/network/backend.c \
|
||||
src/network/connection.c \
|
||||
src/network/epoll.c \
|
||||
src/network/kqueue.c \
|
||||
src/network/select.c \
|
||||
src/network/timeout.c \
|
||||
src/network/timer.c
|
||||
|
||||
|
||||
libadc_common_SOURCES := \
|
||||
src/adc/message.c \
|
||||
src/adc/sid.c
|
||||
|
||||
libutils_SOURCES := \
|
||||
src/util/cbuffer.c \
|
||||
src/util/config_token.c \
|
||||
src/util/credentials.c \
|
||||
src/util/floodctl.c \
|
||||
src/util/ipcalc.c \
|
||||
src/util/list.c \
|
||||
src/util/log.c \
|
||||
src/util/memory.c \
|
||||
src/util/misc.c \
|
||||
src/network/network.c \
|
||||
src/util/rbtree.c \
|
||||
src/util/tiger.c
|
||||
|
||||
libadc_client_SOURCES := \
|
||||
src/tools/adcclient.c
|
||||
|
||||
uhub_SOURCES := src/core/main.c
|
||||
|
||||
uhub-passwd_SOURCES := src/tools/uhub-passwd.c
|
||||
uhub-passwd_LIBS := -lsqlite3
|
||||
|
||||
adcrush_SOURCES := src/tools/adcrush.c
|
||||
|
||||
admin_SOURCES := src/tools/admin.c
|
||||
|
||||
autotest_SOURCES := \
|
||||
autotest/test_commands.tcc \
|
||||
autotest/test_credentials.tcc \
|
||||
autotest/test_eventqueue.tcc \
|
||||
autotest/test_hub.tcc \
|
||||
autotest/test_inf.tcc \
|
||||
autotest/test_ipfilter.tcc \
|
||||
autotest/test_list.tcc \
|
||||
autotest/test_memory.tcc \
|
||||
autotest/test_message.tcc \
|
||||
autotest/test_misc.tcc \
|
||||
autotest/test_sid.tcc \
|
||||
autotest/test_tiger.tcc \
|
||||
autotest/test_timer.tcc \
|
||||
autotest/test_tokenizer.tcc \
|
||||
autotest/test_usermanager.tcc
|
||||
|
||||
autotest_OBJECTS = autotest.o
|
||||
|
||||
# Plugin targets:
|
||||
plugin_example_SOURCES := src/plugins/mod_example.c
|
||||
plugin_example_TARGET := mod_example.so
|
||||
|
||||
plugin_welcome_SOURCES := src/plugins/mod_welcome.c
|
||||
plugin_welcome_TARGET := mod_welcome.so
|
||||
|
||||
plugin_logging_SOURCES := src/plugins/mod_logging.c
|
||||
plugin_logging_TARGET := mod_logging.so
|
||||
|
||||
plugin_auth_SOURCES := src/plugins/mod_auth_simple.c
|
||||
plugin_auth_TARGET := mod_auth_simple.so
|
||||
|
||||
plugin_auth_sqlite_SOURCES := src/plugins/mod_auth_sqlite.c
|
||||
plugin_auth_sqlite_TARGET := mod_auth_sqlite.so
|
||||
plugin_auth_sqlite_LIBS := -lsqlite3
|
||||
|
||||
plugin_chat_history_SOURCE := src/plugins/mod_chat_history.c
|
||||
plugin_chat_history_TARGET := mod_chat_history.so
|
||||
|
||||
plugin_chat_only_SOURCE := src/plugins/mod_chat_only.c
|
||||
plugin_chat_only_TARGET := mod_chat_only.so
|
||||
|
||||
# Source to objects
|
||||
libuhub_OBJECTS := $(libuhub_SOURCES:.c=.o)
|
||||
libutils_OBJECTS := $(libutils_SOURCES:.c=.o)
|
||||
libadc_client_OBJECTS := $(libadc_client_SOURCES:.c=.o)
|
||||
libadc_common_OBJECTS := $(libadc_common_SOURCES:.c=.o)
|
||||
|
||||
uhub_OBJECTS := $(uhub_SOURCES:.c=.o)
|
||||
uhub-passwd_OBJECTS := $(uhub-passwd_SOURCES:.c=.o)
|
||||
adcrush_OBJECTS := $(adcrush_SOURCES:.c=.o)
|
||||
admin_OBJECTS := $(admin_SOURCES:.c=.o)
|
||||
|
||||
all_plugins := $(plugin_example_TARGET) $(plugin_logging_TARGET) $(plugin_auth_TARGET) $(plugin_auth_sqlite_TARGET) $(plugin_welcome_TARGET) $(plugin_chat_history_TARGET) $(plugin_chat_only_TARGET)
|
||||
all_OBJECTS := $(libuhub_OBJECTS) $(uhub_OBJECTS) $(libutils_OBJECTS) $(adcrush_OBJECTS) $(autotest_OBJECTS) $(admin_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||
all_OBJECTS += $(all_plugins)
|
||||
|
||||
uhub_BINARY=uhub$(BIN_EXT)
|
||||
uhub-passwd_BINARY=uhub-passwd$(BIN_EXT)
|
||||
adcrush_BINARY=adcrush$(BIN_EXT)
|
||||
admin_BINARY=uhub-admin$(BIN_EXT)
|
||||
autotest_BINARY=autotest/test$(BIN_EXT)
|
||||
|
||||
|
||||
.PHONY: revision.h.tmp all plugins
|
||||
|
||||
%.o: %.c version.h revision.h
|
||||
$(MSG_CC) $(CC) -fPIC -c $(CFLAGS) -o $@ $<
|
||||
|
||||
|
||||
#%.so: %.c
|
||||
# $(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
|
||||
all: $(uhub_BINARY) $(uhub-passwd_BINARY) plugins
|
||||
|
||||
plugins: $(uhub_BINARY) $(all_plugins)
|
||||
|
||||
$(plugin_auth_TARGET): $(plugin_auth_SOURCES) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(plugin_auth_sqlite_TARGET): $(plugin_auth_sqlite_SOURCES) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS) $(LDFLAGS) $(plugin_auth_sqlite_LIBS)
|
||||
|
||||
$(plugin_example_TARGET): $(plugin_example_SOURCES) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(plugin_logging_TARGET): $(plugin_logging_SOURCES) $(libutils_OBJECTS) $(libadc_common_OBJECTS) src/network/network.o
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(plugin_chat_history_TARGET): $(plugin_chat_history_SOURCE) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(plugin_chat_only_TARGET): $(plugin_chat_only_SOURCE) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(plugin_welcome_TARGET): $(plugin_welcome_SOURCES) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(adcrush_BINARY): $(adcrush_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
$(admin_BINARY): $(admin_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
$(uhub_BINARY): $(uhub_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS)
|
||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
$(uhub-passwd_BINARY): $(uhub-passwd_OBJECTS)
|
||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS) $(uhub-passwd_LIBS)
|
||||
|
||||
|
||||
autotest.c: $(autotest_SOURCES)
|
||||
$(shell exotic --standalone $(autotest_SOURCES) > $@)
|
||||
|
||||
revision.h.tmp:
|
||||
@rm -f $@
|
||||
@echo "/* AUTOGENERATED FILE - DO NOT EDIT */" > $@
|
||||
@if [ -n '$(GIT_VERSION)' ]; then echo \#define GIT_VERSION \"$(GIT_VERSION)\" >> $@; fi
|
||||
@if [ -n '$(GIT_REVISION)' ]; then echo \#define GIT_REVISION \"$(GIT_REVISION)\" >> $@; fi
|
||||
|
||||
version.h: revision.h
|
||||
|
||||
revision.h: revision.h.tmp
|
||||
@if [ '$(GIT_REVISION)' != '$(OLD_REVISION)' ]; then cp $@.tmp $@; fi
|
||||
@if [ ! -f $@ ]; then cp $@.tmp $@; fi
|
||||
|
||||
$(autotest_OBJECTS): autotest.c
|
||||
$(MSG_CC) $(CC) -c $(CFLAGS) -Isrc -o $@ $<
|
||||
|
||||
$(autotest_BINARY): $(autotest_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
autotest: $(autotest_BINARY)
|
||||
@./$(autotest_BINARY) -s -f
|
||||
|
||||
ifeq ($(WINDOWS),YES)
|
||||
install:
|
||||
@echo "Cannot install automatically on windows."
|
||||
else
|
||||
install: $(uhub_BINARY)
|
||||
@echo Copying $(uhub_BINARY) to $(UHUB_PREFIX)/bin/
|
||||
@cp $(uhub_BINARY) $(UHUB_PREFIX)/bin/
|
||||
@cp $(uhub-passwd_BINARY) $(UHUB_PREFIX)/bin/
|
||||
@if [ ! -d $(UHUB_CONF_DIR) ]; then echo Creating $(UHUB_CONF_DIR); mkdir -p $(UHUB_CONF_DIR); fi
|
||||
@if [ ! -f $(UHUB_CONF_DIR)/uhub.conf ]; then cp doc/uhub.conf $(UHUB_CONF_DIR); fi
|
||||
@if [ ! -f $(UHUB_CONF_DIR)/rules.txt ]; then cp doc/rules.txt $(UHUB_CONF_DIR); fi
|
||||
@if [ ! -f $(UHUB_CONF_DIR)/plugins.conf ]; then cp doc/plugins.conf $(UHUB_CONF_DIR); fi
|
||||
@if [ ! -d $(UHUB_MOD_DIR) ]; then echo Creating $(UHUB_MOD_DIR); mkdir -p $(UHUB_MOD_DIR); fi
|
||||
@cp -f mod_*.so $(UHUB_MOD_DIR)
|
||||
@touch $(UHUB_CONF_DIR)/motd.txt
|
||||
@echo done.
|
||||
endif
|
||||
|
||||
dist-clean:
|
||||
@rm -rf $(all_OBJECTS) *~ core
|
||||
|
||||
clean:
|
||||
@rm -rf $(libuhub_OBJECTS) *~ core $(uhub_BINARY) $(admin_BINARY) $(autotest_BINARY) $(adcrush_BINARY) $(all_OBJECTS) $(all_plugins) autotest.c revision.h revision.h.tmp && \
|
||||
echo $(MSG_CLEAN)
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
Welcome and thanks for downloading uHub, a high performance ADC p2p hub.
|
||||
|
||||
For the official documentation, bugs and other information, please visit:
|
||||
http://www.uhub.org/
|
||||
|
||||
For a list of compatible ADC clients, see:
|
||||
http://www.adcportal.com/wiki/index.php/ADC_Software_List#Client_Software
|
||||
|
||||
-140
@@ -1,140 +0,0 @@
|
||||
HOST_SYSTEM=`uname -s | tr [:upper:] [:lower:] | sed s/darwin/macosx/`
|
||||
|
||||
if [ "${HOST_SYSTEM}" = "macosx" ]; then
|
||||
HOST_MACHINE=`uname -p | tr [:upper:] [:lower:]`
|
||||
else
|
||||
HOST_MACHINE=`uname -m | tr [:upper:] [:lower:] | sed s/i686/i386/ | sed s/x86_64/amd64/ | sed s/ppc64/powerpc/`
|
||||
fi
|
||||
|
||||
BINSUFFIX=
|
||||
MAKEARGS=
|
||||
MAKE=make
|
||||
WANTZIP=0
|
||||
|
||||
if [ "${HOST_SYSTEM}" = "mingw32_nt-5.1" ]; then
|
||||
HOST_SYSTEM=win32
|
||||
BINSUFFIX=.exe
|
||||
WANTZIP=1
|
||||
MAKEARGS="USE_BIGENDIAN=NO"
|
||||
fi
|
||||
|
||||
BINARY=uhub${BINSUFFIX}
|
||||
|
||||
if [ "${HOST_SYSTEM}" = "freebsd" ]; then
|
||||
MAKE=gmake
|
||||
fi
|
||||
|
||||
VERSION=`grep define\ VERSION version.h | cut -f 3 -d " " | tr -d [=\"=]`
|
||||
SNAPSHOT=`date '+%Y%m%d'`
|
||||
PACKAGE=uhub-${VERSION}
|
||||
PACKAGE_SRC=${PACKAGE}-src
|
||||
PACKAGE_BIN=${PACKAGE}-${HOST_SYSTEM}-${HOST_MACHINE}
|
||||
ARCHIVE='build-archive:~/www/downloads/uhub/'
|
||||
|
||||
function export_source_directory
|
||||
{
|
||||
if [ -d ${PACKAGE} ]; then
|
||||
rm -Rf ${PACKAGE};
|
||||
fi
|
||||
|
||||
if [ ! -d .git ]; then
|
||||
echo "No git repo found in `dirname $0`"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git archive --format=tar --prefix=${PACKAGE}/ HEAD > tmp.tar && tar -xf tmp.tar && rm tmp.tar
|
||||
|
||||
if [ ! -d ${PACKAGE} ]; then
|
||||
echo "Something went wrong while exporting the repo."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function package_zips
|
||||
{
|
||||
tar cf $1.tar $2
|
||||
gzip -c -9 $1.tar > $1.tar.gz
|
||||
bzip2 -c -9 $1.tar > $1.tar.bz2
|
||||
rm -f $1.tar
|
||||
|
||||
if [ $WANTZIP -eq 1 ]; then
|
||||
zip -q -9 -r $1.zip $2
|
||||
fi
|
||||
}
|
||||
|
||||
function export_sources
|
||||
{
|
||||
if [ ! -d ${PACKAGE} ]; then
|
||||
export_source_directory
|
||||
fi
|
||||
|
||||
cd ${PACKAGE}
|
||||
${MAKE} ${MAKEARGS} autotest.c
|
||||
cd ..
|
||||
|
||||
if [ ! -f ${PACKAGE}/autotest.c ]; then
|
||||
echo "Unable to create autotest.c, aborting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -Rf ${PACKAGE}/admin
|
||||
package_zips ${PACKAGE_SRC} ${PACKAGE}
|
||||
|
||||
rm -Rf ${PACKAGE};
|
||||
cp ChangeLog ChangeLog-${VERSION}
|
||||
}
|
||||
|
||||
function build_binaries
|
||||
{
|
||||
if [ ! -d ${PACKAGE} ]; then
|
||||
export_source_directory
|
||||
fi
|
||||
|
||||
cd ${PACKAGE}
|
||||
${MAKE} ${MAKEARGS} RELEASE=YES
|
||||
cd ..
|
||||
|
||||
if [ ! -x ${PACKAGE}/${BINARY} ]; then
|
||||
echo "Build failed, no binary found..."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function export_binaries
|
||||
{
|
||||
build_binaries
|
||||
|
||||
rm -Rf ${PACKAGE}/admin
|
||||
rm -Rf ${PACKAGE}/autotest
|
||||
rm -Rf ${PACKAGE}/src
|
||||
rm -Rf ${PACKAGE}/debian
|
||||
rm -f ${PACKAGE}/autotest.c
|
||||
rm -f ${PACKAGE}/*akefile
|
||||
rm -f ${PACKAGE}/version.h
|
||||
rm -f ${PACKAGE}/doc/Doxyfile
|
||||
rm -f ${PACKAGE}/doc/uhub.dot
|
||||
rm -f ${PACKAGE}/libuhub*
|
||||
|
||||
package_zips ${PACKAGE_BIN} ${PACKAGE}
|
||||
rm -Rf ${PACKAGE}
|
||||
}
|
||||
|
||||
function upload_pkg
|
||||
{
|
||||
if [ -f $1 ]; then
|
||||
scp $1 ${ARCHIVE}
|
||||
fi
|
||||
}
|
||||
|
||||
function upload_packages
|
||||
{
|
||||
upload_pkg ${PACKAGE_SRC}.tar.gz
|
||||
upload_pkg ${PACKAGE_SRC}.tar.bz2
|
||||
upload_pkg ${PACKAGE_SRC}.zip
|
||||
upload_pkg ChangeLog-${VERSION}
|
||||
upload_pkg ${PACKAGE_BIN}.tar.gz
|
||||
upload_pkg ${PACKAGE_BIN}.tar.bz2
|
||||
upload_pkg ${PACKAGE_BIN}.zip
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
. admin/common.sh
|
||||
export_source_directory
|
||||
@@ -1,95 +0,0 @@
|
||||
#!/bin/sh
|
||||
. admin/common.sh
|
||||
|
||||
export_source_directory
|
||||
build_binaries
|
||||
|
||||
DEB_REVISION=1
|
||||
|
||||
if [ -d deb ]; then
|
||||
rm -Rf deb
|
||||
fi
|
||||
|
||||
mkdir -p \
|
||||
deb/DEBIAN \
|
||||
deb/usr/bin \
|
||||
deb/usr/share/man/man1/ \
|
||||
deb/usr/share/doc/uhub \
|
||||
deb/etc/uhub \
|
||||
|| exit 1
|
||||
|
||||
find deb -type d | xargs chmod 755
|
||||
|
||||
# Copy binaries...
|
||||
cp ${PACKAGE}/${BINARY} deb/usr/bin
|
||||
strip deb/usr/bin/${BINARY}
|
||||
|
||||
# Copy configuration files...
|
||||
cp ${PACKAGE}/doc/uhub.conf deb/etc/uhub
|
||||
cp ${PACKAGE}/doc/users.conf deb/etc/uhub
|
||||
echo "Welcome to uHub" > deb/etc/uhub/motd.txt
|
||||
|
||||
# Copy other files
|
||||
cp ${PACKAGE}/README deb/usr/share/doc/uhub
|
||||
cp ${PACKAGE}/AUTHORS deb/usr/share/doc/uhub
|
||||
gzip -c --best < ${PACKAGE}/ChangeLog > deb/usr/share/doc/uhub/changelog.gz
|
||||
gzip -c --best < ${PACKAGE}/doc/uhub.1 > deb/usr/share/man/man1/uhub.1.gz
|
||||
|
||||
cat > deb/usr/share/doc/uhub/copyright <<EOF
|
||||
uHub - a high performance hub for the ADC peer-to-peer network
|
||||
|
||||
Copyright (C) 2007-2009 Jan Vidar Krey <janvidar@extatic.org>
|
||||
|
||||
uHub is free and open source software, licensed under the
|
||||
GNU General Public License version 3.
|
||||
|
||||
For details, see /usr/share/common-licenses/GPL-3
|
||||
EOF
|
||||
|
||||
gzip -c --best > deb/usr/share/doc/uhub/changelog.Debian.gz <<EOF
|
||||
uhub (${VERSION}) stable; urgency=low
|
||||
|
||||
* See changelog.gz for details.
|
||||
|
||||
-- Jan Vidar Krey <janvidar@extatic.org> `date -R`
|
||||
EOF
|
||||
|
||||
### Write control files
|
||||
cd deb
|
||||
echo "/etc/uhub/uhub.conf" > DEBIAN/conffiles
|
||||
echo "/etc/uhub/users.conf" >> DEBIAN/conffiles
|
||||
echo "/etc/uhub/motd.txt" >> DEBIAN/conffiles
|
||||
|
||||
md5sum `find usr -type f` > DEBIAN/md5sums
|
||||
|
||||
INSTALL_SIZE=`du -s | cut -f 1`
|
||||
|
||||
cat > DEBIAN/control <<EOF
|
||||
Package: uhub
|
||||
Version: ${VERSION}-${DEB_REVISION}
|
||||
Architecture: ${HOST_MACHINE}
|
||||
Maintainer: Jan Vidar Krey <janvidar@extatic.org>
|
||||
Installed-Size: ${INSTALL_SIZE}
|
||||
Depends: libc6 (>= 2.7-1), libevent1 (>= 1.3e-1)
|
||||
Section: net
|
||||
Priority: optional
|
||||
Description: a high performance hub for the ADC peer-to-peer network
|
||||
uHub is a high performance peer-to-peer hub for the ADC network.
|
||||
Its low memory footprint allows it to handle several thousand users
|
||||
on high-end servers, or a small private hub on embedded hardware.
|
||||
.
|
||||
Homepage: http://www.extatic.org/uhub/
|
||||
EOF
|
||||
cd ..
|
||||
|
||||
### Create deb file
|
||||
fakeroot dpkg-deb --build deb
|
||||
mv deb.deb uhub_${VERSION}-${DEB_REVISION}_${HOST_MACHINE}.deb
|
||||
|
||||
### Check for errors
|
||||
lintian uhub_${VERSION}-${DEB_REVISION}_${HOST_MACHINE}.deb
|
||||
|
||||
### Cleanup
|
||||
rm -Rf deb
|
||||
rm -Rf ${PACKAGE}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
. admin/common.sh
|
||||
export_binaries
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
. admin/common.sh
|
||||
WANTZIP=1
|
||||
export_sources
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
PUB="${HOME}/.ssh/id_rsa.pub"
|
||||
CFG="${HOME}/.ssh/config"
|
||||
|
||||
if [ ! "`grep build-archive ${CFG}`" ]; then
|
||||
echo "Updating ssh config (${CFG})..."
|
||||
cat >> ${CFG} <<EOF
|
||||
|
||||
Host build-archive
|
||||
ForwardX11 no
|
||||
HostName login.domeneshop.no
|
||||
User extatic
|
||||
EOF
|
||||
else
|
||||
echo "ssh config seems OK (${CFG})"
|
||||
fi
|
||||
|
||||
if [ ! -f ${PUB} ]; then
|
||||
echo "No id_rsa.pub - run ssh-keygen"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Copying public key (${PUB})..."
|
||||
cat ${PUB} | ssh build-archive "cat >> .ssh/authorized_keys"
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
. admin/common.sh
|
||||
upload_packages
|
||||
@@ -1,146 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
static struct hub_info* hub = NULL;
|
||||
static struct hub_user user;
|
||||
static struct command_base* cbase = NULL;
|
||||
static struct command_handle* c_test1 = NULL;
|
||||
static struct command_handle* c_test2 = NULL;
|
||||
static struct command_handle* c_test3 = NULL;
|
||||
static struct command_handle* c_test4 = NULL;
|
||||
static struct command_handle* c_test5 = NULL;
|
||||
static struct command_handle* c_test6 = NULL;
|
||||
static struct command_handle* c_test7 = NULL;
|
||||
|
||||
// for results:
|
||||
static int result = 0;
|
||||
|
||||
EXO_TEST(setup, {
|
||||
hub = hub_malloc_zero(sizeof(struct hub_info));
|
||||
cbase = command_initialize(hub);
|
||||
return cbase && hub && uman_init(hub) == 0;
|
||||
});
|
||||
|
||||
static int test_handler(struct command_base* cbase, struct hub_user* user, struct hub_command* hcmd)
|
||||
{
|
||||
result = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct command_handle* create_handler(const char* prefix, const char* args, enum auth_credentials cred)
|
||||
{
|
||||
struct command_handle* c = hub_malloc_zero(sizeof(struct command_handle));
|
||||
c->prefix = prefix;
|
||||
c->length = strlen(prefix);
|
||||
c->args = args;
|
||||
c->cred = cred;
|
||||
c->handler = test_handler;
|
||||
c->description = "A handler added by autotest.";
|
||||
c->description = "exotic";
|
||||
c->ptr = &c->ptr;
|
||||
return c;
|
||||
}
|
||||
|
||||
EXO_TEST(command_setup_user, {
|
||||
memset(&user, 0, sizeof(user));
|
||||
user.id.sid = 1;
|
||||
strcpy(user.id.nick, "tester");
|
||||
strcpy(user.id.cid, "3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY");
|
||||
user.credentials = auth_cred_guest;
|
||||
return 1;
|
||||
});
|
||||
|
||||
#define ADD_TEST(var, prefix, args, cred) \
|
||||
var = create_handler(prefix, args, cred); \
|
||||
if (!command_add(cbase, var, NULL)) \
|
||||
return 0;
|
||||
|
||||
#define DEL_TEST(var) \
|
||||
if (var) \
|
||||
{ \
|
||||
if (!command_del(cbase, var)) \
|
||||
return 0; \
|
||||
hub_free(var); \
|
||||
var = NULL; \
|
||||
}
|
||||
|
||||
EXO_TEST(command_create, {
|
||||
ADD_TEST(c_test1, "test1", "", auth_cred_guest);
|
||||
ADD_TEST(c_test2, "test2", "", auth_cred_operator);
|
||||
ADD_TEST(c_test3, "test3", "N?N?N", auth_cred_guest);
|
||||
ADD_TEST(c_test4, "test4", "n", auth_cred_guest);
|
||||
ADD_TEST(c_test5, "test5", "i", auth_cred_guest);
|
||||
ADD_TEST(c_test6, "test6", "?c", auth_cred_guest);
|
||||
ADD_TEST(c_test6, "test7", "C", auth_cred_guest);
|
||||
return 1;
|
||||
});
|
||||
|
||||
extern void command_destroy(struct hub_command* cmd);
|
||||
|
||||
static int verify(const char* str, enum command_parse_status expected)
|
||||
{
|
||||
struct hub_command* cmd = command_parse(cbase, &user, str);
|
||||
enum command_parse_status status = cmd->status;
|
||||
command_free(cmd);
|
||||
return status == expected;
|
||||
}
|
||||
|
||||
EXO_TEST(command_access_1, { return verify("!test1", cmd_status_ok); });
|
||||
EXO_TEST(command_access_2, { return verify("!test2", cmd_status_access_error); });
|
||||
EXO_TEST(command_access_3, { user.credentials = auth_cred_operator; return verify("!test2", cmd_status_ok); });
|
||||
|
||||
EXO_TEST(command_syntax_1, { return verify("", cmd_status_syntax_error); });
|
||||
EXO_TEST(command_syntax_2, { return verify("!", cmd_status_syntax_error); });
|
||||
|
||||
EXO_TEST(command_missing_args_1, { return verify("!test3", cmd_status_missing_args); });
|
||||
EXO_TEST(command_missing_args_2, { return verify("!test3 12345", cmd_status_ok); });
|
||||
EXO_TEST(command_missing_args_3, { return verify("!test3 1 2 345", cmd_status_ok); });
|
||||
EXO_TEST(command_number_1, { return verify("!test3 abc", cmd_status_arg_number); });
|
||||
EXO_TEST(command_number_2, { return verify("!test3 -", cmd_status_arg_number); });
|
||||
EXO_TEST(command_number_3, { return verify("!test3 -12", cmd_status_ok); });
|
||||
|
||||
EXO_TEST(command_user_1, { return verify("!test4 tester", cmd_status_arg_nick); });
|
||||
EXO_TEST(command_user_2, { return verify("!test5 3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY", cmd_status_arg_cid); });
|
||||
EXO_TEST(command_user_3, { return uman_add(hub, &user) == 0; });
|
||||
EXO_TEST(command_user_4, { return verify("!test4 tester", cmd_status_ok); });
|
||||
EXO_TEST(command_user_5, { return verify("!test5 3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY", cmd_status_ok); });
|
||||
|
||||
EXO_TEST(command_command_1, { return verify("!test6 test1", cmd_status_ok); });
|
||||
EXO_TEST(command_command_2, { return verify("!test6 test2", cmd_status_ok); });
|
||||
EXO_TEST(command_command_3, { return verify("!test6 test3", cmd_status_ok); });
|
||||
EXO_TEST(command_command_4, { return verify("!test6 test4", cmd_status_ok); });
|
||||
EXO_TEST(command_command_5, { return verify("!test6 test5", cmd_status_ok); });
|
||||
EXO_TEST(command_command_6, { return verify("!test6 test6", cmd_status_ok); });
|
||||
EXO_TEST(command_command_7, { return verify("!test6 fail", cmd_status_arg_command); });
|
||||
EXO_TEST(command_command_8, { return verify("!test6", cmd_status_ok); });
|
||||
|
||||
EXO_TEST(command_cred_1, { return verify("!test7 guest", cmd_status_ok); });
|
||||
EXO_TEST(command_cred_2, { return verify("!test7 user", cmd_status_ok); });
|
||||
EXO_TEST(command_cred_3, { return verify("!test7 operator", cmd_status_ok); });
|
||||
EXO_TEST(command_cred_4, { return verify("!test7 super", cmd_status_ok); });
|
||||
EXO_TEST(command_cred_5, { return verify("!test7 admin", cmd_status_ok); });
|
||||
EXO_TEST(command_cred_6, { return verify("!test7 nobody", cmd_status_arg_cred); });
|
||||
EXO_TEST(command_cred_7, { return verify("!test7 bot", cmd_status_ok); });
|
||||
EXO_TEST(command_cred_8, { return verify("!test7 link", cmd_status_ok); });
|
||||
|
||||
|
||||
#if 0
|
||||
cmd_status_arg_cred, /** <<< "A credentials argument is not valid ('C')" */
|
||||
};
|
||||
#endif
|
||||
|
||||
// command not found
|
||||
EXO_TEST(command_parse_3, { return verify("!fail", cmd_status_not_found); });
|
||||
|
||||
// built-in command
|
||||
EXO_TEST(command_parse_4, { return verify("!help", cmd_status_ok); });
|
||||
|
||||
EXO_TEST(command_destroy, {
|
||||
DEL_TEST(c_test1);
|
||||
DEL_TEST(c_test2);
|
||||
DEL_TEST(c_test3);
|
||||
DEL_TEST(c_test4);
|
||||
DEL_TEST(c_test5);
|
||||
DEL_TEST(c_test6);
|
||||
DEL_TEST(c_test7);
|
||||
return 1;
|
||||
});
|
||||
@@ -1,24 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
EXO_TEST(cred_to_string_1, { return !strcmp(auth_cred_to_string(auth_cred_none), "none"); });
|
||||
EXO_TEST(cred_to_string_2, { return !strcmp(auth_cred_to_string(auth_cred_bot), "bot"); });
|
||||
EXO_TEST(cred_to_string_3, { return !strcmp(auth_cred_to_string(auth_cred_guest), "guest"); });
|
||||
EXO_TEST(cred_to_string_4, { return !strcmp(auth_cred_to_string(auth_cred_user), "user"); });
|
||||
EXO_TEST(cred_to_string_5, { return !strcmp(auth_cred_to_string(auth_cred_operator), "operator"); });
|
||||
EXO_TEST(cred_to_string_6, { return !strcmp(auth_cred_to_string(auth_cred_super), "super"); });
|
||||
EXO_TEST(cred_to_string_7, { return !strcmp(auth_cred_to_string(auth_cred_link), "link"); });
|
||||
EXO_TEST(cred_to_string_8, { return !strcmp(auth_cred_to_string(auth_cred_admin), "admin"); });
|
||||
|
||||
#define CRED_FROM_STRING(STR, EXPECT) enum auth_credentials cred; return auth_string_to_cred(STR, &cred) && cred == EXPECT;
|
||||
|
||||
EXO_TEST(cred_from_string_1, { CRED_FROM_STRING("none", auth_cred_none); });
|
||||
EXO_TEST(cred_from_string_2, { CRED_FROM_STRING("bot", auth_cred_bot); });
|
||||
EXO_TEST(cred_from_string_3, { CRED_FROM_STRING("guest", auth_cred_guest); });
|
||||
EXO_TEST(cred_from_string_4, { CRED_FROM_STRING("user", auth_cred_user); });
|
||||
EXO_TEST(cred_from_string_5, { CRED_FROM_STRING("reg", auth_cred_user); });
|
||||
EXO_TEST(cred_from_string_6, { CRED_FROM_STRING("operator", auth_cred_operator); });
|
||||
EXO_TEST(cred_from_string_7, { CRED_FROM_STRING("op", auth_cred_operator); });
|
||||
EXO_TEST(cred_from_string_8, { CRED_FROM_STRING("super", auth_cred_super); });
|
||||
EXO_TEST(cred_from_string_9, { CRED_FROM_STRING("link", auth_cred_link); });
|
||||
EXO_TEST(cred_from_string_10, { CRED_FROM_STRING("admin", auth_cred_admin); });
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
static struct event_queue* eq;
|
||||
static int eq_val;
|
||||
|
||||
static void eq_callback(void* callback_data, struct event_data* event_data)
|
||||
{
|
||||
eq_val += event_data->id;
|
||||
}
|
||||
|
||||
EXO_TEST(eventqueue_init_1, {
|
||||
eq = 0;
|
||||
eq_val = 0;
|
||||
return event_queue_initialize(&eq, eq_callback, &eq_val) == 0 && event_queue_size(eq) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(eventqueue_init_2, {
|
||||
/* hack */
|
||||
return eq->callback_data == &eq_val && eq->callback == eq_callback && eq->q1 && eq->q2 && !eq->locked;
|
||||
});
|
||||
|
||||
EXO_TEST(eventqueue_post_1, {
|
||||
struct event_data message;
|
||||
message.id = 0x1001;
|
||||
message.ptr = &message;
|
||||
message.flags = message.id * 2;
|
||||
event_queue_post(eq, &message);
|
||||
return event_queue_size(eq) == 1;
|
||||
});
|
||||
|
||||
EXO_TEST(eventqueue_process_1, {
|
||||
event_queue_process(eq);
|
||||
return eq_val == 0x1001;
|
||||
});
|
||||
|
||||
EXO_TEST(eventqueue_size_1, {
|
||||
eq_val = 0;
|
||||
return event_queue_size(eq) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(eventqueue_post_2, {
|
||||
struct event_data message;
|
||||
message.id = 0x1002;
|
||||
message.ptr = &message;
|
||||
message.flags = message.id * 2;
|
||||
event_queue_post(eq, &message);
|
||||
return event_queue_size(eq) == 1;
|
||||
});
|
||||
|
||||
EXO_TEST(eventqueue_size_2, {
|
||||
eq_val = 0;
|
||||
return event_queue_size(eq) == 1;
|
||||
});
|
||||
|
||||
|
||||
EXO_TEST(eventqueue_post_3, {
|
||||
struct event_data message;
|
||||
message.id = 0x1003;
|
||||
message.ptr = &message;
|
||||
message.flags = message.id * 2;
|
||||
event_queue_post(eq, &message);
|
||||
return event_queue_size(eq) == 2;
|
||||
});
|
||||
|
||||
EXO_TEST(eventqueue_size_3, {
|
||||
eq_val = 0;
|
||||
return event_queue_size(eq) == 2;
|
||||
});
|
||||
|
||||
EXO_TEST(eventqueue_process_2, {
|
||||
event_queue_process(eq);
|
||||
return eq_val == 0x2005;
|
||||
});
|
||||
|
||||
EXO_TEST(eventqueue_size_4, {
|
||||
eq_val = 0;
|
||||
return event_queue_size(eq) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(eventqueue_shutdown_1, {
|
||||
event_queue_shutdown(eq);
|
||||
return 1;
|
||||
});
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
static struct hub_config g_config;
|
||||
static struct acl_handle g_acl;
|
||||
static struct hub_info* g_hub;
|
||||
|
||||
/*
|
||||
static void create_test_user()
|
||||
{
|
||||
if (g_user)
|
||||
return;
|
||||
|
||||
g_user = (struct hub_user*) malloc(sizeof(struct hub_user));
|
||||
memset(g_user, 0, sizeof(struct hub_user));
|
||||
memcpy(g_user->id.nick, "exotic-tester", 13);
|
||||
g_user->sid = 1;
|
||||
}
|
||||
*/
|
||||
|
||||
EXO_TEST(hub_net_startup, {
|
||||
return (net_initialize() != -1);
|
||||
});
|
||||
|
||||
EXO_TEST(hub_config_initialize, {
|
||||
config_defaults(&g_config);
|
||||
g_config.server_port = 65111;
|
||||
return 1;
|
||||
});
|
||||
|
||||
EXO_TEST(hub_acl_initialize, {
|
||||
return (acl_initialize(&g_config, &g_acl) != -1);
|
||||
});
|
||||
|
||||
EXO_TEST(hub_service_initialize, {
|
||||
g_hub = hub_start_service(&g_config);
|
||||
return g_hub ? 1 : 0;
|
||||
});
|
||||
|
||||
EXO_TEST(hub_variables_startup, {
|
||||
hub_set_variables(g_hub, &g_acl);
|
||||
return 1;
|
||||
});
|
||||
|
||||
/*** HUB IS OPERATIONAL HERE! ***/
|
||||
|
||||
EXO_TEST(hub_variables_shutdown, {
|
||||
hub_free_variables(g_hub);
|
||||
return 1;
|
||||
});
|
||||
|
||||
EXO_TEST(hub_acl_shutdown, {
|
||||
acl_shutdown(&g_acl);
|
||||
return 1;
|
||||
});
|
||||
|
||||
EXO_TEST(hub_config_shutdown, {
|
||||
free_config(&g_config);
|
||||
return 1;
|
||||
});
|
||||
|
||||
EXO_TEST(hub_service_shutdown, {
|
||||
if (g_hub)
|
||||
{
|
||||
hub_shutdown_service(g_hub);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
EXO_TEST(hub_net_shutdown, {
|
||||
return (net_destroy() != -1);
|
||||
});
|
||||
@@ -1,161 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
#define USER_CID "GNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI"
|
||||
#define USER_PID "3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y"
|
||||
#define USER_NICK "Friend"
|
||||
#define USER_SID "AAAB"
|
||||
|
||||
static struct hub_user* inf_user = 0;
|
||||
static struct hub_info* inf_hub = 0;
|
||||
|
||||
extern int hub_handle_info_login(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd);
|
||||
|
||||
static void inf_create_hub()
|
||||
{
|
||||
inf_hub = (struct hub_info*) hub_malloc_zero(sizeof(struct hub_info));
|
||||
inf_hub->users = (struct hub_user_manager*) hub_malloc_zero(sizeof(struct hub_user_manager));
|
||||
inf_hub->users->list = list_create();
|
||||
inf_hub->users->sids = sid_pool_create(500);
|
||||
|
||||
inf_hub->acl = (struct acl_handle*) hub_malloc_zero(sizeof(struct acl_handle));
|
||||
inf_hub->config = (struct hub_config*) hub_malloc_zero(sizeof(struct hub_config));
|
||||
|
||||
config_defaults(inf_hub->config);
|
||||
acl_initialize(inf_hub->config, inf_hub->acl);
|
||||
}
|
||||
|
||||
static void inf_destroy_hub()
|
||||
{
|
||||
/* FIXME */
|
||||
list_destroy(inf_hub->users->list);
|
||||
sid_pool_destroy(inf_hub->users->sids);
|
||||
acl_shutdown(inf_hub->acl);
|
||||
free_config(inf_hub->config);
|
||||
hub_free(inf_hub->users);
|
||||
hub_free(inf_hub->acl);
|
||||
hub_free(inf_hub->config);
|
||||
hub_free(inf_hub);
|
||||
}
|
||||
|
||||
|
||||
static void inf_create_user()
|
||||
{
|
||||
if (inf_user) return;
|
||||
inf_user = (struct hub_user*) hub_malloc_zero(sizeof(struct hub_user));
|
||||
inf_user->id.sid = 1;
|
||||
inf_user->limits.upload_slots = 1;
|
||||
}
|
||||
|
||||
static void inf_destroy_user()
|
||||
{
|
||||
if (!inf_user) return;
|
||||
hub_free(inf_user);
|
||||
inf_user = 0;
|
||||
}
|
||||
|
||||
EXO_TEST(inf_create_setup,
|
||||
{
|
||||
inf_create_hub();
|
||||
inf_create_user();
|
||||
return (inf_user && inf_hub);
|
||||
});
|
||||
|
||||
|
||||
/* FIXME: MEMORY LEAK - Need to fix hub_handle_info_login */
|
||||
#define CHECK_INF(MSG, EXPECT) \
|
||||
struct adc_message* msg = adc_msg_parse_verify(inf_user, MSG, strlen(MSG)); \
|
||||
int ok = hub_handle_info_login(inf_hub, inf_user, msg); /* FIXME: MEMORY LEAK */ \
|
||||
adc_msg_free(msg); \
|
||||
if (ok == EXPECT) \
|
||||
user_set_info(inf_user, 0); \
|
||||
return ok == EXPECT;
|
||||
|
||||
|
||||
EXO_TEST(inf_ok_1, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", 0); });
|
||||
|
||||
/* check CID abuse */
|
||||
EXO_TEST(inf_cid_1, { CHECK_INF("BINF AAAB NIFriend PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_missing); });
|
||||
EXO_TEST(inf_cid_2, { CHECK_INF("BINF AAAB NIFriend IDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_invalid); });
|
||||
EXO_TEST(inf_cid_3, { CHECK_INF("BINF AAAB NIFriend IDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_invalid); });
|
||||
EXO_TEST(inf_cid_4, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2R PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_invalid); }); /* cid 1 byte short */
|
||||
EXO_TEST(inf_cid_5, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RX PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_invalid); }); /* cid 1 byte longer */
|
||||
EXO_TEST(inf_cid_6, { CHECK_INF("BINF AAAB NIFriend IDA PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_invalid); });
|
||||
EXO_TEST(inf_cid_7, { CHECK_INF("BINF AAAB NIFriend IDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_invalid); }); /* multi */
|
||||
EXO_TEST(inf_cid_8, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y IDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n", status_msg_inf_error_cid_invalid); });
|
||||
EXO_TEST(inf_cid_9, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI\n", status_msg_inf_error_cid_invalid); });
|
||||
|
||||
/* equivalent to the pid versions */
|
||||
EXO_TEST(inf_pid_1, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI\n", status_msg_inf_error_pid_missing); }); /* pid missing */
|
||||
EXO_TEST(inf_pid_2, { CHECK_INF("BINF AAAB NIFriend ID3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y PDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n", status_msg_inf_error_cid_invalid); }); /* variant of inf_cid_2 */
|
||||
EXO_TEST(inf_pid_3, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n", status_msg_inf_error_pid_invalid); }); /* pid invalid */
|
||||
EXO_TEST(inf_pid_4, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7\n", status_msg_inf_error_pid_invalid); }); /* pid 1 byte short */
|
||||
EXO_TEST(inf_pid_5, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7YX\n", status_msg_inf_error_pid_invalid); }); /* pid 1 byte longer */
|
||||
EXO_TEST(inf_pid_6, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PDA\n", status_msg_inf_error_pid_invalid); }); /* very short pid */
|
||||
EXO_TEST(inf_pid_7, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y PDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n", status_msg_inf_error_pid_invalid); });
|
||||
EXO_TEST(inf_pid_8, { CHECK_INF("BINF AAAB NIFriend PDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_pid_invalid); });
|
||||
EXO_TEST(inf_pid_9, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_pid_invalid); });
|
||||
|
||||
/* check nickname abuse */
|
||||
EXO_TEST(inf_nick_01, { CHECK_INF("BINF AAAB IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_missing); });
|
||||
EXO_TEST(inf_nick_02, { CHECK_INF("BINF AAAB NI IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_short); });
|
||||
EXO_TEST(inf_nick_03, { CHECK_INF("BINF AAAB NIa IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_short); });
|
||||
EXO_TEST(inf_nick_04, { CHECK_INF("BINF AAAB NIabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_long); });
|
||||
EXO_TEST(inf_nick_05, { CHECK_INF("BINF AAAB NI\\sabc IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_spaces); });
|
||||
EXO_TEST(inf_nick_06, { CHECK_INF("BINF AAAB NIa\\sc IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", 0); });
|
||||
EXO_TEST(inf_nick_07, { CHECK_INF("BINF AAAB NIa\tc IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_bad_chars); });
|
||||
EXO_TEST(inf_nick_08, { CHECK_INF("BINF AAAB NIa\\nc IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_bad_chars); });
|
||||
EXO_TEST(inf_nick_09, { CHECK_INF("BINF AAAB NIabc NIdef IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_multiple); });
|
||||
EXO_TEST(inf_nick_10, {
|
||||
const char* line = "BINF AAAB IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n";
|
||||
char nick[10];
|
||||
nick[0] = 0xf7; nick[1] = 0x80; nick[2] = 0x7f; nick[3] = 0x81; nick[4] = 0x98; nick[5] = 0x00;
|
||||
struct adc_message* msg = adc_msg_parse_verify(inf_user, line, strlen(line));
|
||||
|
||||
adc_msg_add_named_argument(msg, "NI", nick);
|
||||
int ok = hub_handle_info_login(inf_hub, inf_user, msg);
|
||||
adc_msg_free(msg);
|
||||
if (ok != status_msg_inf_error_nick_not_utf8)
|
||||
printf("Expected %d, got %d\n", status_msg_inf_error_nick_not_utf8, ok);
|
||||
return ok == status_msg_inf_error_nick_not_utf8;
|
||||
});
|
||||
|
||||
/* check limits for slots and share */
|
||||
EXO_TEST(inf_limits_1, { inf_hub->config->limit_min_slots = 1; CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y SL0\n", status_msg_user_slots_low); });
|
||||
EXO_TEST(inf_limits_2, { inf_hub->config->limit_max_slots = 5; CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y SL99\n", status_msg_user_slots_high); });
|
||||
EXO_TEST(inf_limits_3, { inf_hub->config->limit_min_share = 100; CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y SS104857599\n", status_msg_user_share_size_low); });
|
||||
EXO_TEST(inf_limits_4, { inf_hub->config->limit_max_share = 500; CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y SS524288001\n", status_msg_user_share_size_high); });
|
||||
|
||||
/* setup for check limits for hubs */
|
||||
EXO_TEST(inf_limit_hubs_setup,
|
||||
{
|
||||
inf_hub->config->limit_min_slots = 0;
|
||||
inf_hub->config->limit_max_slots = 0;
|
||||
inf_hub->config->limit_max_share = 0;
|
||||
inf_hub->config->limit_min_share = 0;
|
||||
inf_hub->config->limit_max_hubs_user = 10;
|
||||
inf_hub->config->limit_max_hubs_reg = 10;
|
||||
inf_hub->config->limit_max_hubs_op = 10;
|
||||
inf_hub->config->limit_min_hubs_user = 2;
|
||||
inf_hub->config->limit_min_hubs_reg = 2;
|
||||
inf_hub->config->limit_min_hubs_op = 2;
|
||||
inf_hub->config->limit_max_hubs = 25;
|
||||
|
||||
return 1;
|
||||
} );
|
||||
|
||||
|
||||
EXO_TEST(inf_limit_hubs_1, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HN15\n", status_msg_user_hub_limit_high); });
|
||||
EXO_TEST(inf_limit_hubs_2, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HN1\n", status_msg_user_hub_limit_low); });
|
||||
EXO_TEST(inf_limit_hubs_3, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HO15\n", status_msg_user_hub_limit_high); });
|
||||
EXO_TEST(inf_limit_hubs_4, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HO1\n", status_msg_user_hub_limit_low); });
|
||||
EXO_TEST(inf_limit_hubs_5, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HR15\n", status_msg_user_hub_limit_high); });
|
||||
EXO_TEST(inf_limit_hubs_6, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HR1\n", status_msg_user_hub_limit_low); });
|
||||
EXO_TEST(inf_limit_hubs_7, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HN15 HR15 HO15\n", status_msg_user_hub_limit_high); });
|
||||
|
||||
|
||||
EXO_TEST(inf_destroy_setup,
|
||||
{
|
||||
inf_destroy_user();
|
||||
inf_destroy_hub();
|
||||
return 1;
|
||||
});
|
||||
@@ -1,621 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
static int ipv6 = 0;
|
||||
|
||||
static struct ip_addr_encap ip4_a;
|
||||
static struct ip_addr_encap ip4_b;
|
||||
static struct ip_addr_encap ip4_c;
|
||||
static struct ip_addr_encap ip6_a;
|
||||
static struct ip_addr_encap ip6_b;
|
||||
static struct ip_addr_encap ip6_c;
|
||||
static struct ip_addr_encap mask;
|
||||
static struct ip_range ban6;
|
||||
static struct ip_range ban4;
|
||||
|
||||
EXO_TEST(prepare_network, {
|
||||
return net_initialize() == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(check_ipv6, {
|
||||
ipv6 = net_is_ipv6_supported();
|
||||
return ipv6 != -1;
|
||||
});
|
||||
|
||||
EXO_TEST(create_addresses_1, {
|
||||
return
|
||||
ip_convert_to_binary("192.168.0.0", &ip4_a) &&
|
||||
ip_convert_to_binary("192.168.255.255", &ip4_b) &&
|
||||
ip_convert_to_binary("192.168.0.1", &ip4_c);
|
||||
});
|
||||
|
||||
EXO_TEST(create_addresses_2, {
|
||||
return
|
||||
ip_convert_to_binary("2001::201:2ff:fefa:0", &ip6_a) &&
|
||||
ip_convert_to_binary("2001::201:2ff:fefa:ffff", &ip6_b) &&
|
||||
ip_convert_to_binary("2001::201:2ff:fefa:fffe", &ip6_c);
|
||||
});
|
||||
|
||||
EXO_TEST(ip_is_valid_ipv4_1, {
|
||||
return ip_is_valid_ipv4("127.0.0.1");
|
||||
});
|
||||
|
||||
EXO_TEST(ip_is_valid_ipv4_2, {
|
||||
return ip_is_valid_ipv4("10.18.1.178");
|
||||
});
|
||||
|
||||
EXO_TEST(ip_is_valid_ipv4_3, {
|
||||
return ip_is_valid_ipv4("10.18.1.178");
|
||||
});
|
||||
|
||||
EXO_TEST(ip_is_valid_ipv4_4, {
|
||||
return ip_is_valid_ipv4("224.0.0.1");
|
||||
});
|
||||
|
||||
EXO_TEST(ip_is_valid_ipv4_5, {
|
||||
return !ip_is_valid_ipv4("224.0.0.");
|
||||
});
|
||||
|
||||
EXO_TEST(ip_is_valid_ipv4_6, {
|
||||
return !ip_is_valid_ipv4("invalid");
|
||||
});
|
||||
|
||||
EXO_TEST(ip_is_valid_ipv4_7, {
|
||||
return !ip_is_valid_ipv4("localhost");
|
||||
});
|
||||
|
||||
EXO_TEST(ip_is_valid_ipv4_8, {
|
||||
return !ip_is_valid_ipv4("123.45.67.890");
|
||||
});
|
||||
|
||||
EXO_TEST(ip_is_valid_ipv4_9, {
|
||||
return !ip_is_valid_ipv4("777.777.777.777");
|
||||
});
|
||||
|
||||
EXO_TEST(ip_is_valid_ipv6_1, {
|
||||
if (!ipv6) return 1;
|
||||
return ip_is_valid_ipv6("::");
|
||||
});
|
||||
|
||||
EXO_TEST(ip_is_valid_ipv6_2, {
|
||||
if (!ipv6) return 1;
|
||||
return ip_is_valid_ipv6("::1");
|
||||
});
|
||||
|
||||
EXO_TEST(ip_is_valid_ipv6_3, {
|
||||
if (!ipv6) return 1;
|
||||
return ip_is_valid_ipv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_compare_1, {
|
||||
return ip_compare(&ip4_a, &ip4_b) < 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_compare_2, {
|
||||
return ip_compare(&ip4_a, &ip4_c) < 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_compare_3, {
|
||||
return ip_compare(&ip4_b, &ip4_c) > 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_compare_4, {
|
||||
return ip_compare(&ip4_b, &ip4_a) > 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_compare_5, {
|
||||
return ip_compare(&ip4_c, &ip4_a) > 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_compare_6, {
|
||||
if (!ipv6) return 1;
|
||||
return ip_compare(&ip4_c, &ip4_c) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip6_compare_1, {
|
||||
if (!ipv6) return 1;
|
||||
return ip_compare(&ip6_a, &ip6_b) < 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip6_compare_2, {
|
||||
if (!ipv6) return 1;
|
||||
return ip_compare(&ip6_a, &ip6_c) < 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip6_compare_3, {
|
||||
if (!ipv6) return 1;
|
||||
return ip_compare(&ip6_b, &ip6_c) > 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip6_compare_4, {
|
||||
if (!ipv6) return 1;
|
||||
return ip_compare(&ip6_b, &ip6_a) > 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip6_compare_5, {
|
||||
if (!ipv6) return 1;
|
||||
return ip_compare(&ip6_c, &ip6_a) > 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip6_compare_6, {
|
||||
if (!ipv6) return 1;
|
||||
return ip_compare(&ip6_c, &ip6_c) == 0;
|
||||
});
|
||||
|
||||
static int compare_str(const char* s1, const char* s2)
|
||||
{
|
||||
int ok = strcmp(s1, s2);
|
||||
#ifdef DEBUG_TESTS
|
||||
if (ok)
|
||||
{
|
||||
printf("compare_str fail: s1='%s', s2='%s'\n", s1, s2);
|
||||
}
|
||||
#endif
|
||||
return ok;
|
||||
}
|
||||
|
||||
#define LMASK4(bits) !ip_mask_create_left (AF_INET, bits, &mask)
|
||||
#define LMASK6(bits) (ipv6 ? !ip_mask_create_left (AF_INET6, bits, &mask) : 1)
|
||||
#define RMASK4(bits) !ip_mask_create_right(AF_INET, bits, &mask)
|
||||
#define RMASK6(bits) (ipv6 ? !ip_mask_create_right(AF_INET6, bits, &mask) : 1)
|
||||
#define CHECK4(expect) !compare_str(ip_convert_to_string(&mask), expect)
|
||||
#define CHECK6(expect) (ipv6 ? !compare_str(ip_convert_to_string(&mask), expect) : 1)
|
||||
|
||||
/* Check IPv4 masks */
|
||||
EXO_TEST(ipv4_lmask_create_0, { return LMASK4( 0) && CHECK4("0.0.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_1, { return LMASK4( 1) && CHECK4("128.0.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_2, { return LMASK4( 2) && CHECK4("192.0.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_3, { return LMASK4( 3) && CHECK4("224.0.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_4, { return LMASK4( 4) && CHECK4("240.0.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_5, { return LMASK4( 5) && CHECK4("248.0.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_6, { return LMASK4( 6) && CHECK4("252.0.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_7, { return LMASK4( 7) && CHECK4("254.0.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_8, { return LMASK4( 8) && CHECK4("255.0.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_9, { return LMASK4( 9) && CHECK4("255.128.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_10, { return LMASK4(10) && CHECK4("255.192.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_11, { return LMASK4(11) && CHECK4("255.224.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_12, { return LMASK4(12) && CHECK4("255.240.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_13, { return LMASK4(13) && CHECK4("255.248.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_14, { return LMASK4(14) && CHECK4("255.252.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_15, { return LMASK4(15) && CHECK4("255.254.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_16, { return LMASK4(16) && CHECK4("255.255.0.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_17, { return LMASK4(17) && CHECK4("255.255.128.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_18, { return LMASK4(18) && CHECK4("255.255.192.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_19, { return LMASK4(19) && CHECK4("255.255.224.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_20, { return LMASK4(20) && CHECK4("255.255.240.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_21, { return LMASK4(21) && CHECK4("255.255.248.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_22, { return LMASK4(22) && CHECK4("255.255.252.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_23, { return LMASK4(23) && CHECK4("255.255.254.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_24, { return LMASK4(24) && CHECK4("255.255.255.0"); });
|
||||
EXO_TEST(ipv4_lmask_create_25, { return LMASK4(25) && CHECK4("255.255.255.128"); });
|
||||
EXO_TEST(ipv4_lmask_create_26, { return LMASK4(26) && CHECK4("255.255.255.192"); });
|
||||
EXO_TEST(ipv4_lmask_create_27, { return LMASK4(27) && CHECK4("255.255.255.224"); });
|
||||
EXO_TEST(ipv4_lmask_create_28, { return LMASK4(28) && CHECK4("255.255.255.240"); });
|
||||
EXO_TEST(ipv4_lmask_create_29, { return LMASK4(29) && CHECK4("255.255.255.248"); });
|
||||
EXO_TEST(ipv4_lmask_create_30, { return LMASK4(30) && CHECK4("255.255.255.252"); });
|
||||
EXO_TEST(ipv4_lmask_create_31, { return LMASK4(31) && CHECK4("255.255.255.254"); });
|
||||
EXO_TEST(ipv4_lmask_create_32, { return LMASK4(32) && CHECK4("255.255.255.255"); });
|
||||
|
||||
/* Check IPv4 right to left mask */
|
||||
EXO_TEST(ipv4_rmask_create_0, { return RMASK4( 0) && CHECK4("0.0.0.0"); });
|
||||
EXO_TEST(ipv4_rmask_create_1, { return RMASK4( 1) && CHECK4("0.0.0.1"); });
|
||||
EXO_TEST(ipv4_rmask_create_2, { return RMASK4( 2) && CHECK4("0.0.0.3"); });
|
||||
EXO_TEST(ipv4_rmask_create_3, { return RMASK4( 3) && CHECK4("0.0.0.7"); });
|
||||
EXO_TEST(ipv4_rmask_create_4, { return RMASK4( 4) && CHECK4("0.0.0.15"); });
|
||||
EXO_TEST(ipv4_rmask_create_5, { return RMASK4( 5) && CHECK4("0.0.0.31"); });
|
||||
EXO_TEST(ipv4_rmask_create_6, { return RMASK4( 6) && CHECK4("0.0.0.63"); });
|
||||
EXO_TEST(ipv4_rmask_create_7, { return RMASK4( 7) && CHECK4("0.0.0.127"); });
|
||||
EXO_TEST(ipv4_rmask_create_8, { return RMASK4( 8) && CHECK4("0.0.0.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_9, { return RMASK4( 9) && CHECK4("0.0.1.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_10, { return RMASK4(10) && CHECK4("0.0.3.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_11, { return RMASK4(11) && CHECK4("0.0.7.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_12, { return RMASK4(12) && CHECK4("0.0.15.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_13, { return RMASK4(13) && CHECK4("0.0.31.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_14, { return RMASK4(14) && CHECK4("0.0.63.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_15, { return RMASK4(15) && CHECK4("0.0.127.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_16, { return RMASK4(16) && CHECK4("0.0.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_17, { return RMASK4(17) && CHECK4("0.1.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_18, { return RMASK4(18) && CHECK4("0.3.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_19, { return RMASK4(19) && CHECK4("0.7.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_20, { return RMASK4(20) && CHECK4("0.15.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_21, { return RMASK4(21) && CHECK4("0.31.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_22, { return RMASK4(22) && CHECK4("0.63.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_23, { return RMASK4(23) && CHECK4("0.127.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_24, { return RMASK4(24) && CHECK4("0.255.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_25, { return RMASK4(25) && CHECK4("1.255.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_26, { return RMASK4(26) && CHECK4("3.255.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_27, { return RMASK4(27) && CHECK4("7.255.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_28, { return RMASK4(28) && CHECK4("15.255.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_29, { return RMASK4(29) && CHECK4("31.255.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_30, { return RMASK4(30) && CHECK4("63.255.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_31, { return RMASK4(31) && CHECK4("127.255.255.255"); });
|
||||
EXO_TEST(ipv4_rmask_create_32, { return RMASK4(32) && CHECK4("255.255.255.255"); });
|
||||
|
||||
|
||||
/* Check IPv6 masks */
|
||||
EXO_TEST(ip6_lmask_create_0, { return LMASK6( 0) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_lmask_create_1, { return LMASK6( 1) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe"); });
|
||||
EXO_TEST(ip6_lmask_create_2, { return LMASK6( 2) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc"); });
|
||||
EXO_TEST(ip6_lmask_create_3, { return LMASK6( 3) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff8"); });
|
||||
EXO_TEST(ip6_lmask_create_4, { return LMASK6( 4) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0"); });
|
||||
EXO_TEST(ip6_lmask_create_5, { return LMASK6( 5) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffe0"); });
|
||||
EXO_TEST(ip6_lmask_create_6, { return LMASK6( 6) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffc0"); });
|
||||
EXO_TEST(ip6_lmask_create_7, { return LMASK6( 7) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff80"); });
|
||||
EXO_TEST(ip6_lmask_create_8, { return LMASK6( 8) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"); });
|
||||
EXO_TEST(ip6_lmask_create_9, { return LMASK6( 9) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fe00"); });
|
||||
EXO_TEST(ip6_lmask_create_10, { return LMASK6( 10) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fc00"); });
|
||||
EXO_TEST(ip6_lmask_create_11, { return LMASK6( 11) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:f800"); });
|
||||
EXO_TEST(ip6_lmask_create_12, { return LMASK6( 12) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:f000"); });
|
||||
EXO_TEST(ip6_lmask_create_13, { return LMASK6( 13) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:e000"); });
|
||||
EXO_TEST(ip6_lmask_create_14, { return LMASK6( 14) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:c000"); });
|
||||
EXO_TEST(ip6_lmask_create_15, { return LMASK6( 15) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:8000"); });
|
||||
EXO_TEST(ip6_lmask_create_16, { return LMASK6( 16) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff::")); });
|
||||
EXO_TEST(ip6_lmask_create_17, { return LMASK6( 17) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fffe:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fffe::")); });
|
||||
EXO_TEST(ip6_lmask_create_18, { return LMASK6( 18) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fffc:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fffc::")); });
|
||||
EXO_TEST(ip6_lmask_create_19, { return LMASK6( 19) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fff8:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fff8::")); });
|
||||
EXO_TEST(ip6_lmask_create_20, { return LMASK6( 20) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fff0:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fff0::")); });
|
||||
EXO_TEST(ip6_lmask_create_21, { return LMASK6( 21) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffe0:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffe0::")); });
|
||||
EXO_TEST(ip6_lmask_create_22, { return LMASK6( 22) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffc0:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffc0::")); });
|
||||
EXO_TEST(ip6_lmask_create_23, { return LMASK6( 23) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ff80:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ff80::")); });
|
||||
EXO_TEST(ip6_lmask_create_24, { return LMASK6( 24) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ff00:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ff00::")); });
|
||||
EXO_TEST(ip6_lmask_create_25, { return LMASK6( 25) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fe00:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fe00::")); });
|
||||
EXO_TEST(ip6_lmask_create_26, { return LMASK6( 26) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fc00:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fc00::")); });
|
||||
EXO_TEST(ip6_lmask_create_27, { return LMASK6( 27) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:f800:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:f800::")); });
|
||||
EXO_TEST(ip6_lmask_create_28, { return LMASK6( 28) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:f000:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:f000::")); });
|
||||
EXO_TEST(ip6_lmask_create_29, { return LMASK6( 29) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:e000:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:e000::")); });
|
||||
EXO_TEST(ip6_lmask_create_30, { return LMASK6( 30) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:c000:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:c000::")); });
|
||||
EXO_TEST(ip6_lmask_create_31, { return LMASK6( 31) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:8000:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:8000::")); });
|
||||
EXO_TEST(ip6_lmask_create_32, { return LMASK6( 32) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff::"); });
|
||||
EXO_TEST(ip6_lmask_create_33, { return LMASK6( 33) && CHECK6("ffff:ffff:ffff:ffff:ffff:fffe::"); });
|
||||
EXO_TEST(ip6_lmask_create_34, { return LMASK6( 34) && CHECK6("ffff:ffff:ffff:ffff:ffff:fffc::"); });
|
||||
EXO_TEST(ip6_lmask_create_35, { return LMASK6( 35) && CHECK6("ffff:ffff:ffff:ffff:ffff:fff8::"); });
|
||||
EXO_TEST(ip6_lmask_create_36, { return LMASK6( 36) && CHECK6("ffff:ffff:ffff:ffff:ffff:fff0::"); });
|
||||
EXO_TEST(ip6_lmask_create_37, { return LMASK6( 37) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffe0::"); });
|
||||
EXO_TEST(ip6_lmask_create_38, { return LMASK6( 38) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffc0::"); });
|
||||
EXO_TEST(ip6_lmask_create_39, { return LMASK6( 39) && CHECK6("ffff:ffff:ffff:ffff:ffff:ff80::"); });
|
||||
EXO_TEST(ip6_lmask_create_40, { return LMASK6( 40) && CHECK6("ffff:ffff:ffff:ffff:ffff:ff00::"); });
|
||||
EXO_TEST(ip6_lmask_create_41, { return LMASK6( 41) && CHECK6("ffff:ffff:ffff:ffff:ffff:fe00::"); });
|
||||
EXO_TEST(ip6_lmask_create_42, { return LMASK6( 42) && CHECK6("ffff:ffff:ffff:ffff:ffff:fc00::"); });
|
||||
EXO_TEST(ip6_lmask_create_43, { return LMASK6( 43) && CHECK6("ffff:ffff:ffff:ffff:ffff:f800::"); });
|
||||
EXO_TEST(ip6_lmask_create_44, { return LMASK6( 44) && CHECK6("ffff:ffff:ffff:ffff:ffff:f000::"); });
|
||||
EXO_TEST(ip6_lmask_create_45, { return LMASK6( 45) && CHECK6("ffff:ffff:ffff:ffff:ffff:e000::"); });
|
||||
EXO_TEST(ip6_lmask_create_46, { return LMASK6( 46) && CHECK6("ffff:ffff:ffff:ffff:ffff:c000::"); });
|
||||
EXO_TEST(ip6_lmask_create_47, { return LMASK6( 47) && CHECK6("ffff:ffff:ffff:ffff:ffff:8000::"); });
|
||||
EXO_TEST(ip6_lmask_create_48, { return LMASK6( 48) && CHECK6("ffff:ffff:ffff:ffff:ffff::"); });
|
||||
EXO_TEST(ip6_lmask_create_49, { return LMASK6( 49) && CHECK6("ffff:ffff:ffff:ffff:fffe::"); });
|
||||
EXO_TEST(ip6_lmask_create_50, { return LMASK6( 50) && CHECK6("ffff:ffff:ffff:ffff:fffc::"); });
|
||||
EXO_TEST(ip6_lmask_create_51, { return LMASK6( 51) && CHECK6("ffff:ffff:ffff:ffff:fff8::"); });
|
||||
EXO_TEST(ip6_lmask_create_52, { return LMASK6( 52) && CHECK6("ffff:ffff:ffff:ffff:fff0::"); });
|
||||
EXO_TEST(ip6_lmask_create_53, { return LMASK6( 53) && CHECK6("ffff:ffff:ffff:ffff:ffe0::"); });
|
||||
EXO_TEST(ip6_lmask_create_54, { return LMASK6( 54) && CHECK6("ffff:ffff:ffff:ffff:ffc0::"); });
|
||||
EXO_TEST(ip6_lmask_create_55, { return LMASK6( 55) && CHECK6("ffff:ffff:ffff:ffff:ff80::"); });
|
||||
EXO_TEST(ip6_lmask_create_56, { return LMASK6( 56) && CHECK6("ffff:ffff:ffff:ffff:ff00::"); });
|
||||
EXO_TEST(ip6_lmask_create_57, { return LMASK6( 57) && CHECK6("ffff:ffff:ffff:ffff:fe00::"); });
|
||||
EXO_TEST(ip6_lmask_create_58, { return LMASK6( 58) && CHECK6("ffff:ffff:ffff:ffff:fc00::"); });
|
||||
EXO_TEST(ip6_lmask_create_59, { return LMASK6( 59) && CHECK6("ffff:ffff:ffff:ffff:f800::"); });
|
||||
EXO_TEST(ip6_lmask_create_60, { return LMASK6( 60) && CHECK6("ffff:ffff:ffff:ffff:f000::"); });
|
||||
EXO_TEST(ip6_lmask_create_61, { return LMASK6( 61) && CHECK6("ffff:ffff:ffff:ffff:e000::"); });
|
||||
EXO_TEST(ip6_lmask_create_62, { return LMASK6( 62) && CHECK6("ffff:ffff:ffff:ffff:c000::"); });
|
||||
EXO_TEST(ip6_lmask_create_63, { return LMASK6( 63) && CHECK6("ffff:ffff:ffff:ffff:8000::"); });
|
||||
EXO_TEST(ip6_lmask_create_64, { return LMASK6( 64) && CHECK6("ffff:ffff:ffff:ffff::"); });
|
||||
EXO_TEST(ip6_lmask_create_65, { return LMASK6( 65) && CHECK6("ffff:ffff:ffff:fffe::"); });
|
||||
EXO_TEST(ip6_lmask_create_66, { return LMASK6( 66) && CHECK6("ffff:ffff:ffff:fffc::"); });
|
||||
EXO_TEST(ip6_lmask_create_67, { return LMASK6( 67) && CHECK6("ffff:ffff:ffff:fff8::"); });
|
||||
EXO_TEST(ip6_lmask_create_68, { return LMASK6( 68) && CHECK6("ffff:ffff:ffff:fff0::"); });
|
||||
EXO_TEST(ip6_lmask_create_69, { return LMASK6( 69) && CHECK6("ffff:ffff:ffff:ffe0::"); });
|
||||
EXO_TEST(ip6_lmask_create_70, { return LMASK6( 70) && CHECK6("ffff:ffff:ffff:ffc0::"); });
|
||||
EXO_TEST(ip6_lmask_create_71, { return LMASK6( 71) && CHECK6("ffff:ffff:ffff:ff80::"); });
|
||||
EXO_TEST(ip6_lmask_create_72, { return LMASK6( 72) && CHECK6("ffff:ffff:ffff:ff00::"); });
|
||||
EXO_TEST(ip6_lmask_create_73, { return LMASK6( 73) && CHECK6("ffff:ffff:ffff:fe00::"); });
|
||||
EXO_TEST(ip6_lmask_create_74, { return LMASK6( 74) && CHECK6("ffff:ffff:ffff:fc00::"); });
|
||||
EXO_TEST(ip6_lmask_create_75, { return LMASK6( 75) && CHECK6("ffff:ffff:ffff:f800::"); });
|
||||
EXO_TEST(ip6_lmask_create_76, { return LMASK6( 76) && CHECK6("ffff:ffff:ffff:f000::"); });
|
||||
EXO_TEST(ip6_lmask_create_77, { return LMASK6( 77) && CHECK6("ffff:ffff:ffff:e000::"); });
|
||||
EXO_TEST(ip6_lmask_create_78, { return LMASK6( 78) && CHECK6("ffff:ffff:ffff:c000::"); });
|
||||
EXO_TEST(ip6_lmask_create_79, { return LMASK6( 79) && CHECK6("ffff:ffff:ffff:8000::"); });
|
||||
EXO_TEST(ip6_lmask_create_80, { return LMASK6( 80) && CHECK6("ffff:ffff:ffff::"); });
|
||||
EXO_TEST(ip6_lmask_create_81, { return LMASK6( 81) && CHECK6("ffff:ffff:fffe::"); });
|
||||
EXO_TEST(ip6_lmask_create_82, { return LMASK6( 82) && CHECK6("ffff:ffff:fffc::"); });
|
||||
EXO_TEST(ip6_lmask_create_83, { return LMASK6( 83) && CHECK6("ffff:ffff:fff8::"); });
|
||||
EXO_TEST(ip6_lmask_create_84, { return LMASK6( 84) && CHECK6("ffff:ffff:fff0::"); });
|
||||
EXO_TEST(ip6_lmask_create_85, { return LMASK6( 85) && CHECK6("ffff:ffff:ffe0::"); });
|
||||
EXO_TEST(ip6_lmask_create_86, { return LMASK6( 86) && CHECK6("ffff:ffff:ffc0::"); });
|
||||
EXO_TEST(ip6_lmask_create_87, { return LMASK6( 87) && CHECK6("ffff:ffff:ff80::"); });
|
||||
EXO_TEST(ip6_lmask_create_88, { return LMASK6( 88) && CHECK6("ffff:ffff:ff00::"); });
|
||||
EXO_TEST(ip6_lmask_create_89, { return LMASK6( 89) && CHECK6("ffff:ffff:fe00::"); });
|
||||
EXO_TEST(ip6_lmask_create_90, { return LMASK6( 90) && CHECK6("ffff:ffff:fc00::"); });
|
||||
EXO_TEST(ip6_lmask_create_91, { return LMASK6( 91) && CHECK6("ffff:ffff:f800::"); });
|
||||
EXO_TEST(ip6_lmask_create_92, { return LMASK6( 92) && CHECK6("ffff:ffff:f000::"); });
|
||||
EXO_TEST(ip6_lmask_create_93, { return LMASK6( 93) && CHECK6("ffff:ffff:e000::"); });
|
||||
EXO_TEST(ip6_lmask_create_94, { return LMASK6( 94) && CHECK6("ffff:ffff:c000::"); });
|
||||
EXO_TEST(ip6_lmask_create_95, { return LMASK6( 95) && CHECK6("ffff:ffff:8000::"); });
|
||||
EXO_TEST(ip6_lmask_create_96, { return LMASK6( 96) && CHECK6("ffff:ffff::"); });
|
||||
EXO_TEST(ip6_lmask_create_97, { return LMASK6( 97) && CHECK6("ffff:fffe::"); });
|
||||
EXO_TEST(ip6_lmask_create_98, { return LMASK6( 98) && CHECK6("ffff:fffc::"); });
|
||||
EXO_TEST(ip6_lmask_create_99, { return LMASK6( 99) && CHECK6("ffff:fff8::"); });
|
||||
EXO_TEST(ip6_lmask_create_100, { return LMASK6(100) && CHECK6("ffff:fff0::"); });
|
||||
EXO_TEST(ip6_lmask_create_101, { return LMASK6(101) && CHECK6("ffff:ffe0::"); });
|
||||
EXO_TEST(ip6_lmask_create_102, { return LMASK6(102) && CHECK6("ffff:ffc0::"); });
|
||||
EXO_TEST(ip6_lmask_create_103, { return LMASK6(103) && CHECK6("ffff:ff80::"); });
|
||||
EXO_TEST(ip6_lmask_create_104, { return LMASK6(104) && CHECK6("ffff:ff00::"); });
|
||||
EXO_TEST(ip6_lmask_create_105, { return LMASK6(105) && CHECK6("ffff:fe00::"); });
|
||||
EXO_TEST(ip6_lmask_create_106, { return LMASK6(106) && CHECK6("ffff:fc00::"); });
|
||||
EXO_TEST(ip6_lmask_create_107, { return LMASK6(107) && CHECK6("ffff:f800::"); });
|
||||
EXO_TEST(ip6_lmask_create_108, { return LMASK6(108) && CHECK6("ffff:f000::"); });
|
||||
EXO_TEST(ip6_lmask_create_109, { return LMASK6(109) && CHECK6("ffff:e000::"); });
|
||||
EXO_TEST(ip6_lmask_create_110, { return LMASK6(110) && CHECK6("ffff:c000::"); });
|
||||
EXO_TEST(ip6_lmask_create_111, { return LMASK6(111) && CHECK6("ffff:8000::"); });
|
||||
EXO_TEST(ip6_lmask_create_112, { return LMASK6(112) && CHECK6("ffff::"); });
|
||||
EXO_TEST(ip6_lmask_create_113, { return LMASK6(113) && CHECK6("fffe::"); });
|
||||
EXO_TEST(ip6_lmask_create_114, { return LMASK6(114) && CHECK6("fffc::"); });
|
||||
EXO_TEST(ip6_lmask_create_115, { return LMASK6(115) && CHECK6("fff8::"); });
|
||||
EXO_TEST(ip6_lmask_create_116, { return LMASK6(116) && CHECK6("fff0::"); });
|
||||
EXO_TEST(ip6_lmask_create_117, { return LMASK6(117) && CHECK6("ffe0::"); });
|
||||
EXO_TEST(ip6_lmask_create_118, { return LMASK6(118) && CHECK6("ffc0::"); });
|
||||
EXO_TEST(ip6_lmask_create_119, { return LMASK6(119) && CHECK6("ff80::"); });
|
||||
EXO_TEST(ip6_lmask_create_120, { return LMASK6(120) && CHECK6("ff00::"); });
|
||||
EXO_TEST(ip6_lmask_create_121, { return LMASK6(121) && CHECK6("fe00::"); });
|
||||
EXO_TEST(ip6_lmask_create_122, { return LMASK6(122) && CHECK6("fc00::"); });
|
||||
EXO_TEST(ip6_lmask_create_123, { return LMASK6(123) && CHECK6("f800::"); });
|
||||
EXO_TEST(ip6_lmask_create_124, { return LMASK6(124) && CHECK6("f000::"); });
|
||||
EXO_TEST(ip6_lmask_create_125, { return LMASK6(125) && CHECK6("e000::"); });
|
||||
EXO_TEST(ip6_lmask_create_126, { return LMASK6(126) && CHECK6("c000::"); });
|
||||
EXO_TEST(ip6_lmask_create_127, { return LMASK6(127) && CHECK6("8000::"); });
|
||||
EXO_TEST(ip6_lmask_create_128, { return LMASK6(128) && CHECK6("::"); });
|
||||
|
||||
/* Check IPv6 right to left masks */
|
||||
EXO_TEST(ip6_rmask_create_0, { return RMASK6( 0) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_1, { return RMASK6( 1) && CHECK6("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_2, { return RMASK6( 2) && CHECK6("3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_3, { return RMASK6( 3) && CHECK6("1fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_4, { return RMASK6( 4) && CHECK6("fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_5, { return RMASK6( 5) && CHECK6("7ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_6, { return RMASK6( 6) && CHECK6("3ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_7, { return RMASK6( 7) && CHECK6("1ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_8, { return RMASK6( 8) && CHECK6("ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_9, { return RMASK6( 9) && CHECK6("7f:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_10, { return RMASK6( 10) && CHECK6("3f:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_11, { return RMASK6( 11) && CHECK6("1f:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_12, { return RMASK6( 12) && CHECK6("f:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_13, { return RMASK6( 13) && CHECK6("7:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_14, { return RMASK6( 14) && CHECK6("3:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_15, { return RMASK6( 15) && CHECK6("1:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
|
||||
EXO_TEST(ip6_rmask_create_16, { return RMASK6( 16) && (CHECK6("0:ffff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::ffff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_17, { return RMASK6( 17) && (CHECK6("0:7fff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::7fff:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_18, { return RMASK6( 18) && (CHECK6("0:3fff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::3fff:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_19, { return RMASK6( 19) && (CHECK6("0:1fff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::1fff:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_20, { return RMASK6( 20) && (CHECK6("0:fff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::fff:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_21, { return RMASK6( 21) && (CHECK6("0:7ff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::7ff:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_22, { return RMASK6( 22) && (CHECK6("0:3ff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::3ff:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_23, { return RMASK6( 23) && (CHECK6("0:1ff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::1ff:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_24, { return RMASK6( 24) && (CHECK6("0:ff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::ff:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_25, { return RMASK6( 25) && (CHECK6("0:7f:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::7f:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_26, { return RMASK6( 26) && (CHECK6("0:3f:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::3f:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_27, { return RMASK6( 27) && (CHECK6("0:1f:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::1f:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_28, { return RMASK6( 28) && (CHECK6("0:f:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::f:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_29, { return RMASK6( 29) && (CHECK6("0:7:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::7:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_30, { return RMASK6( 30) && (CHECK6("0:3:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::3:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
EXO_TEST(ip6_rmask_create_31, { return RMASK6( 31) && (CHECK6("0:1:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::1:ffff:ffff:ffff:ffff:ffff:ffff")); });
|
||||
|
||||
EXO_TEST(check_ban_setup_1, {
|
||||
return ip_convert_to_binary("2001::201:2ff:fefa:0", &ban6.lo) &&
|
||||
ip_convert_to_binary("2001::201:2ff:fefa:ffff", &ban6.hi) &&
|
||||
ip_convert_to_binary("192.168.0.0", &ban4.lo) &&
|
||||
ip_convert_to_binary("192.168.0.255", &ban4.hi);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv4_1, {
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("192.168.0.0", &addr);
|
||||
return ip_in_range(&addr, &ban4);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv4_2, {
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("192.168.0.1", &addr);
|
||||
return ip_in_range(&addr, &ban4);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv4_3, {
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("192.168.0.255", &addr);
|
||||
return ip_in_range(&addr, &ban4);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv4_4, {
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("192.168.1.0", &addr);
|
||||
return !ip_in_range(&addr, &ban4);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv4_5, {
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("192.167.255.255", &addr);
|
||||
return !ip_in_range(&addr, &ban4);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv6_1, {
|
||||
if (!ipv6) return 1;
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefa:0", &addr);
|
||||
return ip_in_range(&addr, &ban6);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv6_2, {
|
||||
if (!ipv6) return 1;
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefa:1", &addr);
|
||||
return ip_in_range(&addr, &ban6);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv6_3, {
|
||||
if (!ipv6) return 1;
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefa:fffe", &addr);
|
||||
return ip_in_range(&addr, &ban6);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv6_4, {
|
||||
if (!ipv6) return 1;
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefa:ffff", &addr);
|
||||
return ip_in_range(&addr, &ban6);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv6_5, {
|
||||
if (!ipv6) return 1;
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefb:0", &addr);
|
||||
return !ip_in_range(&addr, &ban6);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv6_6, {
|
||||
if (!ipv6) return 1;
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fef9:ffff", &addr);
|
||||
return !ip_in_range(&addr, &ban6);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_afmix_1, {
|
||||
if (!ipv6) return 1;
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fef9:ffff", &addr);
|
||||
return !ip_in_range(&addr, &ban4);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_afmix_2, {
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("10.20.30.40", &addr);
|
||||
return !ip_in_range(&addr, &ban6);
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_bitwise_AND_1, {
|
||||
ip_convert_to_binary("255.255.255.255", &ip4_a);
|
||||
ip_convert_to_binary("255.255.255.0", &ip4_b);
|
||||
ip_mask_apply_AND(&ip4_a, &ip4_b, &ip4_c);
|
||||
return !strcmp(ip_convert_to_string(&ip4_c), "255.255.255.0");
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_bitwise_AND_2, {
|
||||
ip_convert_to_binary("192.168.217.113", &ip4_a);
|
||||
ip_convert_to_binary("255.255.255.0", &ip4_b);
|
||||
ip_mask_apply_AND(&ip4_a, &ip4_b, &ip4_c);
|
||||
return !strcmp(ip_convert_to_string(&ip4_c), "192.168.217.0");
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_bitwise_AND_3, {
|
||||
ip_convert_to_binary("192.168.217.113", &ip4_a);
|
||||
ip_convert_to_binary("255.255.0.0", &ip4_b);
|
||||
ip_mask_apply_AND(&ip4_a, &ip4_b, &ip4_c);
|
||||
return !strcmp(ip_convert_to_string(&ip4_c), "192.168.0.0");
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_bitwise_AND_4, {
|
||||
ip_convert_to_binary("192.168.217.113", &ip4_a);
|
||||
ip_convert_to_binary("255.0.0.0", &ip4_b);
|
||||
ip_mask_apply_AND(&ip4_a, &ip4_b, &ip4_c);
|
||||
return !strcmp(ip_convert_to_string(&ip4_c), "192.0.0.0");
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_bitwise_AND_5, {
|
||||
ip_convert_to_binary("192.168.217.113", &ip4_a);
|
||||
ip_convert_to_binary("0.0.0.0", &ip4_b);
|
||||
ip_mask_apply_AND(&ip4_a, &ip4_b, &ip4_c);
|
||||
return !strcmp(ip_convert_to_string(&ip4_c), "0.0.0.0");
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_bitwise_OR_1, {
|
||||
ip_convert_to_binary("255.255.255.255", &ip4_a);
|
||||
ip_convert_to_binary("255.255.255.0", &ip4_b);
|
||||
ip_mask_apply_OR(&ip4_a, &ip4_b, &ip4_c);
|
||||
return !strcmp(ip_convert_to_string(&ip4_c), "255.255.255.255");
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_bitwise_OR_2, {
|
||||
ip_convert_to_binary("192.168.217.113", &ip4_a);
|
||||
ip_convert_to_binary("255.255.255.0", &ip4_b);
|
||||
ip_mask_apply_OR(&ip4_a, &ip4_b, &ip4_c);
|
||||
return !strcmp(ip_convert_to_string(&ip4_c), "255.255.255.113");
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_bitwise_OR_3, {
|
||||
ip_convert_to_binary("192.168.217.113", &ip4_a);
|
||||
ip_convert_to_binary("255.255.0.0", &ip4_b);
|
||||
ip_mask_apply_OR(&ip4_a, &ip4_b, &ip4_c);
|
||||
return !strcmp(ip_convert_to_string(&ip4_c), "255.255.217.113");
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_bitwise_OR_4, {
|
||||
ip_convert_to_binary("192.168.217.113", &ip4_a);
|
||||
ip_convert_to_binary("255.0.0.0", &ip4_b);
|
||||
ip_mask_apply_OR(&ip4_a, &ip4_b, &ip4_c);
|
||||
return !strcmp(ip_convert_to_string(&ip4_c), "255.168.217.113");
|
||||
});
|
||||
|
||||
EXO_TEST(ip4_bitwise_OR_5, {
|
||||
ip_convert_to_binary("192.168.217.113", &ip4_a);
|
||||
ip_convert_to_binary("0.0.0.0", &ip4_b);
|
||||
ip_mask_apply_OR(&ip4_a, &ip4_b, &ip4_c);
|
||||
return !strcmp(ip_convert_to_string(&ip4_c), "192.168.217.113");
|
||||
});
|
||||
|
||||
EXO_TEST(ip6_bitwise_AND_1, {
|
||||
if (!ipv6) return 1;
|
||||
ip_convert_to_binary("7f7f:ffff:ffff:3f3f:ffff:ffff:ffff:ffff", &ip6_a);
|
||||
ip_convert_to_binary("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", &ip6_b);
|
||||
ip_mask_apply_AND(&ip6_a, &ip6_b, &ip6_c);
|
||||
return !strcmp(ip_convert_to_string(&ip6_c), "7f7f:ffff:ffff:3f3f:ffff:ffff:ffff:0") ||
|
||||
!strcmp(ip_convert_to_string(&ip6_c), "7f7f:ffff:ffff:3f3f:ffff:ffff:ffff::");
|
||||
});
|
||||
|
||||
EXO_TEST(ip6_bitwise_AND_2, {
|
||||
if (!ipv6) return 1;
|
||||
ip_convert_to_binary("7777:cccc:3333:1111:ffff:ffff:ffff:ffff", &ip6_a);
|
||||
ip_convert_to_binary("ffff:ffff:ffff:ffff::", &ip6_b);
|
||||
ip_mask_apply_AND(&ip6_a, &ip6_b, &ip6_c);
|
||||
return !strcmp(ip_convert_to_string(&ip6_c), "7777:cccc:3333:1111::");
|
||||
});
|
||||
|
||||
EXO_TEST(ip6_bitwise_AND_3, {
|
||||
if (!ipv6) return 1;
|
||||
ip_convert_to_binary("7777:cccc:3333:1111:ffff:ffff:ffff:ffff", &ip6_a);
|
||||
ip_convert_to_binary("::", &ip6_b);
|
||||
ip_mask_apply_AND(&ip6_a, &ip6_b, &ip6_c);
|
||||
return !strcmp(ip_convert_to_string(&ip6_c), "::");
|
||||
});
|
||||
|
||||
EXO_TEST(ip6_bitwise_OR_1, {
|
||||
if (!ipv6) return 1;
|
||||
ip_convert_to_binary("7f7f:ffff:ffff:3f3f:ffff:ffff:ffff:ffff", &ip6_a);
|
||||
ip_convert_to_binary("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", &ip6_b);
|
||||
ip_mask_apply_OR(&ip6_a, &ip6_b, &ip6_c);
|
||||
return !strcmp(ip_convert_to_string(&ip6_c), "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
|
||||
});
|
||||
|
||||
EXO_TEST(ip6_bitwise_OR_2, {
|
||||
if (!ipv6) return 1;
|
||||
ip_convert_to_binary("7777:cccc:3333:1111:ffff:ffff:ffff:ffff", &ip6_a);
|
||||
ip_convert_to_binary("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", &ip6_b);
|
||||
ip_mask_apply_OR(&ip6_a, &ip6_b, &ip6_c);
|
||||
return !strcmp(ip_convert_to_string(&ip6_c), "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
|
||||
});
|
||||
|
||||
EXO_TEST(ip6_bitwise_OR_3, {
|
||||
if (!ipv6) return 1;
|
||||
ip_convert_to_binary("7777:cccc:3333:1111:ffff:ffff:ffff:1c1c", &ip6_a);
|
||||
ip_convert_to_binary("::", &ip6_b);
|
||||
ip_mask_apply_OR(&ip6_a, &ip6_b, &ip6_c);
|
||||
return !strcmp(ip_convert_to_string(&ip6_c), "7777:cccc:3333:1111:ffff:ffff:ffff:1c1c");
|
||||
});
|
||||
|
||||
EXO_TEST(ip_range_1, {
|
||||
struct ip_range range; memset(&range, 0, sizeof(range));
|
||||
return ip_convert_address_to_range("192.168.0.1", &range) && memcmp(&range.lo, &range.hi, sizeof(struct ip_addr_encap)) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip_range_2, {
|
||||
struct ip_range range; memset(&range, 0, sizeof(range));
|
||||
return ip_convert_address_to_range("192.168.0.0-192.168.255.255", &range) && range.lo.af == range.hi.af && memcmp(&range.lo, &range.hi, sizeof(struct ip_addr_encap)) != 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip_range_3, {
|
||||
struct ip_range range; memset(&range, 0, sizeof(range));
|
||||
return ip_convert_address_to_range("192.168.0.0/16", &range) && range.lo.af == range.hi.af && memcmp(&range.lo, &range.hi, sizeof(struct ip_addr_encap)) != 0;
|
||||
});
|
||||
|
||||
EXO_TEST(ip_range_4, {
|
||||
struct ip_range range1; memset(&range1, 0, sizeof(range1));
|
||||
struct ip_range range2; memset(&range2, 0, sizeof(range2));
|
||||
return ip_convert_address_to_range("192.168.0.0/16", &range1) && ip_convert_address_to_range("192.168.0.0-192.168.255.255", &range2) && memcmp(&range1, &range2, sizeof(struct ip_range)) == 0;
|
||||
});
|
||||
|
||||
|
||||
EXO_TEST(shutdown_network, {
|
||||
return net_destroy() == 0;
|
||||
});
|
||||
@@ -1,137 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
static struct linked_list* list = NULL;
|
||||
|
||||
static char A[2] = { 'A', 0 };
|
||||
static char B[2] = { 'B', 0 };
|
||||
static char C[2] = { 'C', 0 };
|
||||
|
||||
static void null_free(void* ptr)
|
||||
{
|
||||
(void) ptr;
|
||||
}
|
||||
|
||||
|
||||
EXO_TEST(list_create_destroy, {
|
||||
int ok = 0;
|
||||
struct linked_list* alist;
|
||||
alist = list_create();
|
||||
if (alist) ok = 1;
|
||||
list_destroy(alist);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(list_create, {
|
||||
list = list_create();
|
||||
return list->size == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(list_append_1, {
|
||||
list_append(list, (char*) A);
|
||||
return list->size == 1;
|
||||
});
|
||||
|
||||
EXO_TEST(list_remove_1, {
|
||||
list_remove(list, (char*) A);
|
||||
return list->size == 0;
|
||||
});
|
||||
|
||||
|
||||
EXO_TEST(list_append_2, {
|
||||
list_append(list, A);
|
||||
list_append(list, B);
|
||||
return list->size == 2;
|
||||
});
|
||||
|
||||
EXO_TEST(list_remove_2, {
|
||||
list_remove(list, (char*) A);
|
||||
return list->size == 1;
|
||||
});
|
||||
|
||||
EXO_TEST(list_remove_3, {
|
||||
list_remove(list, (char*) A); /* already removed, so should have no effect */
|
||||
return list->size == 1;
|
||||
});
|
||||
|
||||
EXO_TEST(list_remove_4, {
|
||||
list_remove(list, (char*) B); /* already removed, so should have no effect */
|
||||
return list->size == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(list_append_3, {
|
||||
list_append(list, A);
|
||||
list_append(list, B);
|
||||
list_append(list, C);
|
||||
return list->size == 3;
|
||||
});
|
||||
|
||||
EXO_TEST(list_append_4, {
|
||||
list_append(list, A); /* OK. adding the same one *AGAIN* */
|
||||
return list->size == 4;
|
||||
});
|
||||
|
||||
EXO_TEST(list_remove_5, {
|
||||
list_remove(list, A); /* removing the first one. */
|
||||
return list->size == 3;
|
||||
});
|
||||
|
||||
EXO_TEST(list_get_index_1, {
|
||||
return list_get_index(list, 0) == B;
|
||||
});
|
||||
|
||||
EXO_TEST(list_get_index_2, {
|
||||
return list_get_index(list, 1) == C;
|
||||
});
|
||||
|
||||
EXO_TEST(list_get_index_3, {
|
||||
return list_get_index(list, 2) == A;
|
||||
});
|
||||
|
||||
EXO_TEST(list_get_index_4, {
|
||||
return list_get_index(list, 3) == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(list_get_first_1, {
|
||||
return list_get_first(list) == B;
|
||||
});
|
||||
|
||||
EXO_TEST(list_get_first_next_1, {
|
||||
return list_get_next(list) == C;
|
||||
});
|
||||
|
||||
EXO_TEST(list_get_first_next_2, {
|
||||
return list_get_next(list) == A;
|
||||
});
|
||||
|
||||
EXO_TEST(list_get_last_1, {
|
||||
return list_get_last(list) == A;
|
||||
});
|
||||
|
||||
EXO_TEST(list_get_last_prev_1, {
|
||||
return list_get_prev(list) == C;
|
||||
});
|
||||
|
||||
EXO_TEST(list_get_last_prev_2, {
|
||||
return list_get_prev(list) == B;
|
||||
});
|
||||
|
||||
EXO_TEST(list_get_last_prev_next_1, {
|
||||
return list_get_next(list) == C;
|
||||
});
|
||||
|
||||
EXO_TEST(list_clear, {
|
||||
list_clear(list, &null_free);
|
||||
return list->size == 0 && list->first == 0 && list->last == 0 && list->iterator == 0;
|
||||
});
|
||||
|
||||
|
||||
EXO_TEST(list_destroy_1, {
|
||||
list_destroy(list);
|
||||
return 1;
|
||||
});
|
||||
|
||||
EXO_TEST(list_destroy_2, {
|
||||
list_destroy(0);
|
||||
return 1;
|
||||
});
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
struct adc_message* g_msg;
|
||||
|
||||
EXO_TEST(test_message_refc_1, {
|
||||
g_msg = adc_msg_create("IMSG Hello\\sWorld!");
|
||||
return g_msg != NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(test_message_refc_2, {
|
||||
return g_msg->references == 1;
|
||||
});
|
||||
|
||||
EXO_TEST(test_message_refc_3, {
|
||||
adc_msg_incref(g_msg);
|
||||
return g_msg->references == 2;
|
||||
});
|
||||
|
||||
EXO_TEST(test_message_refc_4, {
|
||||
adc_msg_incref(g_msg);
|
||||
return g_msg->references == 3;
|
||||
});
|
||||
|
||||
EXO_TEST(test_message_refc_5, {
|
||||
adc_msg_free(g_msg);
|
||||
return g_msg->references == 2;
|
||||
});
|
||||
|
||||
EXO_TEST(test_message_refc_6, {
|
||||
adc_msg_free(g_msg);
|
||||
return g_msg->references == 1;
|
||||
});
|
||||
|
||||
EXO_TEST(test_message_refc_7, {
|
||||
adc_msg_free(g_msg);
|
||||
return 1;
|
||||
});
|
||||
@@ -1,560 +0,0 @@
|
||||
#include <uhub.h>
|
||||
static struct hub_user* g_user = 0;
|
||||
static const char* test_string1 = "IINF AAfoo BBbar CCwhat\n";
|
||||
static const char* test_string2 = "BMSG AAAB Hello\\sWorld!\n";
|
||||
static const char* test_string3 = "BINF AAAB IDAN7ZMSLIEBL53OPTM7WXGSTXUS3XOY6KQS5LBGX NIFriend DEstuff SL3 SS0 SF0 VEQuickDC/0.4.17 US6430 SUADC0,TCP4,UDP4 I4127.0.0.1 HO5 HN1 AW\n";
|
||||
static const char* test_string4 = "BMSG AAAB\n";
|
||||
static const char* test_string5 = "BMSG AAAB \n";
|
||||
|
||||
static void create_test_user()
|
||||
{
|
||||
if (g_user)
|
||||
return;
|
||||
|
||||
g_user = (struct hub_user*) malloc(sizeof(struct hub_user));
|
||||
memset(g_user, 0, sizeof(struct hub_user));
|
||||
memcpy(g_user->id.nick, "exotic-tester", 13);
|
||||
g_user->id.sid = 1;
|
||||
}
|
||||
|
||||
EXO_TEST(adc_message_first, {
|
||||
create_test_user();
|
||||
return g_user != 0;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_1, {
|
||||
struct adc_message* msg = adc_msg_create("IMSG Hello\\sWorld!");
|
||||
int ok = msg != NULL;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_2, {
|
||||
struct adc_message* msg = adc_msg_create(test_string2);
|
||||
int ok = (msg != NULL);
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_3, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "BMSG AAAB Hello\\sWorld!", 23);
|
||||
int ok = msg != NULL;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_4, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "BMSG AAAC Hello\\sWorld!", 23);
|
||||
return msg == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_5, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "BMSG AAAB Hello\\sWorld!\n", 24);
|
||||
int ok = msg != NULL;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_6, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB +TCP4 Hello\\sWorld!\n", 30);
|
||||
int ok = msg != NULL;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_7, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB -TCP4 Hello\\sWorld!\n", 30);
|
||||
int ok = msg != NULL;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_8, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB +TCP4+UDP4 Hello\\sWorld!\n", 35);
|
||||
int ok = msg != NULL;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_9, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB +TCP4-UDP4 Hello\\sWorld!\n", 35);
|
||||
int ok = msg != NULL;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_10, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB -TCP4-UDP4 Hello\\sWorld!\n", 35);
|
||||
int ok = msg != NULL;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_11, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB Hello\\sWorld!\n", 24);
|
||||
return msg == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_12, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB Hello\\sWorld!\n", 25);
|
||||
return msg == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_13, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB +jalla Hello\\sWorld!\n", 31);
|
||||
return msg == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_14, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB +jall Hello\\sWorld!\n", 30);
|
||||
int ok = msg != NULL;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_15, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB +TCP4 Hello\\sWorld!\n", 30);
|
||||
int ok = msg != NULL;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_16, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "BMSG AAAB Hello\\sWorld!\n", 24);
|
||||
int ok = msg != NULL;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_17, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "BMSG aaab Hello\\sWorld!\n", 24);
|
||||
return msg == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_18, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "DMSG AAAB AAAC Hello\\sthere!\n", 29);
|
||||
int ok = msg != NULL;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_19, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "DMSG AAAC AAAB Hello\\sthere!\n", 29);
|
||||
return msg == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_20, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "EMSG AAAB AAAC Hello\\sthere!\n", 29);
|
||||
int ok = msg != NULL;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_21, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "EMSG AAAC AAAB Hello\\sthere!\n", 29);
|
||||
return msg == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_22, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "\n", 0);
|
||||
return msg == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_23, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "\r\n", 1);
|
||||
return msg == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_parse_24, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, "EMSG AAAC\0AAAB Hello\\sthere!\n", 29);
|
||||
return msg == NULL;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
EXO_TEST(adc_message_add_arg_1, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_add_argument(msg, "XXwtf?");
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat XXwtf?\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_add_arg_2, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_add_named_argument(msg, "XX", "wtf?");
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat XXwtf?\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_remove_arg_1, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_remove_named_argument(msg, "AA");
|
||||
int ok = strcmp(msg->cache, "IINF BBbar CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_remove_arg_2, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_remove_named_argument(msg, "BB");
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_remove_arg_3, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_remove_named_argument(msg, "CC");
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_remove_arg_4, {
|
||||
/* this ensures we can remove the last element also */
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, test_string3, strlen(test_string3));
|
||||
adc_msg_remove_named_argument(msg, "AW");
|
||||
int ok = strcmp(msg->cache, "BINF AAAB IDAN7ZMSLIEBL53OPTM7WXGSTXUS3XOY6KQS5LBGX NIFriend DEstuff SL3 SS0 SF0 VEQuickDC/0.4.17 US6430 SUADC0,TCP4,UDP4 I4127.0.0.1 HO5 HN1\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_replace_arg_1, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_remove_named_argument(msg, "AA");
|
||||
int ok = strcmp(msg->cache, "IINF BBbar CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_replace_arg_2, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_remove_named_argument(msg, "BB");
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_replace_arg_3, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_remove_named_argument(msg, "CC");
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_get_arg_1, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
char* c = adc_msg_get_argument(msg, 0);
|
||||
int ok = strcmp(c, "AAfoo") == 0;
|
||||
adc_msg_free(msg);
|
||||
hub_free(c);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_get_arg_2, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
char* c = adc_msg_get_argument(msg, 1);
|
||||
int ok = strcmp(c, "BBbar") == 0;
|
||||
adc_msg_free(msg);
|
||||
hub_free(c);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_get_arg_3, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
char* c = adc_msg_get_argument(msg, 2);
|
||||
int ok = strcmp(c, "CCwhat") == 0;
|
||||
adc_msg_free(msg);
|
||||
hub_free(c);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_get_arg_4, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
char* c = adc_msg_get_argument(msg, 3);
|
||||
int ok = c == 0;
|
||||
adc_msg_free(msg);
|
||||
hub_free(c);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_get_named_arg_1, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
char* c = adc_msg_get_named_argument(msg, "AA");
|
||||
int ok = strcmp(c, "foo") == 0;
|
||||
adc_msg_free(msg);
|
||||
hub_free(c);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_get_named_arg_2, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
char* c = adc_msg_get_named_argument(msg, "BB");
|
||||
int ok = strcmp(c, "bar") == 0;
|
||||
adc_msg_free(msg);
|
||||
hub_free(c);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_get_named_arg_3, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
char* c = adc_msg_get_named_argument(msg, "CC");
|
||||
int ok = strcmp(c, "what") == 0;
|
||||
adc_msg_free(msg);
|
||||
hub_free(c);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_get_named_arg_4, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
char* c = adc_msg_get_named_argument(msg, "XX");
|
||||
int ok = c == 0;
|
||||
adc_msg_free(msg);
|
||||
hub_free(c);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_has_named_arg_1, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
int n = adc_msg_has_named_argument(msg, "XX");
|
||||
adc_msg_free(msg);
|
||||
return n == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_has_named_arg_2, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
int n = adc_msg_has_named_argument(msg, "BB");
|
||||
adc_msg_free(msg);
|
||||
return n == 1;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_has_named_arg_3, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
int n = adc_msg_has_named_argument(msg, "CC");
|
||||
adc_msg_free(msg);
|
||||
return n == 1;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_has_named_arg_4, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_add_argument(msg, "XXwtf?");
|
||||
int n = adc_msg_has_named_argument(msg, "XX");
|
||||
adc_msg_free(msg);
|
||||
return n == 1;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_has_named_arg_5, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_add_argument(msg, "XXone");
|
||||
adc_msg_add_argument(msg, "XXtwo");
|
||||
int n = adc_msg_has_named_argument(msg, "XX");
|
||||
adc_msg_free(msg);
|
||||
return n == 2;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_has_named_arg_6, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_add_argument(msg, "XXone");
|
||||
adc_msg_add_argument(msg, "XXtwo");
|
||||
adc_msg_add_argument(msg, "XXthree");
|
||||
int n = adc_msg_has_named_argument(msg, "XX");
|
||||
adc_msg_free(msg);
|
||||
return n == 3;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_has_named_arg_7, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
int n = adc_msg_has_named_argument(msg, "AA");
|
||||
adc_msg_free(msg);
|
||||
return n == 1;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_terminate_1, {
|
||||
struct adc_message* msg = adc_msg_create("IINF AAfoo BBbar CCwhat");
|
||||
adc_msg_unterminate(msg);
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_terminate_2, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_unterminate(msg);
|
||||
adc_msg_terminate(msg);
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_terminate_3, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_unterminate(msg);
|
||||
adc_msg_terminate(msg);
|
||||
adc_msg_unterminate(msg);
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_terminate_4, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_unterminate(msg);
|
||||
adc_msg_terminate(msg);
|
||||
adc_msg_terminate(msg);
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_terminate_5, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_terminate(msg);
|
||||
adc_msg_terminate(msg);
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_terminate_6, {
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_unterminate(msg);
|
||||
adc_msg_unterminate(msg);
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_escape_1, {
|
||||
char* s = adc_msg_escape(test_string1);
|
||||
int ok = strcmp(s, "IINF\\sAAfoo\\sBBbar\\sCCwhat\\n") == 0;
|
||||
hub_free(s);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_escape_2, {
|
||||
char* s = adc_msg_escape(test_string1);
|
||||
char* s2 = adc_msg_unescape(s);
|
||||
int ok = strcmp(s2, test_string1) == 0;
|
||||
hub_free(s);
|
||||
hub_free(s2);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_escape_3, {
|
||||
char* s = adc_msg_unescape(test_string1);
|
||||
int ok = strcmp(s, test_string1) == 0;
|
||||
hub_free(s);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_copy_1, {
|
||||
struct adc_message* msg1 = adc_msg_create(test_string1);
|
||||
struct adc_message* msg2 = adc_msg_copy(msg1);
|
||||
int ok = strncmp(msg1->cache, msg2->cache, msg1->length) == 0;
|
||||
adc_msg_free(msg1);
|
||||
adc_msg_free(msg2);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_copy_2, {
|
||||
struct adc_message* msg1 = adc_msg_parse_verify(g_user, test_string2, strlen(test_string2));
|
||||
struct adc_message* msg2 = adc_msg_copy(msg1);
|
||||
int ok = msg1->source == msg2->source;
|
||||
adc_msg_free(msg1);
|
||||
adc_msg_free(msg2);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_copy_3, {
|
||||
struct adc_message* msg1 = adc_msg_parse_verify(g_user, test_string2, strlen(test_string2));
|
||||
struct adc_message* msg2 = adc_msg_copy(msg1);
|
||||
int ok = ( msg1->cmd == msg2->cmd &&
|
||||
msg1->source == msg2->source &&
|
||||
msg1->target == msg2->target &&
|
||||
msg1->length == msg2->length &&
|
||||
msg1->priority == msg2->priority &&
|
||||
msg1->capacity == msg2->capacity && /* might not be true! */
|
||||
strcmp(msg1->cache, msg2->cache) == 0);
|
||||
adc_msg_free(msg1);
|
||||
adc_msg_free(msg2);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_copy_4, {
|
||||
struct adc_message* msg1 = adc_msg_parse_verify(g_user, test_string2, strlen(test_string2));
|
||||
struct adc_message* msg2 = adc_msg_copy(msg1);
|
||||
int ok = msg2->target == 0;
|
||||
adc_msg_free(msg1);
|
||||
adc_msg_free(msg2);
|
||||
return ok;
|
||||
});
|
||||
|
||||
|
||||
static struct adc_message* updater1 = NULL;
|
||||
static struct adc_message* updater2 = NULL;
|
||||
static const char* update_info1 = "BINF AAAB IDABCDEFGHIJKLMNOPQRSTUVWXYZ1234567ABCDEF NItester SL10 SS12817126127 SF4125 HN3 HR0 HO0 VE++\\s0.698 US104857600 DS81911808 SUTCP4,UDP4 I4127.0.0.1\n";
|
||||
static const char* update_info2 = "BINF AAAB HN34 SF4126 SS12817526127\n";
|
||||
|
||||
EXO_TEST(adc_message_update_1, {
|
||||
updater1 = adc_msg_parse_verify(g_user, update_info1, strlen(update_info1));
|
||||
return updater1 != NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_update_2, {
|
||||
user_set_info(g_user, updater1);
|
||||
return strcmp(g_user->info->cache, updater1->cache) == 0 && g_user->info == updater1;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_update_3, {
|
||||
updater2 = adc_msg_parse_verify(g_user, update_info2, strlen(update_info2));
|
||||
return updater2 != NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_update_4, {
|
||||
user_update_info(g_user, updater2);
|
||||
return strlen(g_user->info->cache) == 159;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_update_4_cleanup, {
|
||||
adc_msg_free(updater1);
|
||||
updater1 = 0;
|
||||
adc_msg_free(updater2);
|
||||
updater2 = 0;
|
||||
adc_msg_free(g_user->info);
|
||||
g_user->info = 0;
|
||||
return 1;
|
||||
});
|
||||
|
||||
|
||||
EXO_TEST(adc_message_empty_1, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, test_string2, strlen(test_string2));
|
||||
int ok = adc_msg_is_empty(msg) == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_empty_2, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, test_string4, strlen(test_string4));
|
||||
int ok = adc_msg_is_empty(msg);
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_empty_3, {
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, test_string5, strlen(test_string5));
|
||||
int ok = adc_msg_is_empty(msg) == 0; /* arguably not empty, contains a space */
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_last, {
|
||||
hub_free(g_user);
|
||||
g_user = 0;
|
||||
return g_user == 0;
|
||||
});
|
||||
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
EXO_TEST(is_num_0, { return is_num('0'); });
|
||||
EXO_TEST(is_num_1, { return is_num('1'); });
|
||||
EXO_TEST(is_num_2, { return is_num('2'); });
|
||||
EXO_TEST(is_num_3, { return is_num('3'); });
|
||||
EXO_TEST(is_num_4, { return is_num('4'); });
|
||||
EXO_TEST(is_num_5, { return is_num('5'); });
|
||||
EXO_TEST(is_num_6, { return is_num('6'); });
|
||||
EXO_TEST(is_num_7, { return is_num('7'); });
|
||||
EXO_TEST(is_num_8, { return is_num('8'); });
|
||||
EXO_TEST(is_num_9, { return is_num('9'); });
|
||||
EXO_TEST(is_num_10, { return !is_num('/'); });
|
||||
EXO_TEST(is_num_11, { return !is_num(':'); });
|
||||
|
||||
EXO_TEST(is_space_1, { return is_space(' '); });
|
||||
EXO_TEST(is_space_2, { return !is_space('\t'); });
|
||||
EXO_TEST(is_white_space_1, { return is_white_space(' '); });
|
||||
EXO_TEST(is_white_space_2, { return is_white_space('\t'); });
|
||||
EXO_TEST(is_white_space_3, { return !is_white_space('A'); });
|
||||
EXO_TEST(is_white_space_4, { return !is_white_space('!'); });
|
||||
|
||||
EXO_TEST(itoa_1, { return strcmp(uhub_itoa(0), "0") == 0; });
|
||||
EXO_TEST(itoa_2, { return strcmp(uhub_itoa(1), "1") == 0; });
|
||||
EXO_TEST(itoa_3, { return strcmp(uhub_itoa(-1), "-1") == 0; });
|
||||
EXO_TEST(itoa_4, { return strcmp(uhub_itoa(255), "255") == 0; });
|
||||
EXO_TEST(itoa_5, { return strcmp(uhub_itoa(-3), "-3") == 0; });
|
||||
EXO_TEST(itoa_6, { return strcmp(uhub_itoa(-2147483647), "-2147483647") == 0; });
|
||||
EXO_TEST(itoa_7, { return strcmp(uhub_itoa(2147483647), "2147483647") == 0; });
|
||||
EXO_TEST(itoa_8, { return strcmp(uhub_itoa(-65536), "-65536") == 0; });
|
||||
|
||||
EXO_TEST(base32_valid_1, { return is_valid_base32_char('A'); });
|
||||
EXO_TEST(base32_valid_2, { return is_valid_base32_char('B'); });
|
||||
EXO_TEST(base32_valid_3, { return is_valid_base32_char('C'); });
|
||||
EXO_TEST(base32_valid_4, { return is_valid_base32_char('D'); });
|
||||
EXO_TEST(base32_valid_5, { return is_valid_base32_char('E'); });
|
||||
EXO_TEST(base32_valid_6, { return is_valid_base32_char('F'); });
|
||||
EXO_TEST(base32_valid_7, { return is_valid_base32_char('G'); });
|
||||
EXO_TEST(base32_valid_8, { return is_valid_base32_char('H'); });
|
||||
EXO_TEST(base32_valid_9, { return is_valid_base32_char('I'); });
|
||||
EXO_TEST(base32_valid_10, { return is_valid_base32_char('J'); });
|
||||
EXO_TEST(base32_valid_11, { return is_valid_base32_char('K'); });
|
||||
EXO_TEST(base32_valid_12, { return is_valid_base32_char('L'); });
|
||||
EXO_TEST(base32_valid_13, { return is_valid_base32_char('M'); });
|
||||
EXO_TEST(base32_valid_14, { return is_valid_base32_char('N'); });
|
||||
EXO_TEST(base32_valid_15, { return is_valid_base32_char('O'); });
|
||||
EXO_TEST(base32_valid_16, { return is_valid_base32_char('P'); });
|
||||
EXO_TEST(base32_valid_17, { return is_valid_base32_char('Q'); });
|
||||
EXO_TEST(base32_valid_18, { return is_valid_base32_char('R'); });
|
||||
EXO_TEST(base32_valid_19, { return is_valid_base32_char('S'); });
|
||||
EXO_TEST(base32_valid_20, { return is_valid_base32_char('T'); });
|
||||
EXO_TEST(base32_valid_21, { return is_valid_base32_char('U'); });
|
||||
EXO_TEST(base32_valid_22, { return is_valid_base32_char('V'); });
|
||||
EXO_TEST(base32_valid_23, { return is_valid_base32_char('W'); });
|
||||
EXO_TEST(base32_valid_24, { return is_valid_base32_char('X'); });
|
||||
EXO_TEST(base32_valid_25, { return is_valid_base32_char('Y'); });
|
||||
EXO_TEST(base32_valid_26, { return is_valid_base32_char('Z'); });
|
||||
EXO_TEST(base32_valid_27, { return is_valid_base32_char('2'); });
|
||||
EXO_TEST(base32_valid_28, { return is_valid_base32_char('3'); });
|
||||
EXO_TEST(base32_valid_29, { return is_valid_base32_char('4'); });
|
||||
EXO_TEST(base32_valid_30, { return is_valid_base32_char('5'); });
|
||||
EXO_TEST(base32_valid_31, { return is_valid_base32_char('6'); });
|
||||
EXO_TEST(base32_valid_32, { return is_valid_base32_char('7'); });
|
||||
|
||||
EXO_TEST(base32_invalid_1, { return !is_valid_base32_char('a'); });
|
||||
EXO_TEST(base32_invalid_2, { return !is_valid_base32_char('b'); });
|
||||
EXO_TEST(base32_invalid_3, { return !is_valid_base32_char('c'); });
|
||||
EXO_TEST(base32_invalid_4, { return !is_valid_base32_char('d'); });
|
||||
EXO_TEST(base32_invalid_5, { return !is_valid_base32_char('e'); });
|
||||
EXO_TEST(base32_invalid_6, { return !is_valid_base32_char('f'); });
|
||||
EXO_TEST(base32_invalid_7, { return !is_valid_base32_char('g'); });
|
||||
EXO_TEST(base32_invalid_8, { return !is_valid_base32_char('h'); });
|
||||
EXO_TEST(base32_invalid_9, { return !is_valid_base32_char('i'); });
|
||||
EXO_TEST(base32_invalid_10, { return !is_valid_base32_char('j'); });
|
||||
EXO_TEST(base32_invalid_11, { return !is_valid_base32_char('k'); });
|
||||
EXO_TEST(base32_invalid_12, { return !is_valid_base32_char('l'); });
|
||||
EXO_TEST(base32_invalid_13, { return !is_valid_base32_char('m'); });
|
||||
EXO_TEST(base32_invalid_14, { return !is_valid_base32_char('n'); });
|
||||
EXO_TEST(base32_invalid_15, { return !is_valid_base32_char('o'); });
|
||||
EXO_TEST(base32_invalid_16, { return !is_valid_base32_char('p'); });
|
||||
EXO_TEST(base32_invalid_17, { return !is_valid_base32_char('q'); });
|
||||
EXO_TEST(base32_invalid_18, { return !is_valid_base32_char('r'); });
|
||||
EXO_TEST(base32_invalid_19, { return !is_valid_base32_char('s'); });
|
||||
EXO_TEST(base32_invalid_20, { return !is_valid_base32_char('t'); });
|
||||
EXO_TEST(base32_invalid_21, { return !is_valid_base32_char('u'); });
|
||||
EXO_TEST(base32_invalid_22, { return !is_valid_base32_char('v'); });
|
||||
EXO_TEST(base32_invalid_23, { return !is_valid_base32_char('w'); });
|
||||
EXO_TEST(base32_invalid_24, { return !is_valid_base32_char('x'); });
|
||||
EXO_TEST(base32_invalid_25, { return !is_valid_base32_char('y'); });
|
||||
EXO_TEST(base32_invalid_26, { return !is_valid_base32_char('z'); });
|
||||
EXO_TEST(base32_invalid_27, { return !is_valid_base32_char('0'); });
|
||||
EXO_TEST(base32_invalid_28, { return !is_valid_base32_char('1'); });
|
||||
EXO_TEST(base32_invalid_29, { return !is_valid_base32_char('8'); });
|
||||
EXO_TEST(base32_invalid_30, { return !is_valid_base32_char('9'); });
|
||||
EXO_TEST(base32_invalid_31, { return !is_valid_base32_char('@'); });
|
||||
|
||||
EXO_TEST(utf8_valid_1, { return is_valid_utf8("abcdefghijklmnopqrstuvwxyz"); });
|
||||
EXO_TEST(utf8_valid_2, { return is_valid_utf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); });
|
||||
EXO_TEST(utf8_valid_3, { return is_valid_utf8("0123456789"); });
|
||||
EXO_TEST(utf8_valid_4, { return is_valid_utf8( (char[]) { 0x65, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_5, { return !is_valid_utf8( (char[]) { 0xD8, 0x00} ); });
|
||||
|
||||
EXO_TEST(utf8_valid_6, { return is_valid_utf8( (char[]) { 0x24, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_7, { return !is_valid_utf8( (char[]) { 0xC2, 0x24, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_8, { return is_valid_utf8( (char[]) { 0xC2, 0xA2, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_9, { return is_valid_utf8( (char[]) { 0xE2, 0x82, 0xAC, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_10, { return !is_valid_utf8( (char[]) { 0xC2, 0x32, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_11, { return !is_valid_utf8( (char[]) { 0xE2, 0x82, 0x32, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_12, { return !is_valid_utf8( (char[]) { 0xE2, 0x32, 0x82, 0x00} ); });
|
||||
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
static struct sid_pool* sid_pool = 0;
|
||||
|
||||
struct dummy_user
|
||||
{
|
||||
sid_t sid;
|
||||
};
|
||||
|
||||
static struct dummy_user* last = 0;
|
||||
sid_t last_sid = 0;
|
||||
|
||||
EXO_TEST(sid_create_pool, {
|
||||
sid_pool = sid_pool_create(4);
|
||||
return sid_pool != 0;
|
||||
});
|
||||
|
||||
EXO_TEST(sid_check_0a, {
|
||||
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, 0);
|
||||
return user == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(sid_check_0b, {
|
||||
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, 5);
|
||||
return user == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(sid_alloc_1, {
|
||||
struct dummy_user* user = hub_malloc_zero(sizeof(struct dummy_user));
|
||||
user->sid = sid_alloc(sid_pool, (struct hub_user*) user);
|
||||
last = user;
|
||||
last_sid = user->sid;
|
||||
return (user->sid > 0 && user->sid < 1048576);
|
||||
});
|
||||
|
||||
EXO_TEST(sid_check_1a, {
|
||||
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid);
|
||||
return last == user;
|
||||
});
|
||||
|
||||
EXO_TEST(sid_check_1b, {
|
||||
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid+1);
|
||||
return user == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(sid_alloc_2, {
|
||||
struct dummy_user* user = hub_malloc_zero(sizeof(struct dummy_user));
|
||||
user->sid = sid_alloc(sid_pool, (struct hub_user*) user);
|
||||
last_sid = user->sid;
|
||||
return (user->sid > 0 && user->sid < 1048576);
|
||||
});
|
||||
|
||||
EXO_TEST(sid_check_2, {
|
||||
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid);
|
||||
return last != user;
|
||||
});
|
||||
|
||||
EXO_TEST(sid_alloc_3, {
|
||||
struct dummy_user* user = hub_malloc_zero(sizeof(struct dummy_user));
|
||||
user->sid = sid_alloc(sid_pool, (struct hub_user*) user);
|
||||
last_sid = user->sid;
|
||||
return (user->sid > 0 && user->sid < 1048576);
|
||||
});
|
||||
|
||||
EXO_TEST(sid_check_3, {
|
||||
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid);
|
||||
return last != user;
|
||||
});
|
||||
|
||||
EXO_TEST(sid_alloc_4, {
|
||||
struct dummy_user* user = hub_malloc_zero(sizeof(struct dummy_user));
|
||||
user->sid = sid_alloc(sid_pool, (struct hub_user*) user);
|
||||
last_sid = user->sid;
|
||||
return (user->sid > 0 && user->sid < 1048576);
|
||||
});
|
||||
|
||||
EXO_TEST(sid_check_4, {
|
||||
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid);
|
||||
return last != user;
|
||||
});
|
||||
|
||||
EXO_TEST(sid_alloc_5, {
|
||||
struct dummy_user user;
|
||||
sid_t sid;
|
||||
sid = sid_alloc(sid_pool, (struct hub_user*) &user);
|
||||
return sid == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(sid_check_6, {
|
||||
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, 0);
|
||||
return user == 0;
|
||||
});
|
||||
|
||||
|
||||
EXO_TEST(sid_list_all_1, {
|
||||
sid_t s;
|
||||
size_t n = 0;
|
||||
int ok = 1;
|
||||
for (s = last->sid; s <= last_sid; s++)
|
||||
{
|
||||
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, s);
|
||||
if (s != (user ? user->sid : -1))
|
||||
{
|
||||
ok = 0;
|
||||
break;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
return ok && n == 4;
|
||||
});
|
||||
|
||||
#define FREE_SID(N) \
|
||||
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, N); \
|
||||
sid_free(sid_pool, N); \
|
||||
hub_free(user); \
|
||||
return sid_lookup(sid_pool, N) == NULL;
|
||||
|
||||
EXO_TEST(sid_remove_1, {
|
||||
FREE_SID(2);
|
||||
});
|
||||
|
||||
EXO_TEST(sid_remove_2, {
|
||||
FREE_SID(1);
|
||||
});
|
||||
|
||||
EXO_TEST(sid_remove_3, {
|
||||
FREE_SID(4);
|
||||
});
|
||||
|
||||
EXO_TEST(sid_remove_4, {
|
||||
FREE_SID(3);
|
||||
});
|
||||
|
||||
EXO_TEST(sid_destroy_pool, {
|
||||
sid_pool_destroy(sid_pool);
|
||||
sid_pool = 0;
|
||||
return sid_pool == 0;
|
||||
});
|
||||
@@ -1,69 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
#define DEBUG_HASH
|
||||
|
||||
static char* byte_to_hex(char* dest, uint8_t c)
|
||||
{
|
||||
static const char* hexchars = "0123456789abcdef";
|
||||
*dest = hexchars[c / 16]; dest++;
|
||||
*dest = hexchars[c % 16]; dest++;
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
static int test_tiger_hex(char* input, char* expected) {
|
||||
char buf[TIGERSIZE*2+1];
|
||||
uint64_t tiger_res[3];
|
||||
int i = 0;
|
||||
#ifdef DEBUG_HASH
|
||||
int res = 0;
|
||||
#endif
|
||||
char* ptr = buf;
|
||||
buf[TIGERSIZE*2] = 0;
|
||||
|
||||
tiger((uint64_t*) input, strlen(input), (uint64_t*) tiger_res);
|
||||
for (i = 0; i < TIGERSIZE; i++)
|
||||
ptr = byte_to_hex(ptr, (char) (((uint8_t*) tiger_res)[i]) );
|
||||
|
||||
#ifdef DEBUG_HASH
|
||||
res = strcasecmp(buf, expected) == 0 ? 1 : 0;
|
||||
|
||||
if (!res)
|
||||
{
|
||||
printf("Expected: '%s', Got: '%s'\n", expected, buf);
|
||||
}
|
||||
return res;
|
||||
#else
|
||||
return strcasecmp(buf, expected) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
EXO_TEST(hash_tiger_1, {
|
||||
return test_tiger_hex("", "3293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3");
|
||||
});
|
||||
|
||||
EXO_TEST(hash_tiger_2, {
|
||||
return test_tiger_hex("a", "77BEFBEF2E7EF8AB2EC8F93BF587A7FC613E247F5F247809");
|
||||
});
|
||||
|
||||
EXO_TEST(hash_tiger_3, {
|
||||
return test_tiger_hex("abc", "2AAB1484E8C158F2BFB8C5FF41B57A525129131C957B5F93");
|
||||
});
|
||||
|
||||
EXO_TEST(hash_tiger_4, {
|
||||
return test_tiger_hex("message digest", "D981F8CB78201A950DCF3048751E441C517FCA1AA55A29F6");
|
||||
});
|
||||
|
||||
EXO_TEST(hash_tiger_5, {
|
||||
return test_tiger_hex("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "0F7BF9A19B9C58F2B7610DF7E84F0AC3A71C631E7B53F78E");
|
||||
});
|
||||
|
||||
EXO_TEST(hash_tiger_6, {
|
||||
return test_tiger_hex("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "8DCEA680A17583EE502BA38A3C368651890FFBCCDC49A8CC");
|
||||
});
|
||||
|
||||
EXO_TEST(hash_tiger_7, {
|
||||
return test_tiger_hex("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "1C14795529FD9F207A958F84C52F11E887FA0CABDFD91BFD");
|
||||
});
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
#define MAX_EVENTS 15
|
||||
static struct timeout_queue* g_queue;
|
||||
static time_t g_now;
|
||||
static size_t g_max;
|
||||
static struct timeout_evt g_events[MAX_EVENTS];
|
||||
|
||||
static size_t g_triggered;
|
||||
|
||||
static void timeout_cb(struct timeout_evt* t)
|
||||
{
|
||||
g_triggered++;
|
||||
}
|
||||
|
||||
/*
|
||||
typedef void (*timeout_evt_cb)(struct timeout_evt*);
|
||||
|
||||
struct timeout_evt
|
||||
{
|
||||
time_t timestamp;
|
||||
timeout_evt_cb callback;
|
||||
void* ptr;
|
||||
struct timeout_evt* prev;
|
||||
struct timeout_evt* next;
|
||||
};
|
||||
|
||||
void timeout_evt_initialize(struct timeout_evt*, timeout_evt_cb, void* ptr);
|
||||
void timeout_evt_reset(struct timeout_evt*);
|
||||
int timeout_evt_is_scheduled(struct timeout_evt*);
|
||||
|
||||
|
||||
struct timeout_queue
|
||||
{
|
||||
time_t last;
|
||||
size_t max;
|
||||
struct timeout_evt** events;
|
||||
};
|
||||
|
||||
void timeout_queue_initialize(struct timeout_queue*, time_t now, size_t max);
|
||||
void timeout_queue_shutdown(struct timeout_queue*);
|
||||
size_t timeout_queue_process(struct timeout_queue*, time_t now);
|
||||
void timeout_queue_insert(struct timeout_queue*, struct timeout_evt*, size_t seconds);
|
||||
void timeout_queue_remove(struct timeout_queue*, struct timeout_evt*);
|
||||
void timeout_queue_reschedule(struct timeout_queue*, struct timeout_evt*, size_t seconds);
|
||||
|
||||
size_t timeout_queue_get_next_timeout(struct timeout_queue*, time_t now);
|
||||
*/
|
||||
|
||||
|
||||
EXO_TEST(timer_setup,{
|
||||
size_t n;
|
||||
g_queue = hub_malloc_zero(sizeof(struct timeout_queue));
|
||||
g_now = 0;
|
||||
g_max = 5;
|
||||
g_triggered = 0;
|
||||
timeout_queue_initialize(g_queue, g_now, g_max);
|
||||
|
||||
memset(g_events, 0, sizeof(g_events));
|
||||
for (n = 0; n < MAX_EVENTS; n++)
|
||||
{
|
||||
timeout_evt_initialize(&g_events[n], timeout_cb, &g_events[n]);
|
||||
}
|
||||
|
||||
return g_queue != NULL;
|
||||
});
|
||||
|
||||
|
||||
EXO_TEST(timer_check_timeout_0,{
|
||||
return timeout_queue_get_next_timeout(g_queue, g_now) == g_max;
|
||||
});
|
||||
|
||||
|
||||
EXO_TEST(timer_add_event_1,{
|
||||
timeout_queue_insert(g_queue, &g_events[0], 2);
|
||||
return g_events[0].prev != NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(timer_check_timeout_1,{
|
||||
return timeout_queue_get_next_timeout(g_queue, g_now) == 2;
|
||||
});
|
||||
|
||||
EXO_TEST(timer_remove_event_1,{
|
||||
timeout_queue_remove(g_queue, &g_events[0]);
|
||||
return g_events[0].prev == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(timer_check_timeout_2,{
|
||||
return timeout_queue_get_next_timeout(g_queue, g_now) == g_max;
|
||||
});
|
||||
|
||||
/* test re-removing an event - should not crash! */
|
||||
EXO_TEST(timer_remove_event_1_no_crash,{
|
||||
timeout_queue_remove(g_queue, &g_events[0]);
|
||||
return g_events[0].prev == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(timer_add_5_events_1,{
|
||||
timeout_queue_insert(g_queue, &g_events[0], 0);
|
||||
timeout_queue_insert(g_queue, &g_events[1], 1);
|
||||
timeout_queue_insert(g_queue, &g_events[2], 2);
|
||||
timeout_queue_insert(g_queue, &g_events[3], 3);
|
||||
timeout_queue_insert(g_queue, &g_events[4], 4);
|
||||
|
||||
return (g_events[0].prev != NULL &&
|
||||
g_events[1].prev != NULL &&
|
||||
g_events[2].prev != NULL &&
|
||||
g_events[3].prev != NULL &&
|
||||
g_events[4].prev != NULL);
|
||||
});
|
||||
|
||||
EXO_TEST(timer_check_5_events_1,{
|
||||
return timeout_queue_get_next_timeout(g_queue, g_now) == 1;
|
||||
});
|
||||
|
||||
EXO_TEST(timer_process_5_events_1,{
|
||||
g_now = 4;
|
||||
return timeout_queue_process(g_queue, g_now) == g_triggered;
|
||||
});
|
||||
@@ -1,107 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
#define SETUP(X, STR) struct cfg_tokens* tokens = cfg_tokenize(STR)
|
||||
#define CLEANUP_LIST(X) do { list_clear(X, hub_free); list_destroy(X); } while(0)
|
||||
#define CLEANUP_TOKENS(X) do { cfg_tokens_free(X); } while(0)
|
||||
|
||||
static int match_str(const char* str1, char* str2)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < strlen(str2); i++)
|
||||
if (str2[i] == '_')
|
||||
str2[i] = ' ';
|
||||
else if (str2[i] == '|')
|
||||
str2[i] = '\t';
|
||||
|
||||
int ret = strcmp(str1, str2);
|
||||
if (ret) {
|
||||
fprintf(stderr, "\n Mismatch: \"%s\" != \"%s\"\n", str1, str2);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int count(const char* STR, size_t EXPECT) {
|
||||
SETUP(tokens, STR);
|
||||
int pass = cfg_token_count(tokens) == EXPECT;
|
||||
CLEANUP_TOKENS(tokens);
|
||||
return pass;
|
||||
}
|
||||
|
||||
static int compare(const char* str, const char* ref) {
|
||||
size_t i, max;
|
||||
struct linked_list* compare = list_create();
|
||||
SETUP(tokens, str);
|
||||
split_string(ref, " ", compare, 0);
|
||||
int pass = cfg_token_count(tokens) == list_size(compare);
|
||||
if (pass) {
|
||||
max = cfg_token_count(tokens);
|
||||
for (i = 0; i < max; i++) {
|
||||
char* token = (char*) cfg_token_get(tokens, i);
|
||||
char* refer = (char*) list_get_index(compare, i);
|
||||
if (match_str(token, refer)) {
|
||||
pass = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
CLEANUP_TOKENS(tokens);
|
||||
CLEANUP_LIST(compare);
|
||||
return pass;
|
||||
}
|
||||
|
||||
EXO_TEST(tokenizer_basic_0, { return count("", 0); });
|
||||
EXO_TEST(tokenizer_basic_1, { return count("a", 1); });
|
||||
EXO_TEST(tokenizer_basic_1a, { return count(" a", 1); })
|
||||
EXO_TEST(tokenizer_basic_1b, { return count("\ta", 1); })
|
||||
EXO_TEST(tokenizer_basic_1c, { return count(" a", 1); })
|
||||
EXO_TEST(tokenizer_basic_1d, { return count(" a ", 1); })
|
||||
EXO_TEST(tokenizer_basic_1e, { return count(" a ", 1); })
|
||||
EXO_TEST(tokenizer_basic_2, { return count("a b", 2); });
|
||||
EXO_TEST(tokenizer_basic_2a, { return count(" a b ", 2); });
|
||||
EXO_TEST(tokenizer_basic_3, { return count("a b c", 3); });
|
||||
EXO_TEST(tokenizer_basic_3a, { return count("a b c", 3); });
|
||||
EXO_TEST(tokenizer_basic_3b, { return count("a b\tc", 3); });
|
||||
EXO_TEST(tokenizer_basic_3c, { return count("a b c ", 3); });
|
||||
EXO_TEST(tokenizer_basic_3d, { return count("a b c ", 3); });
|
||||
|
||||
EXO_TEST(tokenizer_basic_compare_0, { return compare("value1 value2 value3", "value1 value2 value3"); });
|
||||
EXO_TEST(tokenizer_basic_compare_1, { return compare("a b c", "a b c"); });
|
||||
EXO_TEST(tokenizer_basic_compare_2, { return compare("a b c", "a b c"); });
|
||||
EXO_TEST(tokenizer_basic_compare_3, { return compare(" a b c", "a b c"); });
|
||||
EXO_TEST(tokenizer_basic_compare_4, { return compare(" a b c ", "a b c"); });
|
||||
EXO_TEST(tokenizer_basic_compare_5, { return compare("a b c ", "a b c"); });
|
||||
EXO_TEST(tokenizer_basic_compare_6, { return compare("a b c ", "a b c"); });
|
||||
|
||||
EXO_TEST(tokenizer_comment_1, { return compare("value1 value2 # value3", "value1 value2"); });
|
||||
EXO_TEST(tokenizer_comment_2, { return compare("value1 value2\\# value3", "value1 value2# value3"); });
|
||||
EXO_TEST(tokenizer_comment_3, { return compare("value1 \"value2#\" value3", "value1 value2# value3"); });
|
||||
|
||||
EXO_TEST(tokenizer_escape_1, { return compare("\"value1\" value2", "value1 value2"); });
|
||||
EXO_TEST(tokenizer_escape_2, { return compare("\"value1\\\"\" value2", "value1\" value2"); });
|
||||
EXO_TEST(tokenizer_escape_3, { return compare("\"value1\" \"value 2\"", "value1 value_2"); });
|
||||
EXO_TEST(tokenizer_escape_4, { return compare("\"value1\" value\\ 2", "value1 value_2"); });
|
||||
EXO_TEST(tokenizer_escape_5, { return compare("\"value1\" value\\\\2", "value1 value\\2"); });
|
||||
EXO_TEST(tokenizer_escape_6, { return compare("\"value1\" value\\\t2", "value1 value|2"); });
|
||||
EXO_TEST(tokenizer_escape_7, { return compare("\"value1\" \"value\t2\"", "value1 value|2"); });
|
||||
|
||||
static int test_setting(const char* str, const char* expected_key, const char* expected_value)
|
||||
{
|
||||
int success = 0;
|
||||
struct cfg_settings* setting = cfg_settings_split(str);
|
||||
if (!setting) return expected_key == NULL;
|
||||
success = (!strcmp(cfg_settings_get_key(setting), expected_key) && !strcmp(cfg_settings_get_value(setting), expected_value));
|
||||
cfg_settings_free(setting);
|
||||
return success;
|
||||
}
|
||||
|
||||
EXO_TEST(tokenizer_settings_1, { return test_setting("foo=bar", "foo", "bar"); });
|
||||
EXO_TEST(tokenizer_settings_2, { return test_setting("foo =bar", "foo", "bar"); });
|
||||
EXO_TEST(tokenizer_settings_3, { return test_setting("foo= bar", "foo", "bar"); });
|
||||
EXO_TEST(tokenizer_settings_4, { return test_setting("\tfoo=bar", "foo", "bar"); });
|
||||
EXO_TEST(tokenizer_settings_5, { return test_setting("foo=bar\t", "foo", "bar"); });
|
||||
EXO_TEST(tokenizer_settings_6, { return test_setting("\tfoo=bar\t", "foo", "bar"); });
|
||||
EXO_TEST(tokenizer_settings_7, { return test_setting("\tfoo\t=\tbar\t", "foo", "bar"); });
|
||||
EXO_TEST(tokenizer_settings_8, { return test_setting("foo=", "foo", ""); });
|
||||
EXO_TEST(tokenizer_settings_9, { return test_setting("=bar", NULL, ""); });
|
||||
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
#include <uhub.h>
|
||||
|
||||
#define MAX_USERS 64
|
||||
|
||||
static struct hub_info um_hub;
|
||||
static struct hub_user um_user[MAX_USERS];
|
||||
// static struct net_connection um_cons[MAX_USERS];
|
||||
|
||||
EXO_TEST(um_test_setup, {
|
||||
int i = 0;
|
||||
memset(&um_hub, 0, sizeof(um_hub));
|
||||
|
||||
for (i = 0; i < MAX_USERS; i++)
|
||||
{
|
||||
/* memset(&um_cons[i], 0, sizeof(struct net_connection));
|
||||
um_cons[i].sd = -1;
|
||||
|
||||
memset(&um_user[i], 0, sizeof(struct hub_user));
|
||||
um_user[i].id.sid = i+1;
|
||||
um_user[i].connection = &um_cons[i];*/
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
|
||||
EXO_TEST(um_init_1, {
|
||||
return uman_init(0) != 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_init_2, {
|
||||
return uman_init(&um_hub) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_shutdown_1, {
|
||||
return uman_shutdown(0) == -1;
|
||||
});
|
||||
|
||||
EXO_TEST(um_shutdown_2, {
|
||||
return uman_shutdown(&um_hub) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_shutdown_3, {
|
||||
return uman_shutdown(&um_hub) == -1;
|
||||
});
|
||||
|
||||
EXO_TEST(um_init_3, {
|
||||
return uman_init(&um_hub) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_add_1, {
|
||||
return uman_add(&um_hub, &um_user[0]) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_size_1, {
|
||||
return hub_get_user_count(&um_hub) == 1;
|
||||
});
|
||||
|
||||
|
||||
EXO_TEST(um_remove_1, {
|
||||
return uman_remove(&um_hub, &um_user[0]) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_size_2, {
|
||||
return hub_get_user_count(&um_hub) == 0;
|
||||
});
|
||||
|
||||
|
||||
EXO_TEST(um_add_2, {
|
||||
int i;
|
||||
for (i = 0; i < MAX_USERS; i++)
|
||||
{
|
||||
if (uman_add(&um_hub, &um_user[i]) != 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
|
||||
EXO_TEST(um_size_3, {
|
||||
return hub_get_user_count(&um_hub) == MAX_USERS;
|
||||
});
|
||||
|
||||
EXO_TEST(um_add_3, {
|
||||
return uman_add(&um_hub, &um_user[5]) != 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_remove_2, {
|
||||
int i;
|
||||
for (i = 0; i < MAX_USERS; i++)
|
||||
{
|
||||
if (uman_remove(&um_hub, &um_user[i]) != 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Last test */
|
||||
EXO_TEST(um_shutdown_4, {
|
||||
return uman_shutdown(&um_hub) == 0;
|
||||
});
|
||||
Vendored
-25
@@ -1,25 +0,0 @@
|
||||
uhub (0.3.2-1) unstable; urgency=low
|
||||
|
||||
* Updated upstream version.
|
||||
|
||||
-- Jan Vidar Krey <janvidar@extatic.org> Mon 30 May 2010 18:00:00 +0200
|
||||
|
||||
uhub (0.3.1-1) unstable; urgency=low
|
||||
|
||||
* Updated version number.
|
||||
|
||||
-- Jan Vidar Krey <janvidar@extatic.org> Mon 04 Apr 2010 16:44:21 +0200
|
||||
|
||||
uhub (0.3.0-2) unstable; urgency=low
|
||||
|
||||
* Fixed init.d scripts.
|
||||
* Fixed lintian warnings.
|
||||
|
||||
-- Jan Vidar Krey <janvidar@extatic.org> Tue, 26 Jan 2010 19:02:02 +0100
|
||||
|
||||
uhub (0.3.0-1) unstable; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
-- Jan Vidar Krey <janvidar@extatic.org> Tue, 26 Jan 2010 18:59:02 +0100
|
||||
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
7
|
||||
Vendored
-24
@@ -1,24 +0,0 @@
|
||||
Source: uhub
|
||||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: Jan Vidar Krey <janvidar@extatic.org>
|
||||
Build-Depends: debhelper (>= 7.0.0)
|
||||
Standards-Version: 3.8.3.0
|
||||
|
||||
Package: uhub
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}
|
||||
Description: High performance ADC p2p hub
|
||||
uhub is a high performance peer-to-peer hub for the ADC network.
|
||||
Its low memory footprint allows it to handle several thousand users on
|
||||
high-end servers, or a small private hub on embedded hardware.
|
||||
.
|
||||
Key features:
|
||||
- High performance and low memory usage
|
||||
- IPv4 and IPv6 support
|
||||
- Experimental SSL support (optional)
|
||||
- Advanced access control support
|
||||
- Easy configuration
|
||||
.
|
||||
Homepage: http://www.uhub.org/
|
||||
|
||||
Vendored
-19
@@ -1,19 +0,0 @@
|
||||
uhub - High performance ADC p2p hub.
|
||||
Copyright (C) 2010 Jan Vidar Krey <janvidar@extatic.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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
On Debian GNU/Linux systems, the complete text of the GNU General Public
|
||||
License can be found in `/usr/share/common-licenses/GPL'.
|
||||
|
||||
Vendored
-45
@@ -1,45 +0,0 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
# export DH_VERBOSE=1
|
||||
|
||||
makeopts := DESTDIR=$(shell pwd)/debian/uhub/ \
|
||||
UHUB_PREFIX=$(shell pwd)/debian/uhub/usr \
|
||||
RELEASE=YES SILENT=YES
|
||||
|
||||
build: build-stamp
|
||||
build-stamp:
|
||||
dh_testdir
|
||||
make $(makeopts)
|
||||
touch build-stamp
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
rm -f build-stamp
|
||||
make clean
|
||||
dh_clean
|
||||
|
||||
binary-indep: build
|
||||
|
||||
binary-arch: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_clean -k
|
||||
dh_installdirs
|
||||
$(MAKE) install $(makeopts)
|
||||
dh_installdocs
|
||||
dh_installinit
|
||||
dh_installlogrotate
|
||||
dh_installman -A
|
||||
dh_installchangelogs ChangeLog
|
||||
dh_strip
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_shlibdeps
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary
|
||||
|
||||
Vendored
-4
@@ -1,4 +0,0 @@
|
||||
# uhub - high performance adc hub.
|
||||
|
||||
UHUB_ENABLE=0
|
||||
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
etc/default
|
||||
etc/init.d
|
||||
etc/logrotate.d
|
||||
etc/uhub
|
||||
usr/bin
|
||||
var/log/uhub
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
AUTHORS
|
||||
README
|
||||
BUGS
|
||||
TODO
|
||||
doc/getstarted.txt
|
||||
Vendored
-92
@@ -1,92 +0,0 @@
|
||||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: uhub
|
||||
# Required-Start: $remote_fs $network
|
||||
# Required-Stop: $remote_fs $network
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: uhub - High performance ADC p2p hub.
|
||||
### END INIT INFO
|
||||
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
|
||||
NAME=uhub
|
||||
DESC="ADC hub"
|
||||
DAEMON=/usr/bin/uhub
|
||||
PIDFILE=/var/run/uhub/uhub.pid
|
||||
LOGFILE=/var/log/uhub/uhub.log
|
||||
SCRIPTNAME=/etc/init.d/uhub
|
||||
|
||||
DEFAULTFILE=/etc/default/uhub
|
||||
[ -r $DEFAULTFILE ] && . $DEFAULTFILE
|
||||
|
||||
DAEMON_ENABLE="${UHUB_ENABLE}"
|
||||
DAEMON_OPTS="-l ${LOGFILE} -f -p ${PIDFILE}"
|
||||
|
||||
test -x $DAEMON || exit 0
|
||||
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
ulimit -n 65536
|
||||
mkdir -p /var/run/uhub/
|
||||
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
if [ "$DAEMON_ENABLE" != "true" ]; then
|
||||
log_daemon_msg "Disabled $DESC" $NAME
|
||||
log_end_msg 0
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log_daemon_msg "Starting $DESC" $NAME
|
||||
if ! start-stop-daemon --start --quiet --oknodo \
|
||||
--pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS
|
||||
then
|
||||
log_end_msg 1
|
||||
else
|
||||
log_end_msg 0
|
||||
fi
|
||||
;;
|
||||
|
||||
stop)
|
||||
log_daemon_msg "Stopping $DESC" $NAME
|
||||
if start-stop-daemon --quiet --stop --oknodo --retry 30 --oknodo \
|
||||
--pidfile $PIDFILE --exec $DAEMON
|
||||
then
|
||||
rm -f $PIDFILE
|
||||
log_end_msg 0
|
||||
else
|
||||
log_end_msg 1
|
||||
fi
|
||||
;;
|
||||
|
||||
reload)
|
||||
log_daemon_msg "Reloading $DESC configuration" $NAME
|
||||
if start-stop-daemon --stop --signal 2 --oknodo --retry 30 --oknodo \
|
||||
--quiet --pidfile $PIDFILE --exec $DAEMON
|
||||
then
|
||||
if start-stop-daemon --start --quiet \
|
||||
--pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS ; then
|
||||
log_end_msg 0
|
||||
else
|
||||
log_end_msg 1
|
||||
fi
|
||||
else
|
||||
log_end_msg 1
|
||||
fi
|
||||
;;
|
||||
|
||||
restart|force-reload)
|
||||
$0 stop
|
||||
$0 start
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
Vendored
-9
@@ -1,9 +0,0 @@
|
||||
/var/log/uhub/*.log
|
||||
{
|
||||
compress
|
||||
size 10M
|
||||
rotate 10
|
||||
missingok
|
||||
notifempty
|
||||
}
|
||||
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
doc/uhub.1
|
||||
Vendored
-27
@@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
chmod 0750 /var/log/uhub
|
||||
|
||||
if [ -x /etc/init.d/uhub ]; then
|
||||
update-rc.d uhub defaults >/dev/null
|
||||
|
||||
if [ -x /usr/sbin/invoke-rc.d ]; then
|
||||
invoke-rc.d uhub restart
|
||||
else
|
||||
/etc/init.d/uhub restart
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst: error: unknown argument: $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
if [ "$1" = purge ]; then
|
||||
update-rc.d uhub remove >/dev/null
|
||||
fi
|
||||
|
||||
Vendored
-10
@@ -1,10 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
if [ "$1" = remove ]; then
|
||||
if command -v invoke-rc.d >/dev/null 2>&1; then
|
||||
invoke-rc.d uhub stop || true
|
||||
else
|
||||
/etc/init.d/uhub stop
|
||||
fi
|
||||
fi
|
||||
|
||||
-256
@@ -1,256 +0,0 @@
|
||||
# Doxyfile 1.5.5-KDevelop
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = uHub
|
||||
PROJECT_NUMBER = 0.2.0-alpha
|
||||
OUTPUT_DIRECTORY =
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF = "The $name class" \
|
||||
"The $name widget" \
|
||||
"The $name file" \
|
||||
is \
|
||||
provides \
|
||||
specifies \
|
||||
contains \
|
||||
represents \
|
||||
a \
|
||||
an \
|
||||
the
|
||||
ALWAYS_DETAILED_SEC = YES
|
||||
INLINE_INHERITED_MEMB = YES
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = YES
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
QT_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
DETAILS_AT_TOP = YES
|
||||
INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 8
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
OPTIMIZE_FOR_FORTRAN = NO
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
BUILTIN_STL_SUPPORT = NO
|
||||
CPP_CLI_SUPPORT = NO
|
||||
SIP_SUPPORT = NO
|
||||
IDL_PROPERTY_SUPPORT = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
SUBGROUPING = YES
|
||||
TYPEDEF_HIDES_STRUCT = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_METHODS = YES
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_GROUP_NAMES = NO
|
||||
SORT_BY_SCOPE_NAME = YES
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = NO
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = .
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS = *.c \
|
||||
*.h
|
||||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS = autotest/*
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = YES
|
||||
INLINE_SOURCES = YES
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
REFERENCES_LINK_SOURCE = YES
|
||||
USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = YES
|
||||
GENERATE_DOCSET = NO
|
||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = YES
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NONE
|
||||
TREEVIEW_WIDTH = 250
|
||||
FORMULA_FONTSIZE = 10
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE = uhub.tag
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
MSCGEN_PATH =
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = YES
|
||||
DOT_FONTNAME = FreeSans
|
||||
DOT_FONTPATH =
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
CALLER_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = NO
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
MAX_DOT_GRAPH_DEPTH = 1000
|
||||
DOT_TRANSPARENT = YES
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
||||
@@ -1,91 +0,0 @@
|
||||
= Architecture of uHub =
|
||||
|
||||
uHub is single threaded and handles network and timer events using the
|
||||
libevent library.
|
||||
For each state there is a read event (and sometimes a write event) and timeout
|
||||
event in case an expected read (or write) event does not occur.
|
||||
|
||||
|
||||
== Protocol overview ==
|
||||
uHub use "speak" the ADC protocol, which works in short as follows:
|
||||
(C = client, S = server aka uHub).
|
||||
|
||||
C: HSUP ADBASE
|
||||
Client connects to hub and supplies a list of supported features to the hub.
|
||||
|
||||
S: ISUP ADBASE { }
|
||||
Server responds with a list of supported features.
|
||||
|
||||
S: ISID xxxx
|
||||
Server assigns a session-ID to the client (4 bytes, BASE32 encoded).
|
||||
|
||||
C: BINF xxxx (...)
|
||||
Client sends information about itself, such as nick name, etc.
|
||||
The hub will relay this information to all users, including the client.
|
||||
|
||||
S: BINF xxx1 NInick1 (...)
|
||||
S: BINF xxx2 NInick2
|
||||
S: (...)
|
||||
S: BINF xxxx (client's own nick)
|
||||
Client gets list of other clients, which ends with the client's own user info.
|
||||
At this point the client is successfully logged into the hub.
|
||||
|
||||
|
||||
== The hub architecture ==
|
||||
|
||||
Accepting new users
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--------------------- -----------------
|
||||
| Accept connection | <---------- | libevent loop |
|
||||
--------------------- -----------------
|
||||
|
|
||||
V
|
||||
--------------------- ------------
|
||||
| Setup login timer | --+----> | Timeout? | <----+
|
||||
--------------------- | ------------ |
|
||||
| | | |
|
||||
V | V |
|
||||
--------------------- | --------------- |
|
||||
| Receive 'HSUP' | --+----> | DISCONNECT! | |
|
||||
--------------------- --------------- |
|
||||
| ^ |
|
||||
V | |
|
||||
--------------------- | |
|
||||
| Send 'ISUP', and | | |
|
||||
| assign Session ID | | |
|
||||
--------------------- | |
|
||||
| | |
|
||||
V | |
|
||||
--------------------- | |
|
||||
| Receive 'BINF' |-----------------+------------
|
||||
+--| Validate message | ^
|
||||
| --------------------- |
|
||||
| | |
|
||||
| V |
|
||||
| --------------------- ---------------------
|
||||
| | Send password | ------> | Reveive and check |
|
||||
| | request, if needed| | password. |
|
||||
| --------------------- ---------------------
|
||||
| |
|
||||
| |
|
||||
| ------------------------ |
|
||||
+->| Send welcome message |<--------------+
|
||||
------------------------
|
||||
|
|
||||
V
|
||||
------------------------
|
||||
| Send user list to |
|
||||
| newly accepted user. |
|
||||
------------------------
|
||||
|
|
||||
V
|
||||
------------------------
|
||||
| User is logged in. |
|
||||
| Announce to all. |
|
||||
------------------------
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
How to compile:
|
||||
---------------
|
||||
|
||||
See the official compiling howto: http://www.extatic.org/uhub/compile.html
|
||||
|
||||
Prerequisites
|
||||
|
||||
Before you try to compile µHub, please make sure the following prerequisites are met.
|
||||
* GNU make
|
||||
* gcc > 3.0 (or MinGW on Windows)
|
||||
* Perl 5
|
||||
* openssl > 0.9.8 (or use "make USE_SSL=NO")
|
||||
* sqlite > 3.x
|
||||
|
||||
or read http://www.uhub.org/compile.php for more info.
|
||||
|
||||
|
||||
Linux, Mac OSX, FreeBSD, NetBSD and OpenBSD
|
||||
-------------------------------------------
|
||||
Simply, run:
|
||||
% make
|
||||
|
||||
If you have an old gcc compiler, try disabling pre-compiled headers like this:
|
||||
gmake USE_PCH=NO
|
||||
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
ADC protocol extensions supported:
|
||||
|
||||
STATUS: **** Not yet implemented.
|
||||
|
||||
the 'AUT0' extension (network connection auto detection extension).
|
||||
Rationale: Detect if client is capable of initiating active connections.
|
||||
|
||||
After logging in:
|
||||
|
||||
Client -> 'HCHK 12345 ABCD'.
|
||||
|
||||
Server sends a UDP packet containing token to the client's IP address at the given port as shown in the INF message.
|
||||
|
||||
Server -> 'ICHK ABCD'
|
||||
|
||||
The server should send it from a UDP socket bound to the same port as the TCP server, which means the server will
|
||||
have to listen to both TCP and UDP.
|
||||
|
||||
If client receives the packet, it knows it can receive UDP connections, and will advertise it in the INF message as
|
||||
a supported feature.
|
||||
|
||||
If the client does not receive any UDP packets within a few seconds, it MAY try to reconfigure the router using
|
||||
UPnP/ZeroConf, and issue a HCHK command to the server again.
|
||||
|
||||
If the client still doesn't receive any UDP packets, hole punching can be tried.
|
||||
The server will send a UDP packet to the hub (using the port of the TCP server), and reissue the HCHK command.
|
||||
The UDP packet SHOULD be echoed by the hub.
|
||||
This UDP packet should contain simply 'HECH {cid} {token}' (Hub echo).
|
||||
|
||||
The hub should send a packet containing the token back:
|
||||
'IECH {token} {host:port}', aswell as the same message via TCP.
|
||||
|
||||
If the client receives the message via UDP, it should now be able to determine the type of NAT.
|
||||
If the client receives the message via TCP only it knows it has a firewall blocking icomming communication.
|
||||
If the client does not receive the message, it should assume a firewall is blocking all UDP communication,
|
||||
and resume in passive mode.
|
||||
|
||||
Requirements:
|
||||
'AUT0' in the extensions message (SUP) for client and hub.
|
||||
Server will also listen to UDP messages on the same port as the TCP port.
|
||||
|
||||
The server MUST now respond to the 'HCHK' command via TCP
|
||||
The server MUST now respond to the 'HECH' command via UDP.
|
||||
|
||||
The client will always initiate communication.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Syntax: HCHK {port} {token}
|
||||
- port is a 16-bit port number where the client is listening for packets.
|
||||
- token is 4 bytes base32 encoded data specified by the client.
|
||||
|
||||
Example:
|
||||
Client: 'HCHK 1511 BACD' (tcp)
|
||||
Server: 'ICHK BACD' (udp)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Syntax: HECH {cid} {token}
|
||||
- cid is the client ID.
|
||||
- token is 4 bytes base32 encoded data specified by the client.
|
||||
|
||||
Example:
|
||||
Client: 'HECH 3NGFVJUDBRHX2CYRJGQ5HACRDM5CTNLGZ36M64I BACD' (udp)
|
||||
Server: 'IECH BACD 192.168.0.1:1512' (udp)
|
||||
Server: 'IECH BACD 192.168.0.1:1512' (tcp)
|
||||
|
||||
Security considerations:
|
||||
The hub must verify that IP address where the HECH command originated from
|
||||
matches the IP address where the user with the given CID is connected from.
|
||||
If the CID and IP does not match, or the CID is not used the hub MUST ignore
|
||||
the request.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
Getting started guide
|
||||
---------------------
|
||||
|
||||
(This document is maintained at http://www.extatic.org/uhub/getstarted.html )
|
||||
|
||||
Unpack your binaries
|
||||
|
||||
Example:
|
||||
% tar xzf uhub-0.2.6-linux-i386.tar.gz
|
||||
% cd uhub-0.2.6
|
||||
|
||||
Copy the binary to /usr/local/bin
|
||||
|
||||
% sudo cp uhub /usr/local/bin
|
||||
|
||||
Create configuration files.
|
||||
If no configuration files are created, uhub will use the default parameters, so you can skip this step if you are in a hurry to see it run.
|
||||
|
||||
As root, or use sudo.
|
||||
% mkdir /etc/uhub
|
||||
% cp doc/uhub.conf /etc/uhub
|
||||
% cp doc/users.conf /etc/uhub
|
||||
% echo "welcome to uhub" > /etc/uhub/motd.txt
|
||||
|
||||
Start the hub in the foreground for the first time. Shut it down, by pressing CTRL+C.
|
||||
|
||||
% uhub
|
||||
Thu, 05 Feb 2009 00:48:04 +0000 INFO: Starting server, listening on :::1511...
|
||||
|
||||
Connect to the hub using an ADC client, use the address adc://localhost:1511, or replace localhost with the correct hostname or IP address.
|
||||
NOTE: It is important to use the "adc://" prefix, and the port number when using DC++ and other ADC clients.
|
||||
|
||||
If you modify the configuration files in /etc/uhub you will have to notify uhub by sending a HUP signal.
|
||||
|
||||
% kill -HUP <pid of uhub>
|
||||
Or, for the lazy people
|
||||
% killall -HUP uhub
|
||||
|
||||
In order to run uhub as a daemon, start it with the -f switch which will make it fork into the background.
|
||||
In addition, use the -l to specify a log file instead of stdout. One can also specify a specific user and/or group,
|
||||
if one wishes to run uhub as a specific user using the -u and -g switches.
|
||||
|
||||
Example:
|
||||
% uhub -f -l mylog.txt -u nobody -g nogroup
|
||||
|
||||
|
||||
If you are planning to more than 1024 users on hub, you must increase the max number of file descriptors allowed.
|
||||
This limit needs to be higher than the configured max_users in uhub.conf.
|
||||
|
||||
In linux can add the following lines to /etc/security/limits.conf (allows for ~4000 users)
|
||||
* soft nofile 4096
|
||||
* hard nofile 4096
|
||||
|
||||
Or, you can use (as root):
|
||||
% ulimit -n 4096
|
||||
|
||||
Your mileage may vary -- Good luck!
|
||||
@@ -1,112 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# chkconfig: - 91 35
|
||||
# description: Starts and stops the Uhub ( http://www.uhub.org ) daemons on RHEL\CentOS \
|
||||
# used to provide p2p network services.
|
||||
#
|
||||
# pidfile: /var/run/uhub.pid
|
||||
# config: /etc/uhub/uhub.conf
|
||||
|
||||
|
||||
|
||||
# Source function library.
|
||||
if [ -f /etc/init.d/functions ] ; then
|
||||
. /etc/init.d/functions
|
||||
elif [ -f /etc/rc.d/init.d/functions ] ; then
|
||||
. /etc/rc.d/init.d/functions
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Avoid using root's TMPDIR
|
||||
unset TMPDIR
|
||||
|
||||
# Source networking configuration.
|
||||
. /etc/sysconfig/network
|
||||
|
||||
if [ -f /etc/sysconfig/uhub ]; then
|
||||
. /etc/sysconfig/uhub
|
||||
fi
|
||||
|
||||
# Check that networking is up.
|
||||
[ ${NETWORKING} = "no" ] && exit 1
|
||||
|
||||
# Check that uhub.conf exists.
|
||||
[ -f /etc/uhub/uhub.conf ] || exit 6
|
||||
|
||||
RETVAL=0
|
||||
|
||||
|
||||
start() {
|
||||
KIND="Uhub"
|
||||
echo -n $"Starting $KIND services: "
|
||||
daemon uhub $UHUBOPTIONS
|
||||
RETVAL=$?
|
||||
echo ""
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
stop() {
|
||||
KIND="Uhub"
|
||||
echo -n $"Shutting down $KIND services: "
|
||||
killproc uhub
|
||||
RETVAL=$?
|
||||
echo ""
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
reload() {
|
||||
echo -n $"Reloading uhub.conf / user.conf file: "
|
||||
killproc uhub -HUP
|
||||
RETVAL=$?
|
||||
echo ""
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
relog() {
|
||||
echo -n $"Reopen main log file: "
|
||||
killproc uhub -SIGHUP
|
||||
RETVAL=$?
|
||||
echo ""
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
rhstatus() {
|
||||
status uhub
|
||||
RETVAL=$?
|
||||
if [ $RETVAL -ne 0 ] ; then
|
||||
return $RETVAL
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
restart)
|
||||
restart
|
||||
;;
|
||||
reload)
|
||||
reload
|
||||
;;
|
||||
relog)
|
||||
relog
|
||||
;;
|
||||
status)
|
||||
rhstatus
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|restart|reload|relog|status}"
|
||||
exit 2
|
||||
esac
|
||||
|
||||
exit $?
|
||||
@@ -1,14 +0,0 @@
|
||||
# Log rotate for Uhub
|
||||
# see man logrotate
|
||||
#
|
||||
#
|
||||
/var/log/uhub.log {
|
||||
compress
|
||||
size 10M
|
||||
rotate 10
|
||||
missingok
|
||||
notifempty
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# Options to UHUB
|
||||
# -v Verbose mode. Add more -v's for higher verbosity.
|
||||
# -q Quiet mode - no output
|
||||
# -f Fork to background
|
||||
# -l <file> Log messages to given file (default: stderr)
|
||||
# -L Log messages to syslog
|
||||
# -c <file> Specify configuration file (default: /etc/uhub/uhub.conf)
|
||||
# -S Show configuration parameters, but ignore defaults
|
||||
# -u <user> Run as given user
|
||||
# -g <group> Run with given group permissions
|
||||
# -p <file> Store pid in file (process id)
|
||||
UHUBOPTIONS=" -u uhub -f -p /var/run/uhub.pid -l /var/log/uhub.log"
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
# ATTENTION!
|
||||
# Plugins are invoked in the order of listing in the plugin config file.
|
||||
|
||||
|
||||
# Sqlite based user authentication.
|
||||
#
|
||||
# This plugin provides a Sqlite based authentication database for
|
||||
# registered users.
|
||||
# Use the uhub-passwd utility to create the database and add/remove users.
|
||||
#
|
||||
# Parameters:
|
||||
# file: path/filename for database.
|
||||
#
|
||||
plugin /var/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db"
|
||||
|
||||
|
||||
# Log file writer
|
||||
#
|
||||
# Parameters:
|
||||
# file: path/filename for log file.
|
||||
# syslog: if true then syslog is used instead of writing to a file (Unix only)
|
||||
plugin /var/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
||||
|
||||
# A simple example plugin
|
||||
# plugin /var/lib/uhub/mod_example.so
|
||||
# A plugin sending a welcome message.
|
||||
#
|
||||
# This plugin provides the following commands:
|
||||
# !motd - Message of the day
|
||||
# !rules - Show hub rules.
|
||||
#
|
||||
# Parameters:
|
||||
# motd: path/filename for the welcome message (message of the day)
|
||||
# rules: path/filenam for the rules file
|
||||
#
|
||||
# NOTE: The files MUST exist, however if you do not wish to provide one then these parameters can be omitted.
|
||||
#
|
||||
# The motd/rules files can do the following substitutions:
|
||||
# %n - Nickname of the user who entered the hub or issued the command.
|
||||
# %a - IP address of the user
|
||||
# %c - The credentials of the user (guest, user, op, super, admin).
|
||||
# %% - Becomes '%'
|
||||
# %H - Hour 24-hour format (00-23) (Hub local time)
|
||||
# %I - Hour 12-hour format (01-12) (Hub local time)
|
||||
# %P - 'AM' or 'PM'
|
||||
# %p - 'am' or 'pm'
|
||||
# %M - Minutes (00-59) (Hub local time)
|
||||
# %S - Seconds (00-60) (Hub local time)
|
||||
plugin /var/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rules.txt"
|
||||
|
||||
# Load the chat history plugin.
|
||||
#
|
||||
# This plugin provides chat history when users are connecting, or
|
||||
# when users invoke the !history command.
|
||||
# The history command can optionally take a parameter to indicate how many lines of history is requested.
|
||||
#
|
||||
# Parameters:
|
||||
# history_max: the maximum number of messages to keep in history
|
||||
# history_default: when !history is provided without arguments, then this default number of messages are returned.
|
||||
# history_connect: the number of chat history messages to send when users connect (0 = do not send any history)
|
||||
plugin /var/lib/uhub/mod_chat_history.so "history_max=200 history_default=10 history_connect=5"
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
1. rule #1
|
||||
2. rule #2
|
||||
3. rule #3
|
||||
......
|
||||
34. Rule #34
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
.TH UHUB 1 "March 2009"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.SH NAME
|
||||
uhub \- a high performance ADC peer-to-peer hub
|
||||
.SH SYNOPSIS
|
||||
.B uhub
|
||||
.RI [ options ]
|
||||
.SH DESCRIPTION
|
||||
uHub is a high performance peer-to-peer hub for the ADC network.
|
||||
Its low memory footprint allows it to handle several thousand users
|
||||
on high-end servers, or a small private hub on embedded hardware.
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
.BI \^\-v
|
||||
Verbose mode, add more \-v's for higher verbosity.
|
||||
.TP
|
||||
.BI \^\-q
|
||||
Quiet mode, if quiet mode is enabled no output or logs are made.
|
||||
.TP
|
||||
.BI \^\-f
|
||||
Fork uhub to background in order to run it as a daemon.
|
||||
.TP
|
||||
.BI \^\-l " logfile"
|
||||
Log messages to the given logfile (default: stderr)
|
||||
.TP
|
||||
.BI \^\-L
|
||||
Log messages to syslog.
|
||||
.TP
|
||||
.BI \^\-c " config"
|
||||
Specify configuration file (default: /etc/uhub/uhub.conf)
|
||||
.TP
|
||||
.BI \^\-C
|
||||
Check configuration files and return. Will print either \"OK\" or \"ERROR\".
|
||||
.TP
|
||||
.BI \^\-s
|
||||
Show all configuration parameters. In a format that is compatible with
|
||||
the configuration files.
|
||||
.TP
|
||||
.BI \^\-S
|
||||
Show all non-default configuration parameters.
|
||||
.TP
|
||||
.BI \^\-h
|
||||
Show the help message.
|
||||
.TP
|
||||
.BI \^\-u " user"
|
||||
Drop privileges and run as the given user.
|
||||
.TP
|
||||
.BI \^\-g " group"
|
||||
Drop privileges and run with the given group permissions.
|
||||
.TP
|
||||
.BI \^\-V
|
||||
Show the version number
|
||||
.SH EXAMPLES
|
||||
To run uhub as a daemon, and log to a file:
|
||||
.TP
|
||||
.B uhub " -f -l /var/log/uhub/uhub.log"
|
||||
.SH AUTHOR
|
||||
This program was written by Jan Vidar Krey <janvidar@extatic.org>
|
||||
.SH "BUG REPORTS"
|
||||
If you find a bug in uhub please report it to
|
||||
.B http://bugs.extatic.org/
|
||||
-135
@@ -1,135 +0,0 @@
|
||||
# uhub.conf - A example configuration file.
|
||||
# You should normally place this file in /etc/uhub/uhub.conf
|
||||
# And change the file_acl and file_motd below.
|
||||
#
|
||||
# This file is read only to the uhub deamon, and if you
|
||||
# make changes to it while uhub is running you can send a
|
||||
# HUP signal to it ( $ killall -HUP uhub ), to reparse configuration (only on UNIX).
|
||||
# All configuration directives: http://www.uhub.org/config.php
|
||||
|
||||
# Bind to this port and address
|
||||
# server_bind_addr=any means listen to "::" if IPv6 is supported
|
||||
# by the host OS, otherwise 0.0.0.0.
|
||||
server_port=1511
|
||||
server_bind_addr=any
|
||||
|
||||
# Alternative server ports
|
||||
# server_alt_ports = 1512, 1513
|
||||
|
||||
# The maximum amount of users allowed on the hub.
|
||||
max_users=500
|
||||
|
||||
# If 1, will show a "Powered by uHub/{VERSION}".
|
||||
show_banner=1
|
||||
|
||||
# If enabled then operating system and cpu architecture is part of the banner.
|
||||
show_banner_sys_info=1
|
||||
|
||||
# Allow only registered users on the hub if set to 1.
|
||||
registered_users_only=0
|
||||
|
||||
# A server name and description.
|
||||
hub_name=my hub
|
||||
hub_description=Powered by uHub
|
||||
|
||||
# Set this to 0, and the hub will disconnect everyone
|
||||
hub_enabled=1
|
||||
|
||||
# Access control list (user database)
|
||||
file_acl=/etc/uhub/users.conf
|
||||
|
||||
# This file can contain a message of the day. A welcome
|
||||
# message send to any client when connecting.
|
||||
# If the file does not exist, is empty, or cannot be opened
|
||||
# the motd will not be sent to the clients.
|
||||
# Normally this message is sent to clients when connecting.
|
||||
file_motd=/etc/uhub/motd.txt
|
||||
|
||||
# This file can contain a rules of the hub.
|
||||
# Normally this message is sent to clients when write in chat !rules
|
||||
file_rules=/etc/uhub/rules.txt
|
||||
|
||||
# This file can contain a conf for plugin subsystem
|
||||
file_plugins = /etc/uhub/plugins.conf
|
||||
|
||||
# Slots/share/hubs limits
|
||||
limit_max_hubs_user = 0
|
||||
limit_max_hubs_reg = 0
|
||||
limit_max_hubs_op = 0
|
||||
limit_max_hubs = 0
|
||||
limit_min_hubs_user = 0
|
||||
limit_min_hubs_reg = 0
|
||||
limit_min_hubs_op = 0
|
||||
limit_min_share = 0
|
||||
# Example:
|
||||
# To require users to share at least 1 GB in order to enter the hub:
|
||||
# limit_min_share = 1024
|
||||
limit_max_share = 0
|
||||
limit_min_slots = 0
|
||||
limit_max_slots = 0
|
||||
|
||||
# Flood control support:
|
||||
# set the interval to 5 seconds
|
||||
flood_ctl_interval = 5
|
||||
|
||||
# Then the maximum chat, connect, search, updates etc will be measured over 5 seconds.
|
||||
# So, 3 chat messages per 5 seconds allowed.
|
||||
flood_ctl_chat=3
|
||||
flood_ctl_connect=20
|
||||
flood_ctl_search=1
|
||||
flood_ctl_update=2
|
||||
flood_ctl_extras=5
|
||||
|
||||
# chat control
|
||||
# if chat_is_privileged=yes only registered users may write in main chat
|
||||
chat_is_privileged = no
|
||||
|
||||
|
||||
# if obsolete_clients=1 allows old clients to enter , 0 gives an error message (msg_proto_obsolete_adc0) if they try connect
|
||||
# defaults obsolete_clients=1
|
||||
obsolete_clients=1
|
||||
|
||||
|
||||
# Configure status message as sent to clients in different circumstances.
|
||||
msg_hub_full = Hub is full
|
||||
msg_hub_disabled = Hub is disabled
|
||||
msg_hub_registered_users_only = Hub is for registered users only
|
||||
msg_inf_error_nick_missing = No nickname given
|
||||
msg_inf_error_nick_multiple = Multiple nicknames given
|
||||
msg_inf_error_nick_invalid = Nickname is invalid
|
||||
msg_inf_error_nick_long = Nickname too long
|
||||
msg_inf_error_nick_short = Nickname too short
|
||||
msg_inf_error_nick_spaces = Nickname cannot start with spaces
|
||||
msg_inf_error_nick_bad_chars = Nickname contains invalid characters
|
||||
msg_inf_error_nick_not_utf8 = Nickname is not valid utf8
|
||||
msg_inf_error_nick_taken = Nickname is already in use
|
||||
msg_inf_error_nick_restricted = Nickname cannot be used on this hub
|
||||
msg_inf_error_cid_invalid = CID is not valid
|
||||
msg_inf_error_cid_missing = CID is not specified
|
||||
msg_inf_error_cid_taken = CID is taken
|
||||
msg_inf_error_pid_missing = PID is not specified
|
||||
msg_inf_error_pid_invalid = PID is invalid
|
||||
msg_ban_permanently = Banned permanently
|
||||
msg_ban_temporarily = Banned temporarily
|
||||
msg_auth_invalid_password = Password is wrong
|
||||
msg_auth_user_not_found = User not found in password database
|
||||
msg_user_share_size_low = User is not sharing enough
|
||||
msg_user_share_size_high = User is sharing too much
|
||||
msg_user_slots_low = User have too few upload slots
|
||||
msg_user_slots_high = User have too many upload slots
|
||||
msg_user_hub_limit_low = User is on too few hubs
|
||||
msg_user_hub_limit_high = User is on too many hubs
|
||||
msg_error_no_memory = No memory
|
||||
msg_user_flood_chat = Chat flood detected, messages are dropped.
|
||||
msg_user_flood_connect = Connect flood detected, connection refused.
|
||||
msg_user_flood_search = Search flood detected, search is stopped.
|
||||
msg_user_flood_update = Update flood detected.
|
||||
msg_user_flood_extras = Flood detected.
|
||||
|
||||
# If a client that supports ADC but not a compatible hash algorithm (tiger),
|
||||
# then the hub cannot accept the client:
|
||||
msg_proto_no_common_hash = No common hash algorithm.
|
||||
|
||||
# Message to be shown to old clients using an older version of ADC than ADC/1.0
|
||||
msg_proto_obsolete_adc0 = Client is using an obsolete ADC protocol version.
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/**
|
||||
* Overview of uHub
|
||||
*/
|
||||
digraph G
|
||||
{
|
||||
|
||||
"main()" -> "event_dispatch()"
|
||||
|
||||
"event_dispatch()" -> "net_on_accept()"
|
||||
"event_dispatch()" -> "net_on_read()"
|
||||
"event_dispatch()" -> "net_on_write()"
|
||||
"event_dispatch()" -> "event_queue_process()"
|
||||
|
||||
/* net events */
|
||||
"net_on_write()" -> "net_send()"
|
||||
"net_on_write()" -> "user_disconnect()"
|
||||
"net_on_accept()" -> "user_create()"
|
||||
"net_on_read()" -> "net_recv()"
|
||||
"net_on_read()" -> "user_disconnect()"
|
||||
|
||||
"net_recv()" -> "hub_handle_message()"
|
||||
|
||||
/* adc message handling */
|
||||
"hub_handle_message()" -> "hub_handle_password()"
|
||||
"hub_handle_message()" -> "hub_handle_support()"
|
||||
|
||||
"hub_handle_password()" -> "user_disconnect()"
|
||||
"hub_handle_support()" -> "user_disconnect()"
|
||||
"hub_handle_password()" -> "route_to_user()"
|
||||
"hub_handle_support()" -> "route_to_user()"
|
||||
|
||||
"hub_handle_message()" -> "hub_handle_info()"
|
||||
"hub_handle_message()" -> "route_message()"
|
||||
"hub_handle_info()" -> "route_to_user()"
|
||||
"hub_handle_info()" -> "route_to_all()"
|
||||
|
||||
/* message routing, depending on message type */
|
||||
"route_message()" -> "route_to_user()"
|
||||
"route_message()" -> "route_to_all()" -> "route_to_user()"
|
||||
"route_message()" -> "route_to_subscribers()" -> "route_to_user()"
|
||||
|
||||
"route_to_user()" -> "net_send()"
|
||||
"route_to_user()" -> "queue_command()"
|
||||
"route_to_user()" -> "user_disconnect()"
|
||||
|
||||
|
||||
/* Message dispatcher */
|
||||
"event_queue_process()" -> "hub_event_dispatcher()"
|
||||
"hub_event_dispatcher()" -> "EVENT_USER_JOIN"
|
||||
"hub_event_dispatcher()" -> "EVENT_USER_QUIT"
|
||||
"EVENT_USER_QUIT" -> "route_to_all()"
|
||||
"EVENT_USER_QUIT" -> "user_destroy()"
|
||||
"EVENT_USER_JOIN" -> "route_to_all()"
|
||||
|
||||
/* user_disconnect() -- critical part */
|
||||
"user_disconnect()" -> "user_set_state(state_cleanup)" -> "post: EVENT_USER_QUIT"
|
||||
"user_disconnect()" -> "user_destroy()"
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
# Copyright 1999-2010 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: $
|
||||
inherit eutils
|
||||
|
||||
if [ "$PV" != "9999" ]; then
|
||||
SRC_URI="http://www.extatic.org/downloads/uhub/${P}-src.tar.bz2"
|
||||
KEYWORDS="~amd64 ~x86"
|
||||
else
|
||||
inherit git
|
||||
SRC_URI=""
|
||||
EGIT_REPO_URI="git://github.com/janvidar/uhub.git"
|
||||
KEYWORDS=""
|
||||
fi
|
||||
|
||||
EAPI="2"
|
||||
|
||||
DESCRIPTION="High performance ADC hub"
|
||||
HOMEPAGE="http://www.uhub.org/"
|
||||
|
||||
LICENSE="GPL-3"
|
||||
SLOT="0"
|
||||
IUSE="+ssl"
|
||||
|
||||
DEPEND="=dev-lang/perl-5*
|
||||
ssl? ( >=dev-libs/openssl-0.9.8 )
|
||||
"
|
||||
RDEPEND="${DEPEND}"
|
||||
src_compile() {
|
||||
$opts=""
|
||||
use ssl && opts="USE_SSL=YES $opts"
|
||||
emake $opts
|
||||
}
|
||||
src_install() {
|
||||
dodir /usr/bin
|
||||
dodir /etc/uhub
|
||||
emake DESTDIR="${D}" UHUB_PREFIX="${D}/usr" install || die "install failed"
|
||||
newinitd doc/uhub.gentoo.rc uhub || newinitd ${FILESDIR}/uhub.rc uhub
|
||||
}
|
||||
pkg_postinst() {
|
||||
enewuser uhub
|
||||
}
|
||||
-102
@@ -1,102 +0,0 @@
|
||||
Summary: High performance ADC p2p hub.
|
||||
Name: uhub
|
||||
Version: 0.4.0
|
||||
Release: 2
|
||||
License: GPLv3
|
||||
Group: Networking/File transfer
|
||||
Source: uhub-%{version}.tar.gz
|
||||
URL: http://www.uhub.org
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||
|
||||
BuildRequires: sqlite-devel
|
||||
BuildRequires: openssl-devel
|
||||
|
||||
%description
|
||||
uhub is a high performance peer-to-peer hub for the ADC network.
|
||||
Its low memory footprint allows it to handle several thousand users on
|
||||
high-end servers, or a small private hub on embedded hardware.
|
||||
|
||||
Key features:
|
||||
- High performance and low memory usage
|
||||
- IPv4 and IPv6 support
|
||||
- Experimental SSL support (optional)
|
||||
- Advanced access control support
|
||||
- Easy configuration
|
||||
- plugin support
|
||||
- mod_welcome - MOTD\RULES messages
|
||||
- mod_auth_sipmle - auth with sqlite DB
|
||||
- mod_logging - log hub activity
|
||||
|
||||
%prep
|
||||
%setup -q -n %{name}-%{version}
|
||||
|
||||
%build
|
||||
echo RPM_BUILD_ROOT = $RPM_BUILD_ROOT
|
||||
make
|
||||
|
||||
%install
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/bin
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/uhub
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/share/man/man1
|
||||
mkdir -p $RPM_BUILD_ROOT/var/lib/uhub
|
||||
|
||||
install uhub $RPM_BUILD_ROOT/usr/bin/
|
||||
install uhub-passwd $RPM_BUILD_ROOT/usr/bin/
|
||||
> doc/motd.txt
|
||||
install -m644 doc/uhub.conf doc/users.conf doc/rules.txt doc/motd.txt doc/plugins.conf doc/users.db $RPM_BUILD_ROOT/etc/uhub
|
||||
install doc/init.d.RedHat/etc/init.d/uhub $RPM_BUILD_ROOT/etc/init.d
|
||||
install -m644 doc/init.d.RedHat/etc/sysconfig/uhub $RPM_BUILD_ROOT/etc/sysconfig/
|
||||
install -m644 doc/init.d.RedHat/etc/logrotate.d/uhub $RPM_BUILD_ROOT/etc/logrotate.d/
|
||||
/bin/gzip -9c doc/uhub.1 > doc/uhub.1.gz &&
|
||||
install -m644 doc/uhub.1.gz $RPM_BUILD_ROOT/usr/share/man/man1
|
||||
install -m644 mod_*.so $RPM_BUILD_ROOT/var/lib/uhub
|
||||
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc AUTHORS BUGS COPYING ChangeLog README TODO doc/Doxyfile doc/architecture.txt doc/compile.txt doc/extensions.txt doc/getstarted.txt doc/uhub.dot
|
||||
%config(noreplace) /etc/uhub/uhub.conf
|
||||
#%{_sysconfdir}/uhub/uhub.conf
|
||||
%config(noreplace) %{_sysconfdir}/uhub/users.conf
|
||||
%config(noreplace) %{_sysconfdir}/uhub/motd.txt
|
||||
%config(noreplace) %{_sysconfdir}/uhub/rules.txt
|
||||
%config(noreplace) %{_sysconfdir}/uhub/plugins.conf
|
||||
%config(noreplace) %{_sysconfdir}/uhub/users.db
|
||||
%{_sysconfdir}/init.d/uhub
|
||||
%config(noreplace) %{_sysconfdir}/logrotate.d/uhub
|
||||
%config(noreplace) %{_sysconfdir}/sysconfig/uhub
|
||||
/usr/share/man/man1/uhub.1.gz
|
||||
%{_bindir}/uhub
|
||||
%{_libdir}/uhub/mod_*.so
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%post
|
||||
/sbin/chkconfig --add uhub
|
||||
if [ $1 -gt 1 ] ; then
|
||||
/etc/rc.d/init.d/uhub restart >/dev/null || :
|
||||
fi
|
||||
# need more informations about add services and users in system
|
||||
/usr/sbin/adduser -M -d /tmp -G nobody -s /sbin/nologin -c 'The Uhub ADC p2p hub Daemon' uhub >/dev/null 2>&1 ||:
|
||||
# write SSL create
|
||||
echo "PLS see /usr/share/doc/uhub/"
|
||||
|
||||
%changelog
|
||||
* Fri Dec 30 2011 E_zombie
|
||||
- add users.db
|
||||
- add new doc
|
||||
* Tue Jun 26 2010 E_zombie
|
||||
- add plugins.conf
|
||||
* Tue Jan 31 2010 E_zombie
|
||||
- change GROUP
|
||||
- chmod for files
|
||||
- add postinstall scripts
|
||||
- fix "License"
|
||||
* Tue Jan 26 2010 E_zombie
|
||||
- first .spec release
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
# uHub access control lists.
|
||||
#
|
||||
# Syntax: <command> [data]
|
||||
#
|
||||
# commands:
|
||||
# 'user_reg' - registered user with no particular privileges (data=nick:password)
|
||||
# 'user_op' - operator, can kick or ban people (data=nick:password)
|
||||
# 'user_admin' - administrator, can do everything operators can, and reconfigure the hub (data=nick:password)
|
||||
# 'deny_nick' - nick name that is not accepted (example; Administrator)
|
||||
# 'deny_ip' - Unacceptable IP (masks can be specified as CIDR: 0.0.0.0/32 will block all IPv4)
|
||||
# 'ban_nick' - banned user by nick
|
||||
# 'ban_cid' - banned user by cid
|
||||
|
||||
# Administrator
|
||||
# user_admin userA:password1
|
||||
# user_op userB:password2
|
||||
|
||||
# We don't want users with these names
|
||||
deny_nick Hub-Security
|
||||
deny_nick Administrator
|
||||
deny_nick root
|
||||
deny_nick admin
|
||||
deny_nick username
|
||||
deny_nick user
|
||||
deny_nick guest
|
||||
deny_nick operator
|
||||
|
||||
# Banned users
|
||||
# ban_nick H4X0R
|
||||
# ban_cid FOIL5EK2UDZYAXT7UIUFEKL4SEBEAJE3INJDKAY
|
||||
|
||||
# ban by ip
|
||||
#
|
||||
# to ban by CIDR
|
||||
# deny_ip 10.21.44.0/24
|
||||
#
|
||||
# to ban by IP-range.
|
||||
# deny_ip 10.21.44.7-10.21.44.9
|
||||
#
|
||||
# to ban a single IP address
|
||||
# deny_ip 10.21.44.7
|
||||
# (which is equivalent to using):
|
||||
# deny_ip 10.21.44.7/32
|
||||
|
||||
# Will not work, yet
|
||||
# nat_ip 10.0.0.0/8
|
||||
# nat_ip 127.0.0.0/8
|
||||
|
||||
# If you have made changes to this file, you must send a HANGUP signal
|
||||
# to uHub so that it will re-read the configuration files.
|
||||
# For example by invoking: 'killall -HUP uhub'
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<title>uhub by janvidar</title>
|
||||
|
||||
<link rel="stylesheet" href="stylesheets/styles.css">
|
||||
<link rel="stylesheet" href="stylesheets/pygment_trac.css">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<header>
|
||||
<h1>uhub</h1>
|
||||
<p>A high performance ADC peer to peer message hub.</p>
|
||||
<p class="view"><a href="https://github.com/janvidar/uhub">View the Project on GitHub <small>janvidar/uhub</small></a></p>
|
||||
<ul>
|
||||
<li><a href="https://github.com/janvidar/uhub/zipball/master">Download <strong>ZIP File</strong></a></li>
|
||||
<li><a href="https://github.com/janvidar/uhub/tarball/master">Download <strong>TAR Ball</strong></a></li>
|
||||
<li><a href="https://github.com/janvidar/uhub">Fork On <strong>GitHub</strong></a></li>
|
||||
</ul>
|
||||
</header>
|
||||
<section>
|
||||
<h3>Welcome to GitHub Pages.</h3>
|
||||
|
||||
<p>This automatic page generator is the easiest way to create beautiful pages for all of your projects. Author your page content here using GitHub Flavored Markdown, select a template crafted by a designer, and publish. After your page is generated, you can check out the new branch:</p>
|
||||
|
||||
<pre><code>$ cd your_repo_root/repo_name
|
||||
$ git fetch origin
|
||||
$ git checkout gh-pages
|
||||
</code></pre>
|
||||
|
||||
<p>If you're using the GitHub for Mac, simply sync your repository and you'll see the new branch.</p>
|
||||
|
||||
<h3>Designer Templates</h3>
|
||||
|
||||
<p>We've crafted some handsome templates for you to use. Go ahead and continue to layouts to browse through them. You can easily go back to edit your page before publishing. After publishing your page, you can revisit the page generator and switch to another theme. Your Page content will be preserved if it remained markdown format.</p>
|
||||
|
||||
<h3>Rather Drive Stick?</h3>
|
||||
|
||||
<p>If you prefer to not use the automatic generator, push a branch named <code>gh-pages</code> to your repository to create a page manually. In addition to supporting regular HTML content, GitHub Pages support Jekyll, a simple, blog aware static site generator written by our own Tom Preston-Werner. Jekyll makes it easy to create site-wide headers and footers without having to copy them across every page. It also offers intelligent blog support and other advanced templating features.</p>
|
||||
|
||||
<h3>Authors and Contributors</h3>
|
||||
|
||||
<p>You can <a href="https://github.com/blog/821" class="user-mention">@mention</a> a GitHub username to generate a link to their profile. The resulting <code><a></code> element will link to the contributor's GitHub Profile. For example: In 2007, Chris Wanstrath (<a href="https://github.com/defunkt" class="user-mention">@defunkt</a>), PJ Hyett (<a href="https://github.com/pjhyett" class="user-mention">@pjhyett</a>), and Tom Preston-Werner (<a href="https://github.com/mojombo" class="user-mention">@mojombo</a>) founded GitHub.</p>
|
||||
|
||||
<h3>Support or Contact</h3>
|
||||
|
||||
<p>Having trouble with Pages? Check out the documentation at <a href="http://help.github.com/pages">http://help.github.com/pages</a> or contact <a href="mailto:support@github.com">support@github.com</a> and we’ll help you sort it out.</p>
|
||||
</section>
|
||||
<footer>
|
||||
<p>This project is maintained by <a href="https://github.com/janvidar">janvidar</a></p>
|
||||
<p><small>Hosted on GitHub Pages — Theme by <a href="https://github.com/orderedlist">orderedlist</a></small></p>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="javascripts/scale.fix.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,17 @@
|
||||
var metas = document.getElementsByTagName('meta');
|
||||
var i;
|
||||
if (navigator.userAgent.match(/iPhone/i)) {
|
||||
for (i=0; i<metas.length; i++) {
|
||||
if (metas[i].name == "viewport") {
|
||||
metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
|
||||
}
|
||||
}
|
||||
document.addEventListener("gesturestart", gestureStart, false);
|
||||
}
|
||||
function gestureStart() {
|
||||
for (i=0; i<metas.length; i++) {
|
||||
if (metas[i].name == "viewport") {
|
||||
metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"name":"uhub","body":"### Welcome to GitHub Pages.\r\nThis automatic page generator is the easiest way to create beautiful pages for all of your projects. Author your page content here using GitHub Flavored Markdown, select a template crafted by a designer, and publish. After your page is generated, you can check out the new branch:\r\n\r\n```\r\n$ cd your_repo_root/repo_name\r\n$ git fetch origin\r\n$ git checkout gh-pages\r\n```\r\n\r\nIf you're using the GitHub for Mac, simply sync your repository and you'll see the new branch.\r\n\r\n### Designer Templates\r\nWe've crafted some handsome templates for you to use. Go ahead and continue to layouts to browse through them. You can easily go back to edit your page before publishing. After publishing your page, you can revisit the page generator and switch to another theme. Your Page content will be preserved if it remained markdown format.\r\n\r\n### Rather Drive Stick?\r\nIf you prefer to not use the automatic generator, push a branch named `gh-pages` to your repository to create a page manually. In addition to supporting regular HTML content, GitHub Pages support Jekyll, a simple, blog aware static site generator written by our own Tom Preston-Werner. Jekyll makes it easy to create site-wide headers and footers without having to copy them across every page. It also offers intelligent blog support and other advanced templating features.\r\n\r\n### Authors and Contributors\r\nYou can @mention a GitHub username to generate a link to their profile. The resulting `<a>` element will link to the contributor's GitHub Profile. For example: In 2007, Chris Wanstrath (@defunkt), PJ Hyett (@pjhyett), and Tom Preston-Werner (@mojombo) founded GitHub.\r\n\r\n### Support or Contact\r\nHaving trouble with Pages? Check out the documentation at http://help.github.com/pages or contact support@github.com and we’ll help you sort it out.","tagline":"A high performance ADC peer to peer message hub.","google":"","note":"Don't delete this file! It's used internally to help with page regeneration."}
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_ADC_CONSTANTS_H
|
||||
#define HAVE_UHUB_ADC_CONSTANTS_H
|
||||
|
||||
#ifndef SID_T_DEFINED
|
||||
typedef uint32_t sid_t;
|
||||
#define SID_T_DEFINED
|
||||
#endif
|
||||
|
||||
typedef uint32_t fourcc_t;
|
||||
|
||||
/* Internal uhub limit */
|
||||
#define MAX_ADC_CMD_LEN 4096
|
||||
|
||||
#define FOURCC(a,b,c,d) (fourcc_t) ((a << 24) | (b << 16) | (c << 8) | d)
|
||||
|
||||
/* default welcome protocol support message, as sent by this server */
|
||||
#define ADC_PROTO_SUPPORT "ADBASE ADTIGR ADPING"
|
||||
|
||||
/* Server sent commands */
|
||||
#define ADC_CMD_ISID FOURCC('I','S','I','D')
|
||||
#define ADC_CMD_ISUP FOURCC('I','S','U','P')
|
||||
#define ADC_CMD_IGPA FOURCC('I','G','P','A')
|
||||
#define ADC_CMD_ISTA FOURCC('I','S','T','A')
|
||||
#define ADC_CMD_IINF FOURCC('I','I','N','F')
|
||||
#define ADC_CMD_IMSG FOURCC('I','M','S','G')
|
||||
#define ADC_CMD_IQUI FOURCC('I','Q','U','I')
|
||||
|
||||
/* Handshake and login/passwordstuff */
|
||||
#define ADC_CMD_HSUP FOURCC('H','S','U','P')
|
||||
#define ADC_CMD_HPAS FOURCC('H','P','A','S')
|
||||
#define ADC_CMD_HINF FOURCC('H','I','N','F')
|
||||
#define ADC_CMD_BINF FOURCC('B','I','N','F')
|
||||
|
||||
/* This is a Admin extension */
|
||||
#define ADC_CMD_HDSC FOURCC('H','D','S','C')
|
||||
|
||||
/* Status/error messages */
|
||||
#define ADC_CMD_HSTA FOURCC('H','S','T','A')
|
||||
#define ADC_CMD_DSTA FOURCC('D','S','T','A')
|
||||
|
||||
/* searches */
|
||||
#define ADC_CMD_BSCH FOURCC('B','S','C','H')
|
||||
#define ADC_CMD_DSCH FOURCC('D','S','C','H')
|
||||
#define ADC_CMD_ESCH FOURCC('E','S','C','H')
|
||||
#define ADC_CMD_FSCH FOURCC('F','S','C','H')
|
||||
#define ADC_CMD_DRES FOURCC('D','R','E','S')
|
||||
|
||||
/* invalid search results (spam) */
|
||||
#define ADC_CMD_BRES FOURCC('B','R','E','S')
|
||||
#define ADC_CMD_ERES FOURCC('E','R','E','S')
|
||||
#define ADC_CMD_FRES FOURCC('F','R','E','S')
|
||||
|
||||
/* connection setup */
|
||||
#define ADC_CMD_DCTM FOURCC('D','C','T','M')
|
||||
#define ADC_CMD_DRCM FOURCC('D','R','C','M')
|
||||
#define ADC_CMD_ECTM FOURCC('E','C','T','M')
|
||||
#define ADC_CMD_ERCM FOURCC('E','R','C','M')
|
||||
|
||||
/* chat messages */
|
||||
#define ADC_CMD_BMSG FOURCC('B','M','S','G')
|
||||
#define ADC_CMD_DMSG FOURCC('D','M','S','G')
|
||||
#define ADC_CMD_EMSG FOURCC('E','M','S','G')
|
||||
#define ADC_CMD_FMSG FOURCC('F','M','S','G')
|
||||
|
||||
/* disallowed messages */
|
||||
#define ADC_CMD_DINF FOURCC('D','I','N','F')
|
||||
#define ADC_CMD_EINF FOURCC('E','I','N','F')
|
||||
#define ADC_CMD_FINF FOURCC('F','I','N','F')
|
||||
|
||||
/* Extension messages */
|
||||
#define ADC_CMD_HCHK FOURCC('H','C','H','K')
|
||||
|
||||
#define ADC_INF_FLAG_IPV4_ADDR "I4" /* ipv4 address */
|
||||
#define ADC_INF_FLAG_IPV6_ADDR "I6" /* ipv6 address */
|
||||
#define ADC_INF_FLAG_IPV4_UDP_PORT "U4" /* port number */
|
||||
#define ADC_INF_FLAG_IPV6_UDP_PORT "U6" /* port number */
|
||||
#define ADC_INF_FLAG_CLIENT_TYPE "CT" /* client type */
|
||||
#define ADC_INF_FLAG_PRIVATE_ID "PD" /* private id, aka PID */
|
||||
#define ADC_INF_FLAG_CLIENT_ID "ID" /* client id, aka CID */
|
||||
#define ADC_INF_FLAG_NICK "NI" /* nick name */
|
||||
#define ADC_INF_FLAG_DESCRIPTION "DE" /* user description */
|
||||
#define ADC_INF_FLAG_USER_AGENT "VE" /* software version */
|
||||
#define ADC_INF_FLAG_SUPPORT "SU" /* support (extensions, feature cast) */
|
||||
#define ADC_INF_FLAG_SHARED_SIZE "SS" /* size of total files shared in bytes */
|
||||
#define ADC_INF_FLAG_SHARED_FILES "SF" /* number of files shared */
|
||||
#define ADC_INF_FLAG_UPLOAD_SPEED "US" /* maximum upload speed acheived in bytes/sec */
|
||||
#define ADC_INF_FLAG_DOWNLOAD_SPEED "DS" /* maximum download speed acheived in bytes/sec */
|
||||
#define ADC_INF_FLAG_UPLOAD_SLOTS "SL" /* maximum upload slots (concurrent uploads) */
|
||||
#define ADC_INF_FLAG_AUTO_SLOTS "AS" /* automatic slot if upload speed is less than this in bytes/sec */
|
||||
#define ADC_INF_FLAG_AUTO_SLOTS_MAX "AM" /* maximum number of automatic slots */
|
||||
#define ADC_INF_FLAG_COUNT_HUB_NORMAL "HN" /* user is logged into this amount of hubs as a normal user (guest) */
|
||||
#define ADC_INF_FLAG_COUNT_HUB_REGISTER "HR" /* user is logged into this amount of hubs as a registered user (password) */
|
||||
#define ADC_INF_FLAG_COUNT_HUB_OPERATOR "HO" /* user is logged into this amount of hubs as an operator */
|
||||
#define ADC_INF_FLAG_AWAY "AW" /* away flag, 1=away, 2=extended away */
|
||||
#define ADC_INF_FLAG_REFERER "RF" /* URL to referer in case of hub redirect */
|
||||
#define ADC_INF_FLAG_EMAIL "EM" /* E-mail address */
|
||||
|
||||
#define ADC_MSG_FLAG_ACTION "ME" /* message is an *action* message */
|
||||
#define ADC_MSG_FLAG_PRIVATE "PM" /* message is a private message */
|
||||
|
||||
#define ADC_SCH_FLAG_INCLUDE "AN" /* include given search term */
|
||||
#define ADC_SCH_FLAG_EXCLUDE "NO" /* exclude given serach term */
|
||||
#define ADC_SCH_FLAG_FILE_EXTENSION "EX" /* search only for files with the given file extension */
|
||||
#define ADC_SCH_FLAG_FILE_TYPE "TY" /* search only for files with this file type (separate type) */
|
||||
#define ADC_SCH_FLAG_LESS_THAN "LE" /* search for files with this size or less */
|
||||
#define ADC_SCH_FLAG_GREATER_THAN "GE" /* search for files with this size or greater */
|
||||
#define ADC_SCH_FLAG_EQUAL "EQ" /* search only for files with this exact size */
|
||||
#define ADC_SCH_FLAG_TOKEN "TO" /* use this token for search replies */
|
||||
|
||||
#define ADC_RES_FLAG_FILE_NAME "FN" /* file name */
|
||||
#define ADC_RES_FLAG_FILE_SIZE "SI" /* file size */
|
||||
#define ADC_RES_FLAG_UPLOAD_SLOTS "SL" /* number of upload slots available (if > 0, download is possible) */
|
||||
#define ADC_RES_FLAG_TOKEN "TO" /* token, same as the token in the search request */
|
||||
|
||||
#define ADC_QUI_FLAG_TIME_LEFT "TL" /* time in seconds before reconnect is allowed, or -1 forever */
|
||||
#define ADC_QUI_FLAG_MESSAGE "MS" /* kick/leave message */
|
||||
#define ADC_QUI_FLAG_DISCONNECT "DI" /* all further transfers with this user should be disconnected */
|
||||
#define ADC_QUI_FLAG_REDIRECT "RD" /* redirect to URL */
|
||||
#define ADC_QUI_FLAG_KICK_OPERATOR "ID" /* SID of operator who disconnected the user */
|
||||
|
||||
#define ADC_SUP_FLAG_ADD "AD"
|
||||
#define ADC_SUP_FLAG_REMOVE "RM"
|
||||
|
||||
#define ADC_CLIENT_TYPE_BOT "1"
|
||||
#define ADC_CLIENT_TYPE_REGISTERED_USER "2"
|
||||
#define ADC_CLIENT_TYPE_OPERATOR "4"
|
||||
#define ADC_CLIENT_TYPE_SUPER_USER "12" /* 8 + 4 */
|
||||
#define ADC_CLIENT_TYPE_ADMIN "20" /* 16 + 4 = hub owner */
|
||||
#define ADC_CLIENT_TYPE_HUB "32" /* the hub itself */
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_ADC_CONSTANTS_H */
|
||||
@@ -1,909 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define ADC_MSG_ASSERT(X) \
|
||||
uhub_assert(X); \
|
||||
uhub_assert(X->cache); \
|
||||
uhub_assert(X->capacity); \
|
||||
uhub_assert(X->length); \
|
||||
uhub_assert(X->length <= X->capacity); \
|
||||
uhub_assert(X->references > 0); \
|
||||
uhub_assert(X->length == strlen(X->cache));
|
||||
#define ADC_MSG_NULL_ON_FREE
|
||||
#else
|
||||
#define ADC_MSG_ASSERT(X) do { } while(0)
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifdef MSG_MEMORY_DEBUG
|
||||
#undef msg_malloc
|
||||
#undef msg_malloc_zero
|
||||
#undef msg_free
|
||||
|
||||
static void* msg_malloc(size_t size)
|
||||
{
|
||||
void* ptr = valloc(size);
|
||||
LOG_MEMORY("msg_malloc: %p %d", ptr, (int) size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void* msg_malloc_zero(size_t size)
|
||||
{
|
||||
void* ptr = msg_malloc(size);
|
||||
memset(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void msg_free(void* ptr)
|
||||
{
|
||||
LOG_MEMORY("msg_free: %p", ptr);
|
||||
hub_free(ptr);
|
||||
}
|
||||
#else
|
||||
#define msg_malloc(X) hub_malloc(X)
|
||||
#define msg_malloc_zero(X) hub_malloc_zero(X)
|
||||
#define msg_free(X) hub_free(X)
|
||||
#endif /* MSG_MEMORY_DEBUG */
|
||||
|
||||
|
||||
struct adc_message* adc_msg_incref(struct adc_message* msg)
|
||||
{
|
||||
#ifndef ADC_MESSAGE_INCREF
|
||||
msg->references++;
|
||||
#ifdef MSG_MEMORY_DEBUG
|
||||
adc_msg_protect(msg);
|
||||
#endif
|
||||
return msg;
|
||||
#else
|
||||
struct adc_message* copy = adc_msg_copy(msg);
|
||||
return copy;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void adc_msg_set_length(struct adc_message* msg, size_t len)
|
||||
{
|
||||
msg->length = len;
|
||||
}
|
||||
|
||||
static int adc_msg_grow(struct adc_message* msg, size_t size)
|
||||
{
|
||||
char* buf;
|
||||
size_t newsize = 0;
|
||||
|
||||
if (!msg)
|
||||
return 0;
|
||||
|
||||
if (msg->capacity > size)
|
||||
return 1;
|
||||
|
||||
/* Make sure we align our data */
|
||||
newsize = size;
|
||||
newsize += 2; /* termination */
|
||||
newsize += (newsize % sizeof(size_t)); /* alignment padding */
|
||||
|
||||
buf = msg_malloc_zero(newsize);
|
||||
if (!buf)
|
||||
return 0;
|
||||
|
||||
if (msg->cache)
|
||||
{
|
||||
memcpy(buf, msg->cache, msg->length);
|
||||
msg_free(msg->cache);
|
||||
}
|
||||
|
||||
msg->cache = buf;
|
||||
msg->capacity = newsize;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* NOTE: msg must be unterminated here */
|
||||
static int adc_msg_cache_append(struct adc_message* msg, const char* string, size_t len)
|
||||
{
|
||||
if (!adc_msg_grow(msg, msg->length + len))
|
||||
{
|
||||
/* FIXME: OOM! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&msg->cache[msg->length], string, len);
|
||||
adc_msg_set_length(msg, msg->length + len);
|
||||
|
||||
assert(msg->capacity > msg->length);
|
||||
msg->cache[msg->length] = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns position of the first argument of the message.
|
||||
* Excludes mandatory arguments for the given type of message
|
||||
* like source and target.
|
||||
*/
|
||||
int adc_msg_get_arg_offset(struct adc_message* msg)
|
||||
{
|
||||
if (!msg || !msg->cache)
|
||||
return -1;
|
||||
|
||||
switch (msg->cache[0])
|
||||
{
|
||||
/* These *SHOULD* never be seen on a hub */
|
||||
case 'U':
|
||||
case 'C':
|
||||
return 4; /* Actually: 4 + strlen(cid). */
|
||||
|
||||
case 'I':
|
||||
case 'H':
|
||||
return 4;
|
||||
|
||||
case 'B':
|
||||
return 9;
|
||||
|
||||
case 'F':
|
||||
return (10 + (list_size(msg->feature_cast_include)*5) + (list_size(msg->feature_cast_exclude)*5));
|
||||
|
||||
case 'D':
|
||||
case 'E':
|
||||
return 14;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int adc_msg_is_empty(struct adc_message* msg)
|
||||
{
|
||||
int offset = adc_msg_get_arg_offset(msg);
|
||||
|
||||
if (offset == -1)
|
||||
return -1;
|
||||
|
||||
if ((msg->length - 1) == (size_t) offset)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void adc_msg_free(struct adc_message* msg)
|
||||
{
|
||||
if (!msg) return;
|
||||
|
||||
ADC_MSG_ASSERT(msg);
|
||||
|
||||
msg->references--;
|
||||
|
||||
if (msg->references == 0)
|
||||
{
|
||||
#ifdef ADC_MSG_NULL_ON_FREE
|
||||
if (msg->cache)
|
||||
{
|
||||
*msg->cache = 0;
|
||||
}
|
||||
#endif
|
||||
msg_free(msg->cache);
|
||||
|
||||
if (msg->feature_cast_include)
|
||||
{
|
||||
list_clear(msg->feature_cast_include, &hub_free);
|
||||
list_destroy(msg->feature_cast_include);
|
||||
msg->feature_cast_include = 0;
|
||||
}
|
||||
|
||||
if (msg->feature_cast_exclude)
|
||||
{
|
||||
list_clear(msg->feature_cast_exclude, &hub_free);
|
||||
list_destroy(msg->feature_cast_exclude);
|
||||
msg->feature_cast_exclude = 0;
|
||||
}
|
||||
|
||||
msg_free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct adc_message* adc_msg_copy(const struct adc_message* cmd)
|
||||
{
|
||||
char* tmp = 0;
|
||||
struct adc_message* copy = (struct adc_message*) msg_malloc_zero(sizeof(struct adc_message));
|
||||
if (!copy) return NULL; /* OOM */
|
||||
|
||||
ADC_MSG_ASSERT(cmd);
|
||||
|
||||
/* deep copy */
|
||||
copy->cmd = cmd->cmd;
|
||||
copy->source = cmd->source;
|
||||
copy->target = cmd->target;
|
||||
copy->cache = 0;
|
||||
copy->length = cmd->length;
|
||||
copy->capacity = 0;
|
||||
copy->priority = cmd->priority;
|
||||
copy->references = 1;
|
||||
copy->feature_cast_include = 0;
|
||||
copy->feature_cast_exclude = 0;
|
||||
|
||||
if (!adc_msg_grow(copy, copy->length))
|
||||
{
|
||||
adc_msg_free(copy);
|
||||
return NULL; /* OOM */
|
||||
}
|
||||
|
||||
if (!copy->cache)
|
||||
{
|
||||
adc_msg_free(copy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(copy->cache, cmd->cache, cmd->length);
|
||||
copy->cache[copy->length] = 0;
|
||||
|
||||
if (cmd->feature_cast_include)
|
||||
{
|
||||
copy->feature_cast_include = list_create();
|
||||
tmp = list_get_first(cmd->feature_cast_include);
|
||||
while (tmp)
|
||||
{
|
||||
list_append(copy->feature_cast_include, hub_strdup(tmp));
|
||||
tmp = list_get_next(cmd->feature_cast_include);
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd->feature_cast_exclude)
|
||||
{
|
||||
copy->feature_cast_exclude = list_create();
|
||||
tmp = list_get_first(cmd->feature_cast_exclude);
|
||||
while (tmp)
|
||||
{
|
||||
list_append(copy->feature_cast_exclude, hub_strdup(tmp));
|
||||
tmp = list_get_next(cmd->feature_cast_exclude);
|
||||
}
|
||||
}
|
||||
|
||||
ADC_MSG_ASSERT(copy);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
struct adc_message* adc_msg_parse_verify(struct hub_user* u, const char* line, size_t length)
|
||||
{
|
||||
struct adc_message* command = adc_msg_parse(line, length);
|
||||
|
||||
if (!command)
|
||||
return 0;
|
||||
|
||||
if (command->source && (!u || command->source != u->id.sid))
|
||||
{
|
||||
LOG_DEBUG("Command does not match user's SID (command->source=%d, user->id.sid=%d)", command->source, (u ? u->id.sid : 0));
|
||||
adc_msg_free(command);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
|
||||
struct adc_message* adc_msg_parse(const char* line, size_t length)
|
||||
{
|
||||
struct adc_message* command = (struct adc_message*) msg_malloc_zero(sizeof(struct adc_message));
|
||||
char prefix = line[0];
|
||||
size_t n = 0;
|
||||
char temp_sid[5];
|
||||
int ok = 1;
|
||||
int need_terminate = 0;
|
||||
struct linked_list* feature_cast_list;
|
||||
|
||||
if (command == NULL)
|
||||
return NULL; /* OOM */
|
||||
|
||||
if (!is_printable_utf8(line, length))
|
||||
{
|
||||
LOG_DEBUG("Dropped message with non-printable UTF-8 characters.");
|
||||
msg_free(command);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (line[length-1] != '\n')
|
||||
{
|
||||
need_terminate = 1;
|
||||
}
|
||||
|
||||
if (!adc_msg_grow(command, length + need_terminate))
|
||||
{
|
||||
msg_free(command);
|
||||
return NULL; /* OOM */
|
||||
}
|
||||
|
||||
adc_msg_set_length(command, length + need_terminate);
|
||||
memcpy(command->cache, line, length);
|
||||
|
||||
/* Ensure we are zero terminated */
|
||||
command->cache[length] = 0;
|
||||
command->cache[length+need_terminate] = 0;
|
||||
|
||||
command->cmd = FOURCC(line[0], line[1], line[2], line[3]);
|
||||
command->priority = 0;
|
||||
command->references = 1;
|
||||
|
||||
switch (prefix)
|
||||
{
|
||||
case 'U':
|
||||
case 'C':
|
||||
/* these should never be seen on a hub */
|
||||
ok = 0;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
case 'H':
|
||||
ok = (length > 3);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
ok = (length > 8 &&
|
||||
is_space(line[4]) &&
|
||||
is_valid_base32_char(line[5]) &&
|
||||
is_valid_base32_char(line[6]) &&
|
||||
is_valid_base32_char(line[7]) &&
|
||||
is_valid_base32_char(line[8]));
|
||||
|
||||
if (!ok) break;
|
||||
|
||||
temp_sid[0] = line[5];
|
||||
temp_sid[1] = line[6];
|
||||
temp_sid[2] = line[7];
|
||||
temp_sid[3] = line[8];
|
||||
temp_sid[4] = '\0';
|
||||
|
||||
command->source = string_to_sid(temp_sid);
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
ok = (length > 8 &&
|
||||
is_space(line[4]) &&
|
||||
is_valid_base32_char(line[5]) &&
|
||||
is_valid_base32_char(line[6]) &&
|
||||
is_valid_base32_char(line[7]) &&
|
||||
is_valid_base32_char(line[8]));
|
||||
|
||||
if (!ok) break;
|
||||
|
||||
temp_sid[0] = line[5];
|
||||
temp_sid[1] = line[6];
|
||||
temp_sid[2] = line[7];
|
||||
temp_sid[3] = line[8];
|
||||
temp_sid[4] = '\0';
|
||||
|
||||
command->source = string_to_sid(temp_sid);
|
||||
|
||||
/* Create feature cast lists */
|
||||
command->feature_cast_include = list_create();
|
||||
command->feature_cast_exclude = list_create();
|
||||
|
||||
if (!command->feature_cast_include || !command->feature_cast_exclude)
|
||||
{
|
||||
list_destroy(command->feature_cast_include);
|
||||
list_destroy(command->feature_cast_exclude);
|
||||
msg_free(command->cache);
|
||||
msg_free(command);
|
||||
return NULL; /* OOM */
|
||||
}
|
||||
|
||||
n = 10;
|
||||
while (line[n] == '+' || line[n] == '-')
|
||||
{
|
||||
if (line[n++] == '+')
|
||||
feature_cast_list = command->feature_cast_include;
|
||||
else
|
||||
feature_cast_list = command->feature_cast_exclude;
|
||||
|
||||
temp_sid[0] = line[n++];
|
||||
temp_sid[1] = line[n++];
|
||||
temp_sid[2] = line[n++];
|
||||
temp_sid[3] = line[n++];
|
||||
temp_sid[4] = '\0';
|
||||
|
||||
list_append(feature_cast_list, hub_strdup(temp_sid));
|
||||
}
|
||||
|
||||
if (n == 10)
|
||||
ok = 0;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
case 'E':
|
||||
ok = (length > 13 &&
|
||||
is_space(line[4]) &&
|
||||
is_valid_base32_char(line[5]) &&
|
||||
is_valid_base32_char(line[6]) &&
|
||||
is_valid_base32_char(line[7]) &&
|
||||
is_valid_base32_char(line[8]) &&
|
||||
is_space(line[9]) &&
|
||||
is_valid_base32_char(line[10]) &&
|
||||
is_valid_base32_char(line[11]) &&
|
||||
is_valid_base32_char(line[12]) &&
|
||||
is_valid_base32_char(line[13]));
|
||||
|
||||
if (!ok) break;
|
||||
|
||||
temp_sid[0] = line[5];
|
||||
temp_sid[1] = line[6];
|
||||
temp_sid[2] = line[7];
|
||||
temp_sid[3] = line[8];
|
||||
temp_sid[4] = '\0';
|
||||
|
||||
command->source = string_to_sid(temp_sid);
|
||||
|
||||
temp_sid[0] = line[10];
|
||||
temp_sid[1] = line[11];
|
||||
temp_sid[2] = line[12];
|
||||
temp_sid[3] = line[13];
|
||||
temp_sid[4] = '\0';
|
||||
|
||||
command->target = string_to_sid(temp_sid);
|
||||
break;
|
||||
|
||||
default:
|
||||
ok = 0;
|
||||
}
|
||||
|
||||
if (need_terminate)
|
||||
{
|
||||
command->cache[length] = '\n';
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
adc_msg_free(command);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* At this point the arg_offset should point to a space, or the end of message */
|
||||
n = adc_msg_get_arg_offset(command);
|
||||
if (command->cache[n] == ' ')
|
||||
{
|
||||
if (command->cache[n+1] == ' ') ok = 0;
|
||||
}
|
||||
else if (command->cache[n] == '\n') ok = 1;
|
||||
else ok = 0;
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
adc_msg_free(command);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ADC_MSG_ASSERT(command);
|
||||
return command;
|
||||
}
|
||||
|
||||
|
||||
struct adc_message* adc_msg_create(const char* line)
|
||||
{
|
||||
return adc_msg_parse(line, strlen(line));
|
||||
}
|
||||
|
||||
|
||||
struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size)
|
||||
{
|
||||
struct adc_message* msg = (struct adc_message*) msg_malloc_zero(sizeof(struct adc_message));
|
||||
if (!msg)
|
||||
return NULL; /* OOM */
|
||||
|
||||
if (size < sizeof(fourcc)) size = sizeof(fourcc);
|
||||
|
||||
if (!adc_msg_grow(msg, size+1))
|
||||
{
|
||||
msg_free(msg);
|
||||
return NULL; /* OOM */
|
||||
}
|
||||
|
||||
if (fourcc)
|
||||
{
|
||||
msg->cache[0] = (char) ((fourcc >> 24) & 0xff);
|
||||
msg->cache[1] = (char) ((fourcc >> 16) & 0xff);
|
||||
msg->cache[2] = (char) ((fourcc >> 8) & 0xff);
|
||||
msg->cache[3] = (char) ((fourcc ) & 0xff);
|
||||
msg->cache[4] = '\n';
|
||||
|
||||
/* Ensure we are zero terminated */
|
||||
adc_msg_set_length(msg, 5);
|
||||
msg->cache[msg->length] = 0;
|
||||
}
|
||||
|
||||
msg->cmd = fourcc;
|
||||
msg->priority = 0;
|
||||
msg->references = 1;
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
int adc_msg_remove_named_argument(struct adc_message* cmd, const char prefix_[2])
|
||||
{
|
||||
char* start;
|
||||
char* end;
|
||||
char* endInfo;
|
||||
size_t endlen;
|
||||
char prefix[4] = { ' ', prefix_[0], prefix_[1], '\0' };
|
||||
int found = 0;
|
||||
int arg_offset = adc_msg_get_arg_offset(cmd);
|
||||
size_t temp_len = 0;
|
||||
|
||||
adc_msg_unterminate(cmd);
|
||||
|
||||
start = memmem(&cmd->cache[arg_offset], (cmd->length - arg_offset), prefix, 3);
|
||||
while (start)
|
||||
{
|
||||
endInfo = &cmd->cache[cmd->length];
|
||||
|
||||
if (&start[0] < &endInfo[0])
|
||||
{
|
||||
end = memchr(&start[1], ' ', &endInfo[0]-&start[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
end = NULL;
|
||||
}
|
||||
|
||||
if (end)
|
||||
{
|
||||
|
||||
temp_len = &end[0] - &start[0]; // strlen(start);
|
||||
endlen = strlen(end);
|
||||
|
||||
memmove(start, end, endlen);
|
||||
start[endlen] = '\0';
|
||||
found++;
|
||||
adc_msg_set_length(cmd, cmd->length - temp_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
found++;
|
||||
adc_msg_set_length(cmd, cmd->length - strlen(start));
|
||||
start[0] = '\0';
|
||||
break;
|
||||
}
|
||||
start = memmem(&cmd->cache[arg_offset], (cmd->length - arg_offset), prefix, 3);
|
||||
}
|
||||
|
||||
adc_msg_terminate(cmd);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
int adc_msg_has_named_argument(struct adc_message* cmd, const char prefix_[2])
|
||||
{
|
||||
int count = 0;
|
||||
char* start;
|
||||
char prefix[4] = { ' ', prefix_[0], prefix_[1], '\0' };
|
||||
int arg_offset = adc_msg_get_arg_offset(cmd);
|
||||
|
||||
ADC_MSG_ASSERT(cmd);
|
||||
|
||||
start = memmem(&cmd->cache[arg_offset], (cmd->length - arg_offset), prefix, 3);
|
||||
while (start)
|
||||
{
|
||||
count++;
|
||||
if ((size_t) (&start[0] - &cmd->cache[0]) < 1+cmd->length)
|
||||
start = memmem(&start[1], (&cmd->cache[cmd->length] - &start[0]), prefix, 3);
|
||||
else
|
||||
start = NULL;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
char* adc_msg_get_named_argument(struct adc_message* cmd, const char prefix_[2])
|
||||
{
|
||||
char* start;
|
||||
char* end;
|
||||
char* argument;
|
||||
size_t length;
|
||||
char prefix[4] = { ' ', prefix_[0], prefix_[1], '\0' };
|
||||
int arg_offset = adc_msg_get_arg_offset(cmd);
|
||||
|
||||
ADC_MSG_ASSERT(cmd);
|
||||
|
||||
start = memmem(&cmd->cache[arg_offset], cmd->length - arg_offset, prefix, 3);
|
||||
if (!start)
|
||||
return NULL;
|
||||
|
||||
start = &start[3];
|
||||
end = strchr(start, ' ');
|
||||
if (!end) end = &cmd->cache[cmd->length];
|
||||
length = &end[0] - &start[0];
|
||||
|
||||
argument = hub_strndup(start, length);
|
||||
|
||||
if (length > 0 && argument[length-1] == '\n')
|
||||
{
|
||||
argument[length-1] = 0;
|
||||
}
|
||||
|
||||
return argument;
|
||||
}
|
||||
|
||||
|
||||
int adc_msg_replace_named_argument(struct adc_message* cmd, const char prefix[2], const char* string)
|
||||
{
|
||||
ADC_MSG_ASSERT(cmd);
|
||||
|
||||
while (adc_msg_has_named_argument(cmd, prefix))
|
||||
{
|
||||
adc_msg_remove_named_argument(cmd, prefix);
|
||||
}
|
||||
|
||||
if (adc_msg_add_named_argument(cmd, prefix, string) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ADC_MSG_ASSERT(cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void adc_msg_terminate(struct adc_message* cmd)
|
||||
{
|
||||
if (cmd->cache[cmd->length - 1] != '\n')
|
||||
{
|
||||
adc_msg_cache_append(cmd, "\n", 1);
|
||||
}
|
||||
ADC_MSG_ASSERT(cmd);
|
||||
}
|
||||
|
||||
/* FIXME: this looks bogus */
|
||||
void adc_msg_unterminate(struct adc_message* cmd)
|
||||
{
|
||||
ADC_MSG_ASSERT(cmd);
|
||||
|
||||
if (cmd->length > 0 && cmd->cache[cmd->length-1] == '\n')
|
||||
{
|
||||
cmd->length--;
|
||||
cmd->cache[cmd->length] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix[2], const char* string)
|
||||
{
|
||||
int ret = 0;
|
||||
if (!string)
|
||||
return -1;
|
||||
|
||||
ADC_MSG_ASSERT(cmd);
|
||||
|
||||
adc_msg_unterminate(cmd);
|
||||
adc_msg_cache_append(cmd, " ", 1);
|
||||
adc_msg_cache_append(cmd, prefix, 2);
|
||||
adc_msg_cache_append(cmd, string, strlen(string));
|
||||
adc_msg_terminate(cmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int adc_msg_add_named_argument_string(struct adc_message* cmd, const char prefix[2], const char* string)
|
||||
{
|
||||
char* escaped = adc_msg_escape(string);
|
||||
int ret = adc_msg_add_named_argument(cmd, prefix, escaped);
|
||||
hub_free(escaped);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int adc_msg_add_named_argument_int(struct adc_message* cmd, const char prefix[2], int num)
|
||||
{
|
||||
const char* s = uhub_itoa(num);
|
||||
int ret = adc_msg_add_named_argument(cmd, prefix, s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int adc_msg_add_named_argument_uint64(struct adc_message* cmd, const char prefix[2], uint64_t num)
|
||||
{
|
||||
const char* s = uhub_ulltoa(num);
|
||||
int ret = adc_msg_add_named_argument(cmd, prefix, s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int adc_msg_add_argument(struct adc_message* cmd, const char* string)
|
||||
{
|
||||
ADC_MSG_ASSERT(cmd);
|
||||
|
||||
adc_msg_unterminate(cmd);
|
||||
adc_msg_cache_append(cmd, " ", 1);
|
||||
adc_msg_cache_append(cmd, string, strlen(string));
|
||||
adc_msg_terminate(cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char* adc_msg_get_argument(struct adc_message* cmd, int offset)
|
||||
{
|
||||
char* start;
|
||||
char* end;
|
||||
char* argument;
|
||||
int count = 0;
|
||||
|
||||
ADC_MSG_ASSERT(cmd);
|
||||
|
||||
adc_msg_unterminate(cmd);
|
||||
|
||||
start = strchr(&cmd->cache[adc_msg_get_arg_offset(cmd)-1], ' ');
|
||||
while (start)
|
||||
{
|
||||
end = strchr(&start[1], ' ');
|
||||
if (count == offset)
|
||||
{
|
||||
if (end)
|
||||
{
|
||||
argument = hub_strndup(&start[1], (&end[0] - &start[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
argument = hub_strdup(&start[1]);
|
||||
if (argument && *argument && argument[strlen(argument)-1] == '\n')
|
||||
argument[strlen(argument)-1] = 0;
|
||||
}
|
||||
|
||||
if (!argument)
|
||||
return 0; // FIXME: OOM
|
||||
|
||||
if (*argument)
|
||||
{
|
||||
adc_msg_terminate(cmd);
|
||||
return argument;
|
||||
}
|
||||
else
|
||||
{
|
||||
hub_free(argument);
|
||||
}
|
||||
}
|
||||
count++;
|
||||
start = end;
|
||||
}
|
||||
|
||||
adc_msg_terminate(cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: Untested code.
|
||||
*/
|
||||
int adc_msg_get_argument_index(struct adc_message* cmd, const char prefix[2])
|
||||
{
|
||||
char* start;
|
||||
char* end;
|
||||
int count = 0;
|
||||
|
||||
ADC_MSG_ASSERT(cmd);
|
||||
|
||||
adc_msg_unterminate(cmd);
|
||||
|
||||
start = strchr(&cmd->cache[adc_msg_get_arg_offset(cmd)-1], ' ');
|
||||
while (start)
|
||||
{
|
||||
end = strchr(&start[1], ' ');
|
||||
if (((&end[0] - &start[1]) > 2) && ((start[1] == prefix[0]) && (start[2] == prefix[1])))
|
||||
{
|
||||
adc_msg_terminate(cmd);
|
||||
return count;
|
||||
}
|
||||
count++;
|
||||
start = end;
|
||||
}
|
||||
adc_msg_terminate(cmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int adc_msg_escape_length(const char* str)
|
||||
{
|
||||
int add = 0;
|
||||
int n = 0;
|
||||
for (; str[n]; n++)
|
||||
if (str[n] == ' ' || str[n] == '\n' || str[n] == '\\') add++;
|
||||
return n + add;
|
||||
}
|
||||
|
||||
|
||||
int adc_msg_unescape_length(const char* str)
|
||||
{
|
||||
int add = 0;
|
||||
int n = 0;
|
||||
int escape = 0;
|
||||
for (; str[n]; n++)
|
||||
{
|
||||
if (escape)
|
||||
{
|
||||
escape = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (str[n] == '\\')
|
||||
{
|
||||
escape = 1;
|
||||
add++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return n - add;
|
||||
}
|
||||
|
||||
|
||||
char* adc_msg_unescape(const char* string)
|
||||
{
|
||||
char* new_string = msg_malloc(adc_msg_unescape_length(string)+1);
|
||||
char* ptr = (char*) new_string;
|
||||
char* str = (char*) string;
|
||||
int escaped = 0;
|
||||
|
||||
while (*str)
|
||||
{
|
||||
if (escaped) {
|
||||
if (*str == 's')
|
||||
*ptr++ = ' ';
|
||||
else if (*str == '\\')
|
||||
*ptr++ = '\\';
|
||||
else if (*str == 'n')
|
||||
*ptr++ = '\n';
|
||||
else
|
||||
*ptr++ = *str;
|
||||
escaped = 0;
|
||||
} else {
|
||||
if (*str == '\\')
|
||||
escaped = 1;
|
||||
else
|
||||
*ptr++ = *str;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
*ptr = 0;
|
||||
return new_string;
|
||||
}
|
||||
|
||||
|
||||
char* adc_msg_escape(const char* string)
|
||||
{
|
||||
char* str = hub_malloc(adc_msg_escape_length(string)+1);
|
||||
size_t n = 0;
|
||||
size_t i = 0;
|
||||
for (i = 0; i < strlen(string); i++)
|
||||
{
|
||||
switch (string[i]) {
|
||||
case '\\': /* fall through */
|
||||
str[n++] = '\\';
|
||||
str[n++] = '\\';
|
||||
break;
|
||||
case '\n':
|
||||
str[n++] = '\\';
|
||||
str[n++] = 'n';
|
||||
break;
|
||||
case ' ':
|
||||
str[n++] = '\\';
|
||||
str[n++] = 's';
|
||||
break;
|
||||
default:
|
||||
str[n++] = string[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
str[n] = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_COMMAND_H
|
||||
#define HAVE_UHUB_COMMAND_H
|
||||
|
||||
struct hub_user;
|
||||
|
||||
struct adc_message
|
||||
{
|
||||
fourcc_t cmd;
|
||||
sid_t source;
|
||||
sid_t target;
|
||||
char* cache;
|
||||
size_t length;
|
||||
size_t capacity;
|
||||
size_t priority;
|
||||
size_t references;
|
||||
struct linked_list* feature_cast_include;
|
||||
struct linked_list* feature_cast_exclude;
|
||||
};
|
||||
|
||||
enum msg_status_level
|
||||
{
|
||||
status_level_info = 0, /* Success/informative status message */
|
||||
status_level_error = 1, /* Recoverable error */
|
||||
status_level_fatal = 2, /* Fatal error (disconnect) */
|
||||
};
|
||||
|
||||
/**
|
||||
* Increase the reference counter for an ADC message struct.
|
||||
* NOTE: Always use the returned value, and not the passed value, as
|
||||
* it ensures we can actually copy the value if needed.
|
||||
*/
|
||||
extern struct adc_message* adc_msg_incref(struct adc_message* msg);
|
||||
|
||||
/**
|
||||
* Decrease the reference counter, and free the memory when apropriate.
|
||||
*/
|
||||
extern void adc_msg_free(struct adc_message* msg);
|
||||
|
||||
/**
|
||||
* Perform deep copy a command.
|
||||
* NOTE: 'references' will be zero for the copied command.
|
||||
* @return a copy of cmd or NULL if not able to allocate memory.
|
||||
*/
|
||||
extern struct adc_message* adc_msg_copy(const struct adc_message* cmd);
|
||||
|
||||
/**
|
||||
* This will parse 'string' and return it as a adc_message struct, or
|
||||
* NULL if not able to allocate memory or 'string' does not contain
|
||||
* a valid ADC command.
|
||||
*
|
||||
* The message is only considered valid if the user who sent it
|
||||
* is the rightful origin of the message.
|
||||
*/
|
||||
extern struct adc_message* adc_msg_parse_verify(struct hub_user* u, const char* string, size_t length);
|
||||
|
||||
/**
|
||||
* This will parse 'string' and return it as a adc_message struct, or
|
||||
* NULL if not able to allocate memory or 'string' does not contain
|
||||
* a valid ADC command.
|
||||
*/
|
||||
extern struct adc_message* adc_msg_parse(const char* string, size_t length);
|
||||
|
||||
/**
|
||||
* This will construct a adc_message based on 'string'.
|
||||
* Only to be used for server generated commands.
|
||||
*/
|
||||
extern struct adc_message* adc_msg_create(const char* string);
|
||||
|
||||
/**
|
||||
* Construct a message with the given 'fourcc' and allocate
|
||||
* 'size' bytes for later use.
|
||||
*/
|
||||
extern struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size);
|
||||
|
||||
/**
|
||||
* Remove a named argument from the command.
|
||||
*
|
||||
* @arg prefix a 2 character argument prefix
|
||||
* @return the number of named arguments removed.
|
||||
*/
|
||||
extern int adc_msg_remove_named_argument(struct adc_message* cmd, const char prefix[2]);
|
||||
|
||||
/**
|
||||
* Count the number of arguments matching the given 2 character prefix.
|
||||
*
|
||||
* @arg prefix a 2 character argument prefix
|
||||
* @return the number of matching arguments
|
||||
*/
|
||||
extern int adc_msg_has_named_argument(struct adc_message* cmd, const char prefix[2]);
|
||||
|
||||
/**
|
||||
* Returns a named arguments based on the 2 character prefix.
|
||||
* If multiple matching arguments exists, only the first one will be returned
|
||||
* by this function.
|
||||
*
|
||||
* NOTE: Returned memory must be free'd with hub_free().
|
||||
*
|
||||
* @arg prefix a 2 character argument prefix
|
||||
* @return the argument or NULL if OOM/not found.
|
||||
*/
|
||||
extern char* adc_msg_get_named_argument(struct adc_message* cmd, const char prefix[2]);
|
||||
|
||||
/**
|
||||
* Returns a offset of an argument based on the 2 character prefix.
|
||||
* If multiple matching arguments exists, only the first one will be returned
|
||||
* by this function.
|
||||
*
|
||||
* @arg prefix a 2 character argument prefix
|
||||
* @return the offset or -1 if the argument is not found.
|
||||
*/
|
||||
extern int adc_msg_get_named_argument_index(struct adc_message* cmd, const char prefix[2]);
|
||||
|
||||
/**
|
||||
* @param cmd command to be checked
|
||||
* @return 1 if the command does not have any arguments (parameters), 0 otherwise, -1 if cmd is invalid.
|
||||
*/
|
||||
extern int adc_msg_is_empty(struct adc_message* cmd);
|
||||
|
||||
/**
|
||||
* Returns the argument on the offset position in the command.
|
||||
* If offset is invalid NULL is returned.
|
||||
*
|
||||
* NOTE: Returned memory must be free'd with hub_free().
|
||||
*
|
||||
* @return the argument or NULL if OOM/not found.
|
||||
*/
|
||||
extern char* adc_msg_get_argument(struct adc_message* cmd, int offset);
|
||||
|
||||
/**
|
||||
* Replace a named argument in the command.
|
||||
* This will remove any matching arguments (multiple, or none),
|
||||
* then add 'string' as an argument using the given prefix.
|
||||
*
|
||||
* @arg prefix a 2 character argument prefix
|
||||
* @arg string must be escaped (see adc_msg_escape).
|
||||
* @return 0 if successful, or -1 if an error occured.
|
||||
*/
|
||||
extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char prefix[2], const char* string);
|
||||
|
||||
/**
|
||||
* Append an argument
|
||||
*
|
||||
* @arg string must be escaped (see adc_msg_escape).
|
||||
* @return 0 if successful, or -1 if an error occured (out of memory).
|
||||
*/
|
||||
extern int adc_msg_add_argument(struct adc_message* cmd, const char* string);
|
||||
|
||||
/**
|
||||
* Append a named argument
|
||||
*
|
||||
* @arg prefix a 2 character argument prefix
|
||||
* @arg string must be escaped (see adc_msg_escape).
|
||||
* @return 0 if successful, or -1 if an error occured (out of memory).
|
||||
*/
|
||||
extern int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix[2], const char* string);
|
||||
|
||||
/**
|
||||
* Append a string as a named argument.
|
||||
* The string will automatcally be escaped, if you do not wish to escape th string use adc_msg_add_named_argument() instead.
|
||||
*
|
||||
* @arg prefix a 2 character argument prefix
|
||||
* @arg string must NOT be escaped
|
||||
* @return 0 if successful, or -1 if an error occured (out of memory).
|
||||
*/
|
||||
extern int adc_msg_add_named_argument_string(struct adc_message* cmd, const char prefix[2], const char* string);
|
||||
|
||||
/**
|
||||
* Append an integer as a named argument.
|
||||
*/
|
||||
extern int adc_msg_add_named_argument_int(struct adc_message* cmd, const char prefix[2], int integer);
|
||||
extern int adc_msg_add_named_argument_uint64(struct adc_message* cmd, const char prefix[2], uint64_t num);
|
||||
|
||||
/**
|
||||
* Convert a ADC command escaped string to a regular string.
|
||||
* @return string or NULL if out of memory
|
||||
*/
|
||||
extern char* adc_msg_unescape(const char* string);
|
||||
|
||||
/**
|
||||
* Convert a string to a ADC command escaped string.
|
||||
* @return adc command escaped string or NULL if out of memory.
|
||||
*/
|
||||
extern char* adc_msg_escape(const char* string);
|
||||
|
||||
/**
|
||||
* This will ensure a newline is at the end of the command.
|
||||
*/
|
||||
void adc_msg_terminate(struct adc_message* cmd);
|
||||
|
||||
/**
|
||||
* This will remove any newline from the end of the command
|
||||
*/
|
||||
void adc_msg_unterminate(struct adc_message* cmd);
|
||||
|
||||
/**
|
||||
* @return the offset for the first command argument in msg->cache.
|
||||
* or -1 if the command is not understood.
|
||||
* NOTE: for 'U' and 'C' commands (normally not seen by hubs),
|
||||
* this returns 4. Should be 4 + lengthOf(cid).
|
||||
*/
|
||||
int adc_msg_get_arg_offset(struct adc_message* msg);
|
||||
|
||||
#endif /* HAVE_UHUB_COMMAND_H */
|
||||
-155
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
|
||||
const char* BASE32_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
|
||||
char* sid_to_string(sid_t sid_)
|
||||
{
|
||||
static char t_sid[5];
|
||||
sid_t sid = (sid_ & 0xFFFFF); /* 20 bits only */
|
||||
sid_t A, B, C, D = 0;
|
||||
D = (sid % 32);
|
||||
sid = (sid - D) / 32;
|
||||
C = (sid % 32);
|
||||
sid = (sid - C) / 32;
|
||||
B = (sid % 32);
|
||||
sid = (sid - B) / 32;
|
||||
A = (sid % 32);
|
||||
t_sid[0] = BASE32_ALPHABET[A];
|
||||
t_sid[1] = BASE32_ALPHABET[B];
|
||||
t_sid[2] = BASE32_ALPHABET[C];
|
||||
t_sid[3] = BASE32_ALPHABET[D];
|
||||
t_sid[4] = 0;
|
||||
return t_sid;
|
||||
}
|
||||
|
||||
|
||||
sid_t string_to_sid(const char* sid)
|
||||
{
|
||||
sid_t nsid = 0;
|
||||
sid_t n, x;
|
||||
sid_t factors[] = { 32768, 1024, 32, 1};
|
||||
|
||||
if (!sid || strlen(sid) != 4) return 0;
|
||||
|
||||
for (n = 0; n < 4; n++) {
|
||||
for (x = 0; x < strlen(BASE32_ALPHABET); x++)
|
||||
if (sid[n] == BASE32_ALPHABET[x]) break;
|
||||
if (x == 32) return 0;
|
||||
nsid += x * factors[n];
|
||||
}
|
||||
return nsid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Session IDs are heavily reused, since they are a fairly scarce
|
||||
* resource. Only one (2^10)-1 exist, since it is a four byte base32-encoded
|
||||
* value and 'AAAA' (0) is reserved for the hub.
|
||||
*
|
||||
* Initialize with sid_initialize(), which sets min and max to one, and count to 0.
|
||||
*
|
||||
* When allocating a session ID:
|
||||
* - If 'count' is less than the pool size (max-min), then allocate within the pool
|
||||
* - Increase the pool size (see below)
|
||||
* - If unable to do that, hub is really full - don't let anyone in!
|
||||
*
|
||||
* When freeing a session ID:
|
||||
* - If the session ID being freed is 'max', then decrease the pool size by one.
|
||||
*
|
||||
*/
|
||||
|
||||
struct sid_pool
|
||||
{
|
||||
sid_t min;
|
||||
sid_t max;
|
||||
sid_t count;
|
||||
struct hub_user** map;
|
||||
};
|
||||
|
||||
|
||||
struct sid_pool* sid_pool_create(sid_t max)
|
||||
{
|
||||
struct sid_pool* pool = hub_malloc(sizeof(struct sid_pool));
|
||||
if (!pool)
|
||||
return 0;
|
||||
|
||||
pool->min = 1;
|
||||
pool->max = max + 1;
|
||||
pool->count = 0;
|
||||
pool->map = hub_malloc_zero(sizeof(struct hub_user*) * pool->max);
|
||||
if (!pool->map)
|
||||
{
|
||||
hub_free(pool);
|
||||
return 0;
|
||||
}
|
||||
pool->map[0] = (struct hub_user*) pool; /* hack to reserve the first sid. */
|
||||
|
||||
#ifdef DEBUG_SID
|
||||
LOG_DUMP("SID_POOL: max=%d", (int) pool->max);
|
||||
#endif
|
||||
return pool;
|
||||
}
|
||||
|
||||
void sid_pool_destroy(struct sid_pool* pool)
|
||||
{
|
||||
#ifdef DEBUG_SID
|
||||
LOG_DUMP("SID_POOL: destroying, current allocs=%d", (int) pool->count);
|
||||
#endif
|
||||
hub_free(pool->map);
|
||||
hub_free(pool);
|
||||
}
|
||||
|
||||
sid_t sid_alloc(struct sid_pool* pool, struct hub_user* user)
|
||||
{
|
||||
sid_t n;
|
||||
if (pool->count >= (pool->max - pool->min))
|
||||
{
|
||||
#ifdef DEBUG_SID
|
||||
LOG_DUMP("SID_POOL: alloc, sid pool is full.");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = (++pool->count);
|
||||
for (; (pool->map[n % pool->max]); n++) ;
|
||||
|
||||
#ifdef DEBUG_SID
|
||||
LOG_DUMP("SID_ALLOC: %d, user=%p", (int) n, user);
|
||||
#endif
|
||||
pool->map[n] = user;
|
||||
return n;
|
||||
}
|
||||
|
||||
void sid_free(struct sid_pool* pool, sid_t sid)
|
||||
{
|
||||
#ifdef DEBUG_SID
|
||||
LOG_DUMP("SID_FREE: %d", (int) sid);
|
||||
#endif
|
||||
pool->map[sid] = 0;
|
||||
pool->count--;
|
||||
}
|
||||
|
||||
struct hub_user* sid_lookup(struct sid_pool* pool, sid_t sid)
|
||||
{
|
||||
if (!sid || (sid >= pool->max))
|
||||
return 0;
|
||||
return pool->map[sid];
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_SID_H
|
||||
#define HAVE_UHUB_SID_H
|
||||
|
||||
#define SID_MAX 1048576
|
||||
|
||||
struct sid_pool;
|
||||
struct hub_user;
|
||||
|
||||
extern char* sid_to_string(sid_t sid_);
|
||||
extern sid_t string_to_sid(const char* sid);
|
||||
|
||||
extern struct sid_pool* sid_pool_create(sid_t max);
|
||||
extern void sid_pool_destroy(struct sid_pool*);
|
||||
|
||||
extern sid_t sid_alloc(struct sid_pool*, struct hub_user*);
|
||||
extern void sid_free(struct sid_pool*, sid_t);
|
||||
extern struct hub_user* sid_lookup(struct sid_pool*, sid_t);
|
||||
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_SID_H */
|
||||
|
||||
-497
@@ -1,497 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
|
||||
#define ACL_ADD_USER(S, L, V) do { ret = check_cmd_user(S, V, L, line, line_count); if (ret != 0) return ret; } while(0)
|
||||
#define ACL_ADD_BOOL(S, L) do { ret = check_cmd_bool(S, L, line, line_count); if (ret != 0) return ret; } while(0)
|
||||
#define ACL_ADD_ADDR(S, L) do { ret = check_cmd_addr(S, L, line, line_count); if (ret != 0) return ret; } while(0)
|
||||
|
||||
static int check_cmd_bool(const char* cmd, struct linked_list* list, char* line, int line_count)
|
||||
{
|
||||
char* data;
|
||||
|
||||
if (!strncmp(line, cmd, strlen(cmd)))
|
||||
{
|
||||
data = &line[strlen(cmd)];
|
||||
data[0] = '\0';
|
||||
data++;
|
||||
|
||||
data = strip_white_space(data);
|
||||
if (!*data)
|
||||
{
|
||||
LOG_FATAL("ACL parse error on line %d", line_count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
list_append(list, hub_strdup(data));
|
||||
LOG_DEBUG("ACL: Deny access for: '%s' (%s)", data, cmd);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_cmd_user(const char* cmd, int status, struct linked_list* list, char* line, int line_count)
|
||||
{
|
||||
char* data;
|
||||
char* data_extra;
|
||||
struct auth_info* info = 0;
|
||||
|
||||
if (!strncmp(line, cmd, strlen(cmd)))
|
||||
{
|
||||
data = &line[strlen(cmd)];
|
||||
data_extra = 0;
|
||||
data[0] = '\0';
|
||||
data++;
|
||||
|
||||
data = strip_white_space(data);
|
||||
if (!*data)
|
||||
{
|
||||
LOG_FATAL("ACL parse error on line %d", line_count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
info = hub_malloc_zero(sizeof(struct auth_info));
|
||||
|
||||
if (!info)
|
||||
{
|
||||
LOG_ERROR("ACL parse error. Out of memory!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strncmp(cmd, "user_", 5) == 0)
|
||||
{
|
||||
data_extra = strrchr(data, ':');
|
||||
if (data_extra)
|
||||
{
|
||||
data_extra[0] = 0;
|
||||
data_extra++;
|
||||
}
|
||||
}
|
||||
|
||||
strncpy(info->nickname, data, MAX_NICK_LEN);
|
||||
if (data_extra)
|
||||
strncpy(info->password, data_extra, MAX_PASS_LEN);
|
||||
info->credentials = status;
|
||||
list_append(list, info);
|
||||
LOG_DEBUG("ACL: Added user '%s' (%s)", info->nickname, auth_cred_to_string(info->credentials));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void add_ip_range(struct linked_list* list, struct ip_range* info)
|
||||
{
|
||||
char buf1[INET6_ADDRSTRLEN+1];
|
||||
char buf2[INET6_ADDRSTRLEN+1];
|
||||
|
||||
if (info->lo.af == AF_INET)
|
||||
{
|
||||
net_address_to_string(AF_INET, &info->lo.internal_ip_data.in.s_addr, buf1, INET6_ADDRSTRLEN);
|
||||
net_address_to_string(AF_INET, &info->hi.internal_ip_data.in.s_addr, buf2, INET6_ADDRSTRLEN);
|
||||
}
|
||||
else if (info->lo.af == AF_INET6)
|
||||
{
|
||||
net_address_to_string(AF_INET6, &info->lo.internal_ip_data.in6, buf1, INET6_ADDRSTRLEN);
|
||||
net_address_to_string(AF_INET6, &info->hi.internal_ip_data.in6, buf2, INET6_ADDRSTRLEN);
|
||||
}
|
||||
LOG_DEBUG("ACL: Added ip range: %s-%s", buf1, buf2);
|
||||
|
||||
list_append(list, info);
|
||||
}
|
||||
|
||||
|
||||
static int check_cmd_addr(const char* cmd, struct linked_list* list, char* line, int line_count)
|
||||
{
|
||||
char* data;
|
||||
struct ip_range* range = 0;
|
||||
|
||||
if (!strncmp(line, cmd, strlen(cmd)))
|
||||
{
|
||||
data = &line[strlen(cmd)];
|
||||
data[0] = '\0';
|
||||
data++;
|
||||
|
||||
data = strip_white_space(data);
|
||||
if (!*data)
|
||||
{
|
||||
LOG_FATAL("ACL parse error on line %d", line_count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
range = hub_malloc_zero(sizeof(struct ip_range));
|
||||
|
||||
if (!range)
|
||||
{
|
||||
LOG_ERROR("ACL parse error. Out of memory!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ip_convert_address_to_range(data, range))
|
||||
{
|
||||
add_ip_range(list, range);
|
||||
return 1;
|
||||
}
|
||||
hub_free(range);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int acl_parse_line(char* line, int line_count, void* ptr_data)
|
||||
{
|
||||
struct acl_handle* handle = (struct acl_handle*) ptr_data;
|
||||
int ret;
|
||||
|
||||
strip_off_ini_line_comments(line, line_count);
|
||||
|
||||
line = strip_white_space(line);
|
||||
if (!*line)
|
||||
return 0;
|
||||
|
||||
LOG_DEBUG("acl_parse_line: '%s'", line);
|
||||
|
||||
ACL_ADD_USER("bot", handle->users, auth_cred_bot);
|
||||
ACL_ADD_USER("user_admin", handle->users, auth_cred_admin);
|
||||
ACL_ADD_USER("user_super", handle->users, auth_cred_super);
|
||||
ACL_ADD_USER("user_op", handle->users, auth_cred_operator);
|
||||
ACL_ADD_USER("user_reg", handle->users, auth_cred_user);
|
||||
ACL_ADD_USER("link", handle->users, auth_cred_link);
|
||||
ACL_ADD_BOOL("deny_nick", handle->users_denied);
|
||||
ACL_ADD_BOOL("ban_nick", handle->users_banned);
|
||||
ACL_ADD_BOOL("ban_cid", handle->cids);
|
||||
ACL_ADD_ADDR("deny_ip", handle->networks);
|
||||
ACL_ADD_ADDR("nat_ip", handle->nat_override);
|
||||
|
||||
LOG_ERROR("Unknown ACL command on line %d: '%s'", line_count, line);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int acl_initialize(struct hub_config* config, struct acl_handle* handle)
|
||||
{
|
||||
int ret;
|
||||
memset(handle, 0, sizeof(struct acl_handle));
|
||||
|
||||
handle->users = list_create();
|
||||
handle->users_denied = list_create();
|
||||
handle->users_banned = list_create();
|
||||
handle->cids = list_create();
|
||||
handle->networks = list_create();
|
||||
handle->nat_override = list_create();
|
||||
|
||||
if (!handle->users || !handle->cids || !handle->networks || !handle->users_denied || !handle->users_banned || !handle->nat_override)
|
||||
{
|
||||
LOG_FATAL("acl_initialize: Out of memory");
|
||||
|
||||
list_destroy(handle->users);
|
||||
list_destroy(handle->users_denied);
|
||||
list_destroy(handle->users_banned);
|
||||
list_destroy(handle->cids);
|
||||
list_destroy(handle->networks);
|
||||
list_destroy(handle->nat_override);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (config)
|
||||
{
|
||||
if (!*config->file_acl) return 0;
|
||||
|
||||
ret = file_read_lines(config->file_acl, handle, &acl_parse_line);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void acl_free_access_info(void* ptr)
|
||||
{
|
||||
struct auth_info* info = (struct auth_info*) ptr;
|
||||
if (info)
|
||||
{
|
||||
hub_free(info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void acl_free_ip_info(void* ptr)
|
||||
{
|
||||
struct access_info* info = (struct access_info*) ptr;
|
||||
if (info)
|
||||
{
|
||||
hub_free(info);
|
||||
}
|
||||
}
|
||||
|
||||
int acl_shutdown(struct acl_handle* handle)
|
||||
{
|
||||
if (handle->users)
|
||||
{
|
||||
list_clear(handle->users, &acl_free_access_info);
|
||||
list_destroy(handle->users);
|
||||
}
|
||||
|
||||
if (handle->users_denied)
|
||||
{
|
||||
list_clear(handle->users_denied, &hub_free);
|
||||
list_destroy(handle->users_denied);
|
||||
}
|
||||
|
||||
if (handle->users_banned)
|
||||
{
|
||||
list_clear(handle->users_banned, &hub_free);
|
||||
list_destroy(handle->users_banned);
|
||||
}
|
||||
|
||||
|
||||
if (handle->cids)
|
||||
{
|
||||
list_clear(handle->cids, &hub_free);
|
||||
list_destroy(handle->cids);
|
||||
}
|
||||
|
||||
if (handle->networks)
|
||||
{
|
||||
list_clear(handle->networks, &acl_free_ip_info);
|
||||
list_destroy(handle->networks);
|
||||
}
|
||||
|
||||
if (handle->nat_override)
|
||||
{
|
||||
list_clear(handle->nat_override, &acl_free_ip_info);
|
||||
list_destroy(handle->nat_override);
|
||||
}
|
||||
|
||||
memset(handle, 0, sizeof(struct acl_handle));
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int acl_register_user(struct hub_info* hub, struct auth_info* info)
|
||||
{
|
||||
if (plugin_auth_register_user(hub, info) != st_allow)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern int acl_update_user(struct hub_info* hub, struct auth_info* info)
|
||||
{
|
||||
if (plugin_auth_update_user(hub, info) != st_allow)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern int acl_delete_user(struct hub_info* hub, const char* name)
|
||||
{
|
||||
struct auth_info data;
|
||||
strncpy(data.nickname, name, MAX_NICK_LEN);
|
||||
data.nickname[MAX_NICK_LEN] = '\0';
|
||||
data.password[0] = '\0';
|
||||
data.credentials = auth_cred_none;
|
||||
if (plugin_auth_delete_user(hub, &data) != st_allow)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct auth_info* acl_get_access_info(struct hub_info* hub, const char* name)
|
||||
{
|
||||
struct auth_info* info = 0;
|
||||
info = (struct auth_info*) hub_malloc(sizeof(struct auth_info));
|
||||
if (plugin_auth_get_user(hub, name, info) != st_allow)
|
||||
{
|
||||
hub_free(info);
|
||||
return NULL;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
#define STR_LIST_CONTAINS(LIST, STR) \
|
||||
str = (char*) list_get_first(LIST); \
|
||||
while (str) \
|
||||
{ \
|
||||
if (strcasecmp(str, STR) == 0) \
|
||||
return 1; \
|
||||
str = (char*) list_get_next(LIST); \
|
||||
} \
|
||||
return 0
|
||||
|
||||
int acl_is_cid_banned(struct acl_handle* handle, const char* data)
|
||||
{
|
||||
char* str;
|
||||
if (!handle) return 0;
|
||||
STR_LIST_CONTAINS(handle->cids, data);
|
||||
}
|
||||
|
||||
int acl_is_user_banned(struct acl_handle* handle, const char* data)
|
||||
{
|
||||
char* str;
|
||||
if (!handle) return 0;
|
||||
STR_LIST_CONTAINS(handle->users_banned, data);
|
||||
}
|
||||
|
||||
int acl_is_user_denied(struct acl_handle* handle, const char* data)
|
||||
{
|
||||
char* str;
|
||||
if (!handle) return 0;
|
||||
STR_LIST_CONTAINS(handle->users_denied, data);
|
||||
}
|
||||
|
||||
int acl_user_ban_nick(struct acl_handle* handle, const char* nick)
|
||||
{
|
||||
char* data = hub_strdup(nick);
|
||||
if (!data)
|
||||
{
|
||||
LOG_ERROR("ACL error: Out of memory!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
list_append(handle->users_banned, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acl_user_ban_cid(struct acl_handle* handle, const char* cid)
|
||||
{
|
||||
char* data = hub_strdup(cid);
|
||||
if (!data)
|
||||
{
|
||||
LOG_ERROR("ACL error: Out of memory!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
list_append(handle->cids, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acl_user_unban_nick(struct acl_handle* handle, const char* nick)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int acl_user_unban_cid(struct acl_handle* handle, const char* cid)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int acl_is_ip_banned(struct acl_handle* handle, const char* ip_address)
|
||||
{
|
||||
struct ip_addr_encap raw;
|
||||
struct ip_range* info = (struct ip_range*) list_get_first(handle->networks);
|
||||
ip_convert_to_binary(ip_address, &raw);
|
||||
|
||||
while (info)
|
||||
{
|
||||
if (ip_in_range(&raw, info))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
info = (struct ip_range*) list_get_next(handle->networks);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address)
|
||||
{
|
||||
struct ip_addr_encap raw;
|
||||
struct ip_range* info = (struct ip_range*) list_get_first(handle->nat_override);
|
||||
ip_convert_to_binary(ip_address, &raw);
|
||||
|
||||
while (info)
|
||||
{
|
||||
if (ip_in_range(&raw, info))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
info = (struct ip_range*) list_get_next(handle->nat_override);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This will generate the same challenge to the same user, always.
|
||||
* The challenge is made up of the time of the user connected
|
||||
* seconds since the unix epoch (modulus 1 million)
|
||||
* and the SID of the user (0-1 million).
|
||||
*/
|
||||
const char* acl_password_generate_challenge(struct hub_info* hub, struct hub_user* user)
|
||||
{
|
||||
char buf[64];
|
||||
uint64_t tiger_res[3];
|
||||
static char tiger_buf[MAX_CID_LEN+1];
|
||||
|
||||
// FIXME: Generate a better nonce scheme.
|
||||
snprintf(buf, 64, "%p%d%d", user, (int) user->id.sid, (int) net_con_get_sd(user->connection));
|
||||
|
||||
tiger((uint64_t*) buf, strlen(buf), (uint64_t*) tiger_res);
|
||||
base32_encode((unsigned char*) tiger_res, TIGERSIZE, tiger_buf);
|
||||
tiger_buf[MAX_CID_LEN] = 0;
|
||||
return (const char*) tiger_buf;
|
||||
}
|
||||
|
||||
|
||||
int acl_password_verify(struct hub_info* hub, struct hub_user* user, const char* password)
|
||||
{
|
||||
char buf[1024];
|
||||
struct auth_info* access;
|
||||
const char* challenge;
|
||||
char raw_challenge[64];
|
||||
char password_calc[64];
|
||||
uint64_t tiger_res[3];
|
||||
size_t password_len;
|
||||
|
||||
if (!password || !user || strlen(password) != MAX_CID_LEN)
|
||||
return 0;
|
||||
|
||||
access = acl_get_access_info(hub, user->id.nick);
|
||||
if (!access)
|
||||
return 0;
|
||||
|
||||
challenge = acl_password_generate_challenge(hub, user);
|
||||
|
||||
base32_decode(challenge, (unsigned char*) raw_challenge, MAX_CID_LEN);
|
||||
|
||||
password_len = strlen(access->password);
|
||||
|
||||
memcpy(&buf[0], access->password, password_len);
|
||||
memcpy(&buf[password_len], raw_challenge, TIGERSIZE);
|
||||
|
||||
tiger((uint64_t*) buf, TIGERSIZE+password_len, (uint64_t*) tiger_res);
|
||||
base32_encode((unsigned char*) tiger_res, TIGERSIZE, password_calc);
|
||||
password_calc[MAX_CID_LEN] = 0;
|
||||
|
||||
hub_free(access);
|
||||
|
||||
if (strcasecmp(password, password_calc) == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_ACL_H
|
||||
#define HAVE_UHUB_ACL_H
|
||||
|
||||
struct hub_config;
|
||||
struct hub_info;
|
||||
struct hub_user;
|
||||
struct ip_addr_encap;
|
||||
|
||||
struct acl_handle
|
||||
{
|
||||
struct linked_list* users; /* Known users. See enum user_status */
|
||||
struct linked_list* cids; /* Known CIDs */
|
||||
struct linked_list* networks; /* IP ranges, used for banning */
|
||||
struct linked_list* nat_override; /* IPs inside these ranges can provide their false IP. Use with care! */
|
||||
struct linked_list* users_banned; /* Users permanently banned */
|
||||
struct linked_list* users_denied; /* bad nickname */
|
||||
};
|
||||
|
||||
|
||||
extern int acl_initialize(struct hub_config* config, struct acl_handle* handle);
|
||||
extern int acl_shutdown(struct acl_handle* handle);
|
||||
|
||||
extern struct auth_info* acl_get_access_info(struct hub_info* hub, const char* name);
|
||||
extern int acl_register_user(struct hub_info* hub, struct auth_info* info);
|
||||
extern int acl_update_user(struct hub_info* hub, struct auth_info* info);
|
||||
extern int acl_delete_user(struct hub_info* hub, const char* name);
|
||||
|
||||
|
||||
extern int acl_is_cid_banned(struct acl_handle* handle, const char* cid);
|
||||
extern int acl_is_ip_banned(struct acl_handle* handle, const char* ip_address);
|
||||
extern int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address);
|
||||
|
||||
extern int acl_is_user_banned(struct acl_handle* handle, const char* name);
|
||||
extern int acl_is_user_denied(struct acl_handle* handle, const char* name);
|
||||
|
||||
extern int acl_user_ban_nick(struct acl_handle* handle, const char* nick);
|
||||
extern int acl_user_ban_cid(struct acl_handle* handle, const char* cid);
|
||||
extern int acl_user_unban_nick(struct acl_handle* handle, const char* nick);
|
||||
extern int acl_user_unban_cid(struct acl_handle* handle, const char* cid);
|
||||
|
||||
/**
|
||||
* Verify a password.
|
||||
*
|
||||
* @param password the hashed password (based on the nonce).
|
||||
* @return 1 if the password matches, or 0 if the password is incorrect.
|
||||
*/
|
||||
extern int acl_password_verify(struct hub_info* hub, struct hub_user* user, const char* password);
|
||||
extern const char* acl_password_generate_challenge(struct hub_info* hub, struct hub_user* user);
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_ACL_H */
|
||||
-1004
File diff suppressed because it is too large
Load Diff
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_COMMANDS_H
|
||||
#define HAVE_UHUB_COMMANDS_H
|
||||
|
||||
struct command_base;
|
||||
struct command_handle;
|
||||
struct hub_command;
|
||||
|
||||
typedef int (*command_handler)(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd);
|
||||
|
||||
enum command_parse_status
|
||||
{
|
||||
cmd_status_ok, /** <<< "Everything seems to OK" */
|
||||
cmd_status_not_found, /** <<< "Command was not found" */
|
||||
cmd_status_access_error, /** <<< "You don't have access to this command" */
|
||||
cmd_status_syntax_error, /** <<< "Not a valid command." */
|
||||
cmd_status_missing_args, /** <<< "Missing some or all required arguments." */
|
||||
cmd_status_arg_nick, /** <<< "A nick argument does not match an online user. ('n')" */
|
||||
cmd_status_arg_cid, /** <<< "A cid argument does not match an online user. ('i')." */
|
||||
cmd_status_arg_address, /** <<< "A address range argument is not valid ('a')." */
|
||||
cmd_status_arg_number, /** <<< "A number argument is not valid ('N')" */
|
||||
cmd_status_arg_cred, /** <<< "A credentials argument is not valid ('C')" */
|
||||
cmd_status_arg_command, /** <<< "A command argument is not valid ('c')" */
|
||||
};
|
||||
|
||||
struct hub_command_arg_data
|
||||
{
|
||||
enum Type {
|
||||
type_integer,
|
||||
type_string,
|
||||
type_user,
|
||||
type_address,
|
||||
type_range,
|
||||
type_credentials,
|
||||
type_command
|
||||
} type;
|
||||
|
||||
union {
|
||||
int integer;
|
||||
char* string;
|
||||
struct hub_user* user;
|
||||
struct ip_addr_encap* address;
|
||||
struct ip_range* range;
|
||||
enum auth_credentials credentials;
|
||||
struct command_handle* command;
|
||||
} data;
|
||||
|
||||
struct hub_command_arg_data* next;
|
||||
};
|
||||
|
||||
void hub_command_args_free(struct hub_command* command);
|
||||
|
||||
/**
|
||||
* This struct contains all information needed to invoke
|
||||
* a command, which includes the whole message, the prefix,
|
||||
* the decoded arguments (according to parameter list), and
|
||||
* the user pointer (ptr) which comes from the command it was matched to.
|
||||
*
|
||||
* The message and prefix is generally always available, but args only
|
||||
* if status == cmd_status_ok.
|
||||
* Handler and ptr are NULL if status == cmd_status_not_found, or status == cmd_status_access_error.
|
||||
* Ptr might also be NULL if cmd_status_ok because the command that handles it was added with a NULL ptr.
|
||||
*/
|
||||
struct hub_command
|
||||
{
|
||||
const char* message; /**<<< "The complete message." */
|
||||
char* prefix; /**<<< "The prefix extracted from the message." */
|
||||
struct linked_list* args; /**<<< "List of all parsed arguments from the message. Type depends on expectations." */
|
||||
enum command_parse_status status; /**<<< "Status of the hub_command." */
|
||||
command_handler handler; /**<<< "The function handler to call in order to invoke this command." */
|
||||
const struct hub_user* user; /**<<< "The user who invoked this command." */
|
||||
void* ptr; /**<<< "A pointer of data which came from struct command_handler" */
|
||||
};
|
||||
|
||||
/**
|
||||
* Argument codes are used to automatically parse arguments
|
||||
* for a a hub command.
|
||||
*
|
||||
* n = nick name (must exist in hub session)
|
||||
* i = CID (must exist in hub)
|
||||
* a = (IP) address (must be a valid IPv4 or IPv6 address)
|
||||
* r = (IP) address range (either: IP-IP or IP/mask, both IPv4 or IPv6 work)
|
||||
* m = message (string)
|
||||
* p = password (string)
|
||||
* C = credentials (see auth_string_to_cred).
|
||||
* c = command (name of command)
|
||||
* N = number (integer)
|
||||
*
|
||||
* Prefix an argument with ? to make it optional.
|
||||
* NOTE; if an argument is optional then all following arguments must also be optional.
|
||||
*
|
||||
* Example:
|
||||
* "nia" means "nick cid ip"
|
||||
* "n?p" means "nick [password]" where password is optional.
|
||||
*
|
||||
*/
|
||||
struct command_handle
|
||||
{
|
||||
const char* prefix; /**<<< "Command prefix, for instance 'help' would be the prefix for the !help command." */
|
||||
size_t length; /**<<< "Length of the prefix" */
|
||||
const char* args; /**<<< "Argument codes (see above)" */
|
||||
enum auth_credentials cred; /**<<< "Minimum access level for the command" */
|
||||
command_handler handler; /**<<< "Function pointer for the command" */
|
||||
const char* description; /**<<< "Description for the command" */
|
||||
const char* origin; /**<<< "Name of module where the command is implemented." */
|
||||
void* ptr; /**<<< "A pointer which will be passed along to the handler. @See hub_command::ptr" */
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns NULL on error, or handle
|
||||
*/
|
||||
extern struct command_base* command_initialize(struct hub_info* hub);
|
||||
extern void command_shutdown(struct command_base* cbase);
|
||||
|
||||
/**
|
||||
* Add a new command to the command base.
|
||||
* Returns 1 on success, or 0 on error.
|
||||
*/
|
||||
extern int command_add(struct command_base*, struct command_handle*, void* ptr);
|
||||
|
||||
/**
|
||||
* Remove a command from the command base.
|
||||
* Returns 1 on success, or 0 on error.
|
||||
*/
|
||||
extern int command_del(struct command_base*, struct command_handle*);
|
||||
|
||||
/**
|
||||
* Dispatch a message and forward it as a command.
|
||||
* Returns 1 if the message should be forwarded as a chat message, or 0 if
|
||||
* it is supposed to be handled internally in the dispatcher.
|
||||
*
|
||||
* This will break the message down into a struct hub_command and invoke the command handler
|
||||
* for that command if the sufficient access credentials are met.
|
||||
*/
|
||||
extern int command_invoke(struct command_base*, struct hub_user* user, const char* message);
|
||||
|
||||
/**
|
||||
* Parse a message as a command and return a status indicating if the command
|
||||
* is valid and that the arguments are sane.
|
||||
*
|
||||
* @param cbase Command base pointer.
|
||||
* @param user User who invoked the command.
|
||||
* @param message The message that is to be interpreted as a command (including the invokation prefix '!' or '+')
|
||||
*
|
||||
* @return a hub_command that must be freed with command_free(). @See struct hub_command.
|
||||
*/
|
||||
extern struct hub_command* command_parse(struct command_base* cbase, const struct hub_user* user, const char* message);
|
||||
|
||||
/**
|
||||
* Free a hub_command that was created in command_parse().
|
||||
*/
|
||||
extern void command_free(struct hub_command* command);
|
||||
|
||||
|
||||
extern void commands_builtin_add(struct command_base*);
|
||||
extern void commands_builtin_remove(struct command_base*);
|
||||
|
||||
#endif /* HAVE_UHUB_COMMANDS_H */
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "uhub.h"
|
||||
|
||||
|
||||
#ifndef INT_MAX
|
||||
#define INT_MAX 0x7fffffff
|
||||
#endif
|
||||
|
||||
#ifndef INT_MIN
|
||||
#define INT_MIN (-0x7fffffff - 1)
|
||||
#endif
|
||||
|
||||
static int apply_boolean(const char* key, const char* data, int* target)
|
||||
{
|
||||
return string_to_boolean(data, target);
|
||||
}
|
||||
|
||||
static int apply_string(const char* key, const char* data, char** target, char* regexp)
|
||||
{
|
||||
(void) regexp;
|
||||
// FIXME: Add regexp checks for correct data
|
||||
|
||||
if (*target)
|
||||
hub_free(*target);
|
||||
|
||||
*target = hub_strdup(data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int apply_integer(const char* key, const char* data, int* target, int* min, int* max)
|
||||
{
|
||||
char* endptr;
|
||||
int val;
|
||||
errno = 0;
|
||||
val = strtol(data, &endptr, 10);
|
||||
|
||||
if (((errno == ERANGE && (val == INT_MAX || val == INT_MIN)) || (errno != 0 && val == 0)) || endptr == data)
|
||||
return 0;
|
||||
|
||||
if (min && val < *min)
|
||||
return 0;
|
||||
|
||||
if (max && val > *max)
|
||||
return 0;
|
||||
|
||||
*target = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include "gen_config.c"
|
||||
|
||||
static int config_parse_line(char* line, int line_count, void* ptr_data)
|
||||
{
|
||||
char* pos;
|
||||
char* key;
|
||||
char* data;
|
||||
struct hub_config* config = (struct hub_config*) ptr_data;
|
||||
|
||||
strip_off_ini_line_comments(line, line_count);
|
||||
|
||||
if (!*line) return 0;
|
||||
|
||||
LOG_DUMP("config_parse_line(): '%s'", line);
|
||||
|
||||
if (!is_valid_utf8(line))
|
||||
{
|
||||
LOG_WARN("Invalid utf-8 characters on line %d", line_count);
|
||||
}
|
||||
|
||||
if ((pos = strchr(line, '=')) != NULL)
|
||||
{
|
||||
pos[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
key = line;
|
||||
data = &pos[1];
|
||||
|
||||
key = strip_white_space(key);
|
||||
data = strip_white_space(data);
|
||||
data = strip_off_quotes(data);
|
||||
|
||||
if (!*key || !*data)
|
||||
{
|
||||
LOG_FATAL("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_DUMP("config_parse_line: '%s' => '%s'", key, data);
|
||||
|
||||
return apply_config(config, key, data, line_count);
|
||||
}
|
||||
|
||||
|
||||
int read_config(const char* file, struct hub_config* config, int allow_missing)
|
||||
{
|
||||
int ret;
|
||||
|
||||
memset(config, 0, sizeof(struct hub_config));
|
||||
config_defaults(config);
|
||||
|
||||
ret = file_read_lines(file, config, &config_parse_line);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (allow_missing && ret == -2)
|
||||
{
|
||||
LOG_DUMP("Using default configuration.");
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_CONFIG_H
|
||||
#define HAVE_UHUB_CONFIG_H
|
||||
|
||||
#include "gen_config.h"
|
||||
|
||||
/**
|
||||
* This initializes the configuration variables, and sets the default
|
||||
* variables.
|
||||
*
|
||||
* NOTE: Any variable is set to it's default variable if zero.
|
||||
* This function is automatically called in read_config to set any
|
||||
* configuration that was missing there.
|
||||
*/
|
||||
extern void config_defaults(struct hub_config* config);
|
||||
|
||||
/**
|
||||
* Read configuration from file, and use the default variables for
|
||||
* the missing variables.
|
||||
*
|
||||
* @return -1 on error, 0 on success.
|
||||
*/
|
||||
extern int read_config(const char* file, struct hub_config* config, int allow_missing);
|
||||
|
||||
/**
|
||||
* Free the configuration data (allocated by read_config, or config_defaults).
|
||||
*/
|
||||
extern void free_config(struct hub_config* config);
|
||||
|
||||
/**
|
||||
* Print all configuration data to standard out.
|
||||
*/
|
||||
extern void dump_config(struct hub_config* config, int ignore_defaults);
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_CONFIG_H */
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use strict;
|
||||
use XML::Twig;
|
||||
|
||||
sub write_c_header(@);
|
||||
sub write_c_impl_defaults(@);
|
||||
sub write_c_impl_apply(@);
|
||||
sub write_c_impl_free(@);
|
||||
sub write_c_impl_dump(@);
|
||||
sub get_data($);
|
||||
|
||||
# initialize parser and read the file
|
||||
my $input = "./config.xml";
|
||||
my $parser = XML::Twig->new();
|
||||
my $tree = $parser->parsefile($input) || die "Unable to parse XML file.";
|
||||
|
||||
# Write header file
|
||||
open GENHEAD, ">gen_config.h" || die "Unable to write header file";
|
||||
print GENHEAD "/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */\n\nstruct hub_config\n{\n";
|
||||
foreach my $p ($tree->root->children("option"))
|
||||
{
|
||||
write_c_header(get_data($p));
|
||||
}
|
||||
print GENHEAD "};\n\n";
|
||||
|
||||
# Write c source file
|
||||
open GENIMPL, ">gen_config.c" || die "Unable to write source file";
|
||||
print GENIMPL "/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */\n\n";
|
||||
|
||||
# The defaults function
|
||||
print GENIMPL "void config_defaults(struct hub_config* config)\n{\n";
|
||||
foreach my $p ($tree->root->children("option"))
|
||||
{
|
||||
write_c_impl_defaults(get_data($p));
|
||||
}
|
||||
print GENIMPL "}\n\n";
|
||||
|
||||
# apply function
|
||||
print GENIMPL "static int apply_config(struct hub_config* config, char* key, char* data, int line_count)\n{\n\tint max = 0;\n\tint min = 0;\n\n";
|
||||
|
||||
foreach my $p ($tree->root->children("option"))
|
||||
{
|
||||
write_c_impl_apply(get_data($p));
|
||||
}
|
||||
print GENIMPL "\t/* Still here -- unknown directive */\n";
|
||||
print GENIMPL "\tLOG_ERROR(\"Unknown configuration directive: '%s'\", key);\n";
|
||||
print GENIMPL "\t\treturn -1;\n";
|
||||
print GENIMPL "}\n\n";
|
||||
|
||||
# free function (for strings)
|
||||
print GENIMPL "void free_config(struct hub_config* config)\n{\n";
|
||||
foreach my $p ($tree->root->children("option"))
|
||||
{
|
||||
write_c_impl_free(get_data($p));
|
||||
}
|
||||
print GENIMPL "}\n\n";
|
||||
|
||||
# dump function
|
||||
print GENIMPL "void dump_config(struct hub_config* config, int ignore_defaults)\n{\n";
|
||||
foreach my $p ($tree->root->children("option"))
|
||||
{
|
||||
write_c_impl_dump(get_data($p));
|
||||
}
|
||||
print GENIMPL "}\n\n";
|
||||
|
||||
|
||||
|
||||
sub write_c_header(@)
|
||||
{
|
||||
my @output = @_;
|
||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
|
||||
|
||||
print GENHEAD "\t";
|
||||
print GENHEAD "int " if ($type eq "int");
|
||||
print GENHEAD "int " if ($type eq "boolean");
|
||||
print GENHEAD "char*" if ($type =~ /(string|file|message)/);
|
||||
print GENHEAD " " . $name . ";";
|
||||
|
||||
my $comment = "";
|
||||
if ($type eq "message")
|
||||
{
|
||||
$comment = "\"" . $default . "\"";
|
||||
}
|
||||
elsif (defined $short && length $short > 0)
|
||||
{
|
||||
$comment = $short;
|
||||
$comment .= " (default: " . $default . ")" if (defined $default);
|
||||
}
|
||||
|
||||
if (length $comment > 0)
|
||||
{
|
||||
my $pad = "";
|
||||
for (my $i = length $name; $i < 32; $i++)
|
||||
{
|
||||
$pad .= " ";
|
||||
}
|
||||
$comment = $pad . "/*<<< " . $comment . " */";
|
||||
}
|
||||
|
||||
print GENHEAD $comment . "\n";
|
||||
}
|
||||
|
||||
sub write_c_impl_defaults(@)
|
||||
{
|
||||
my @output = @_;
|
||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
|
||||
my $prefix = "";
|
||||
my $suffix = "";
|
||||
|
||||
print GENIMPL "\tconfig->$name = ";
|
||||
if ($type =~ /(string|file|message)/)
|
||||
{
|
||||
$prefix = "hub_strdup(\"";
|
||||
$suffix = "\")"
|
||||
}
|
||||
print GENIMPL $prefix . $default . $suffix . ";\n";
|
||||
}
|
||||
|
||||
sub write_c_impl_apply(@)
|
||||
{
|
||||
my @output = @_;
|
||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $p) = @output;
|
||||
|
||||
my $min;
|
||||
my $max;
|
||||
my $regexp;
|
||||
|
||||
if (defined $p)
|
||||
{
|
||||
$min = $p->att("min");
|
||||
$max = $p->att("max");
|
||||
$regexp = $p->att("regexp");
|
||||
|
||||
print "'check' is defined for option $name";
|
||||
print ", min=$min" if (defined $min);
|
||||
print ", max=$max" if (defined $max);
|
||||
print ", regexp=\"$regexp\"" if (defined $regexp);
|
||||
print "\n";
|
||||
}
|
||||
|
||||
print GENIMPL "\tif (!strcmp(key, \"" . $name . "\"))\n\t{\n";
|
||||
|
||||
if ($type eq "int")
|
||||
{
|
||||
if (defined $min)
|
||||
{
|
||||
print GENIMPL "\t\tmin = $min;\n"
|
||||
}
|
||||
if (defined $max)
|
||||
{
|
||||
print GENIMPL "\t\tmax = $max;\n"
|
||||
}
|
||||
|
||||
print GENIMPL "\t\tif (!apply_integer(key, data, &config->$name, ";
|
||||
|
||||
if (defined $min)
|
||||
{
|
||||
print GENIMPL "&min";
|
||||
}
|
||||
else
|
||||
{
|
||||
print GENIMPL "0";
|
||||
}
|
||||
|
||||
print GENIMPL ", ";
|
||||
|
||||
if (defined $max)
|
||||
{
|
||||
print GENIMPL "&max";
|
||||
}
|
||||
else
|
||||
{
|
||||
print GENIMPL "0";
|
||||
}
|
||||
|
||||
print GENIMPL "))\n";
|
||||
}
|
||||
elsif ($type eq "boolean")
|
||||
{
|
||||
print GENIMPL "\t\tif (!apply_boolean(key, data, &config->$name))\n";
|
||||
}
|
||||
elsif ($type =~ /(string|file|message)/)
|
||||
{
|
||||
print GENIMPL "\t\tif (!apply_string(key, data, &config->$name, (char*) \"\"))\n";
|
||||
}
|
||||
|
||||
print GENIMPL "\t\t{\n" .
|
||||
"\t\t\tLOG_ERROR(\"Configuration parse error on line %d\", line_count);\n" .
|
||||
"\t\t\treturn -1;\n" .
|
||||
"\t\t}\n" .
|
||||
"\t\treturn 0;\n" .
|
||||
"\t}\n\n";
|
||||
}
|
||||
|
||||
sub write_c_impl_free(@)
|
||||
{
|
||||
my @output = @_;
|
||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
|
||||
|
||||
if ($type =~ /(string|file|message)/)
|
||||
{
|
||||
print GENIMPL "\thub_free(config->" . $name . ");\n\n"
|
||||
}
|
||||
}
|
||||
|
||||
sub write_c_impl_dump(@)
|
||||
{
|
||||
my @output = @_;
|
||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
|
||||
my $out;
|
||||
my $val = "config->$name";
|
||||
my $test = "config->$name != $default";
|
||||
|
||||
if ($type eq "int")
|
||||
{
|
||||
$out = "%d";
|
||||
}
|
||||
elsif ($type eq "boolean")
|
||||
{
|
||||
$out = "%s";
|
||||
$val = "config->$name ? \"yes\" : \"no\"";
|
||||
}
|
||||
elsif ($type =~ /(string|file|message)/)
|
||||
{
|
||||
$out = "\\\"%s\\\"";
|
||||
$test = "strcmp(config->$name, \"$default\") != 0";
|
||||
}
|
||||
|
||||
print GENIMPL "\tif (!ignore_defaults || $test)\n";
|
||||
print GENIMPL "\t\tfprintf(stdout, \"$name = $out\\n\", $val);\n\n";
|
||||
}
|
||||
|
||||
sub get_data($)
|
||||
{
|
||||
my $p = shift;
|
||||
my $check = $p->first_child_matches("check");
|
||||
my @data = ($p->att("type"), $p->att("name"), $p->att("default"), $p->att("advanced"), $p->children_text("short"), $p->children_text("description"), $p->children_text("since"), $p->children_text("example"), $check);
|
||||
return @data;
|
||||
}
|
||||
|
||||
@@ -1,662 +0,0 @@
|
||||
<?xml version='1.0' standalone="yes" ?>
|
||||
<config>
|
||||
|
||||
<option name="hub_enabled" type="boolean" default="1">
|
||||
<short>Is server enabled</short>
|
||||
<description><![CDATA[
|
||||
Use this to disable the hub for a while.
|
||||
]]></description>
|
||||
<since>0.1.3</since>
|
||||
</option>
|
||||
|
||||
<option name="server_port" type="int" default="1511">
|
||||
<check min="1" max="65535" />
|
||||
<since>0.1.0</since>
|
||||
<short>Server port to bind to</short>
|
||||
<description><![CDATA[This is specifies the port number the hub should listen on.]]></description>
|
||||
</option>
|
||||
|
||||
<option name="server_bind_addr" type="string" default="any">
|
||||
<check regexp="(\d\.\d\.\d\.\d\)|(any)|(loopback)|(.*)" /><!-- FIXME: add better IPv6 regexp in the future! -->
|
||||
<short>Server bind address</short>
|
||||
<description><![CDATA[
|
||||
Specify the IP address the local hub should bind to. This can be an IPv4 or IPv6 address, or one of the special addresses "any" or "loopback". <br />
|
||||
When "any" or "loopback" is used, the hub will automatically detect if IPv6 is supported and prefer that.
|
||||
]]></description>
|
||||
<syntax>
|
||||
IPv4 address, IPv6 address, "any" or "loopback"
|
||||
</syntax>
|
||||
<since>0.1.2</since>
|
||||
<example><![CDATA[
|
||||
<p>
|
||||
To listen to a specific IP:<br />
|
||||
server_bind_addr = "192.168.12.69"
|
||||
</p>
|
||||
<p>
|
||||
To listen to any IPv4 address:<br />
|
||||
server_bind_addr = "0.0.0.0"
|
||||
</p>
|
||||
<p>
|
||||
Or to listen to any address including IPv6 (if supported):<br />
|
||||
server_bind_addr = "any"
|
||||
</p>
|
||||
]]></example>
|
||||
</option>
|
||||
|
||||
<option name="server_listen_backlog" type="int" default="50">
|
||||
<check min="5" />
|
||||
<short>Server listen backlog</short>
|
||||
<description><![CDATA[
|
||||
<p>
|
||||
This specifies the number of connections the hub will be able to accept in the backlog before they must be processed by the hub.
|
||||
</p>
|
||||
<p>
|
||||
A too low number here will mean the hub will not accept connections fast enough when users are reconnecting really fast. The hub should under normal circumstances be able to empty the listen backlog several times per second.
|
||||
</p>
|
||||
]]></description>
|
||||
<since>0.3.0</since>
|
||||
</option>
|
||||
|
||||
<option name="server_alt_ports" type="string" default="">
|
||||
<check regexp="((\d+)(,(\d+))*)?" />
|
||||
<short>Comma separated list of alternative ports to listen to</short>
|
||||
<description><![CDATA[
|
||||
In addition to the server_port the hub can listen to a list of alternative ports.
|
||||
]]></description>
|
||||
<example><![CDATA[
|
||||
server_alt_ports = 1295,1512,53990
|
||||
]]></example>
|
||||
<since>0.3.0</since>
|
||||
</option>
|
||||
|
||||
<option name="show_banner" type="boolean" default="1">
|
||||
<short>Show banner on connect</short>
|
||||
<description><![CDATA[
|
||||
If enabled, the hub will announce the software version running to clients when they connect with a message like: "Powered by uhub/0.x.y"
|
||||
]]></description>
|
||||
<since>0.1.0</since>
|
||||
</option>
|
||||
|
||||
<option name="show_banner_sys_info" type="boolean" default="1">
|
||||
<short>Show banner on connect</short>
|
||||
<description><![CDATA[
|
||||
If enabled, the hub will announce the operating system and CPU architecture to clients when they join.<br />
|
||||
This option has no effect if show_banner is disabled.
|
||||
]]></description>
|
||||
<since>0.3.0</since>
|
||||
</option>
|
||||
|
||||
<option name="max_users" type="int" default="500">
|
||||
<check min="1" max="1048576" />
|
||||
<short>Maximum number of users allowed on the hub</short>
|
||||
<description><![CDATA[
|
||||
The maximum amount of users allowed on the hub.
|
||||
No new users will be allowed to enter the hub if this number is exceeded, however privileged users (operators, admins, etc) are still able to log in.
|
||||
]]></description>
|
||||
<since>0.1.0</since>
|
||||
<example><![CDATA[
|
||||
To run a hub for max 25 users:<br />
|
||||
max_users = 25
|
||||
]]></example>
|
||||
</option>
|
||||
|
||||
<option name="registered_users_only" type="boolean" default="0">
|
||||
<short>Allow registered users only</short>
|
||||
<description><![CDATA[
|
||||
If this is enabled only registered users will be able to use the hub. A user must be registered in the acl file (file_acl).
|
||||
]]></description>
|
||||
<since>0.1.1</since>
|
||||
</option>
|
||||
|
||||
<option name="register_self" type="boolean" default="0">
|
||||
<short>Allow users to register themselves on the hub.</short>
|
||||
<description><![CDATA[
|
||||
If this is enabled guests can register their nickname on the hub.
|
||||
Otherwise only operators can register users.
|
||||
]]></description>
|
||||
<since>0.4.0</since>
|
||||
</option>
|
||||
|
||||
<option name="obsolete_clients" type="boolean" default="0">
|
||||
<short>Support obsolete clients using a ADC protocol prior to 1.0</short>
|
||||
<description><![CDATA[
|
||||
If this is enabled users using old ADC clients are allowed to enter the hub,
|
||||
however they cannot log in using passwords since the protocols are incompatible.
|
||||
]]></description>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
<option name="chat_is_privileged" type="boolean" default="0">
|
||||
<short>Allow chat for operators and above only</short>
|
||||
<description><![CDATA[
|
||||
If enabled only operators and admins are allowed to chat in the main chat.
|
||||
]]></description>
|
||||
<since>0.2.4</since>
|
||||
</option>
|
||||
|
||||
<option name="hub_name" type="string" default="uhub">
|
||||
<short>Name of hub</short>
|
||||
<description><![CDATA[
|
||||
Configures the name of the hub
|
||||
]]></description>
|
||||
<since>0.1.0</since>
|
||||
<example><![CDATA[
|
||||
hub_name = "my hub"
|
||||
]]></example>
|
||||
</option>
|
||||
|
||||
<option name="hub_description" type="string" default="no description">
|
||||
<short>Short hub description, topic or subject.</short>
|
||||
<description><![CDATA[
|
||||
This is the description of the hub, as seen by users and hub lists.
|
||||
]]></description>
|
||||
<since>0.1.0</since>
|
||||
<example><![CDATA[
|
||||
hub_description = "a friendly hub for friendly people"
|
||||
]]></example>
|
||||
</option>
|
||||
|
||||
<option name="redirect_addr" type="string" default="">
|
||||
<check regexp="(adc|adcs|dchub)://.*" />
|
||||
<short>A common hub redirect address.</short>
|
||||
<description><![CDATA[
|
||||
This is the redirect address used when the hub wants to redirect a client for not fulfilling some requirements.
|
||||
]]></description>
|
||||
<since>0.3.2</since>
|
||||
</option>
|
||||
|
||||
|
||||
<option name="max_recv_buffer" type="int" default="4096" advanced="true" >
|
||||
<check min="1024" max="1048576" />
|
||||
<short>Max read buffer before parse, per user</short>
|
||||
<description><![CDATA[
|
||||
Maximum receive buffer allowed before commands are procesed. If a single ADC message exceeds this limit, it will be discarded by the hub. Use with caution.
|
||||
]]></description>
|
||||
<since>0.1.3</since>
|
||||
</option>
|
||||
|
||||
<option name="max_send_buffer" type="int" default="131072" advanced="true" >
|
||||
<check min="2048" />
|
||||
<short>Max send buffer before disconnect, per user</short>
|
||||
<description><![CDATA[
|
||||
Maximum amount of bytes allowed to be queued for sending to any particular user before the hub will disconnect the user. The lower the limit, the more aggressive the hub will be to disconnect slow clients. Use with caution.
|
||||
]]></description>
|
||||
<since>0.1.3</since>
|
||||
</option>
|
||||
|
||||
<option name="max_send_buffer_soft" type="int" default="98304" advanced="true" >
|
||||
<check min="1024" />
|
||||
<short>Max send buffer before message drops, per user</short>
|
||||
<description><![CDATA[
|
||||
Same as max_send_buffer, however low priority messages may be discarded if this limit is reached. Use with caution.
|
||||
]]></description>
|
||||
<since>0.1.3</since>
|
||||
</option>
|
||||
|
||||
<option name="low_bandwidth_mode" type="boolean" default="0" advanced="true" >
|
||||
<short>Enable bandwidth saving measures</short>
|
||||
<description><![CDATA[
|
||||
If this is enabled the hub will remove excessive information from each user's info message before broadcasting to all connected users.
|
||||
Description, e-mail address will be removed. This saves upload bandwidth for the hub.
|
||||
]]></description>
|
||||
<since>0.2.2</since>
|
||||
</option>
|
||||
|
||||
<option name="max_chat_history" type="int" default="20">
|
||||
<check min="0" max="250" />
|
||||
<short>Number of chat messages kept in history</short>
|
||||
<description><![CDATA[
|
||||
This specifies the number of main chat messages that are kept in the history buffer.
|
||||
Users can use the "!history" command to list these messages.
|
||||
]]></description>
|
||||
<since>0.3.0</since>
|
||||
</option>
|
||||
|
||||
<option name="max_logout_log" type="int" default="20">
|
||||
<check min="0" max="2000" />
|
||||
<short>Number of log entries for people leaving the hub</short>
|
||||
<description><![CDATA[
|
||||
Operators can use the "!log" command to list users who have recently left the hub.
|
||||
This option specifies the maximum size of this log.
|
||||
]]></description>
|
||||
<since>0.3.0</since>
|
||||
</option>
|
||||
|
||||
<option name="limit_max_hubs_user" type="int" default="10">
|
||||
<check min="0" />
|
||||
<short>Max concurrent hubs as a guest user</short>
|
||||
<description><![CDATA[
|
||||
This limits the number of hubs a user can be logged into as a guest user. If this number is exceeded, the user will not be allowed to enter the hub.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="limit_max_hubs_reg" type="int" default="10">
|
||||
<check min="0" />
|
||||
<short>Max concurrent hubs as a registered user</short>
|
||||
<description><![CDATA[
|
||||
This limits the number of hubs a user can be logged into as a registered user. If this number is exceeded, the user will not be allowed to enter the hub.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="limit_max_hubs_op" type="int" default="10">
|
||||
<check min="0" />
|
||||
<short>Max concurrent hubs as a operator (or admin)</short>
|
||||
<description><![CDATA[
|
||||
This limits the number of hubs a user can be logged into as an operator. If this number is exceeded, the user will not be allowed to enter the hub.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="limit_max_hubs" type="int" default="25">
|
||||
<check min="0" />
|
||||
<short>Max total hub connections allowed, user/reg/op combined.</short>
|
||||
<description><![CDATA[
|
||||
Limit the number of hubs a user can be logged into in total regardless of registrations or privileges.
|
||||
If this number is exceeded, the user will not be allowed to enter the hub.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="limit_min_hubs_user" type="int" default="0">
|
||||
<check min="0" />
|
||||
<short>Minimum concurrent hubs as a guest user</short>
|
||||
<description><![CDATA[
|
||||
Only allow users that are logged into other hubs with guest privileges to enter this hub.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="limit_min_hubs_reg" type="int" default="0">
|
||||
<check min="0" />
|
||||
<short>Minimum concurrent hubs as a registered user</short>
|
||||
<description><![CDATA[
|
||||
Only allow users that are logged into other hubs as a registered user to enter this hub.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="limit_min_hubs_op" type="int" default="0">
|
||||
<check min="0" />
|
||||
<short>Minimum concurrent hubs as a operator (or admin)</short>
|
||||
<description><![CDATA[
|
||||
Only allow users that are logged into other hubs with operator privileges to enter this hub.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="limit_min_share" type="int" default="0">
|
||||
<check min="0" />
|
||||
<short>Limit minimum share size in megabytes</short>
|
||||
<description><![CDATA[
|
||||
Minimum share limit in megabytes (MiB). Users sharing less than this will not be allowed to enter the hub.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.2.0</since>
|
||||
<example><![CDATA[
|
||||
To require users to share at least 1 GB in order to enter the hub:<br />
|
||||
limit_min_share = 1024
|
||||
]]></example>
|
||||
</option>
|
||||
|
||||
<option name="limit_max_share" type="int" default="0">
|
||||
<check min="0" />
|
||||
<short>Limit maximum share size in megabytes</short>
|
||||
<description><![CDATA[
|
||||
Maximum share limit in megabytes (MiB). Users sharing more than this will not be allowed to enter the hub.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
|
||||
<option name="limit_min_slots" type="int" default="0">
|
||||
<check min="0" />
|
||||
<short>Limit minimum number of upload slots open per user</short>
|
||||
<description><![CDATA[
|
||||
Minimum number of upload slots required. Users with less than this will not be allowed to enter the hub.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="limit_max_slots" type="int" default="0">
|
||||
<check min="0" />
|
||||
<short>Limit minimum number of upload slots open per user</short>
|
||||
<description><![CDATA[
|
||||
Maximum number of upload slots allowed. Users with more than this will not be allowed to enter the hub.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="flood_ctl_interval" type="int" default="0">
|
||||
<check min="1" max="60" />
|
||||
<short>Time interval in seconds for flood control check.</short>
|
||||
<description><![CDATA[
|
||||
This is the time interval that will be used for all flood control calculations.
|
||||
If this is 0 then all flood control is disabled.
|
||||
]]></description>
|
||||
<example><![CDATA[
|
||||
To limit maximum chat messages to 5 messages on 10 seconds: <br />
|
||||
flood_ctl_interval = 10 <br />
|
||||
flood_ctl_chat = 5<br />
|
||||
]]></example>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
<option name="flood_ctl_chat" type="int" default="0">
|
||||
<short>Max chat messages allowed in time interval</short>
|
||||
<description><![CDATA[
|
||||
If this is 0 then no flood control is disabled for chat messages.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
<option name="flood_ctl_connect" type="int" default="0">
|
||||
<short>Max connections requests allowed in time interval</short>
|
||||
<description><![CDATA[
|
||||
If this is 0 then no flood control is disabled for connection requests.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
<option name="flood_ctl_search" type="int" default="0">
|
||||
<short>Max search requests allowed in time interval</short>
|
||||
<description><![CDATA[
|
||||
If this is 0 then no flood control is disabled for search requests.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
|
||||
<option name="flood_ctl_update" type="int" default="0">
|
||||
<short>Max updates allowed in time interval</short>
|
||||
<description><![CDATA[
|
||||
If this is 0 then no flood control is disabled for info updates (INF messages).
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
<option name="flood_ctl_extras" type="int" default="0">
|
||||
<short>Max extra messages allowed in time interval</short>
|
||||
<description><![CDATA[
|
||||
Extra messages are messages that don't fit into the category of chat, search, update or connect.
|
||||
]]></description>
|
||||
<syntax>0 = off</syntax>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
<option name="tls_enable" type="boolean" default="0">
|
||||
<short>Enable SSL/TLS support</short>
|
||||
<description><![CDATA[
|
||||
Enables/disables TLS/SSL support. tls_certificate and tls_private_key must be set if this is enabled.
|
||||
]]></description>
|
||||
<since>0.3.0</since>
|
||||
</option>
|
||||
|
||||
<option name="tls_require" type="boolean" default="0">
|
||||
<short>If SSL/TLS enabled, should it be required (default: 0)</short>
|
||||
<description><![CDATA[
|
||||
If TLS/SSL support is enabled it can either be optional or mandatory.
|
||||
If this option is disabled then SSL/TLS is not required to enter the hub, however it is possible to enter either with or without.
|
||||
This option has no effect unless tls_enable is enabled.
|
||||
]]></description>
|
||||
<since>0.3.0</since>
|
||||
</option>
|
||||
|
||||
<option name="tls_require_redirect_addr" type="string" default="">
|
||||
<check regexp="(adc|adcs|dchub)://.*" />
|
||||
<short>A redirect address in case a client connects using "adc://" when "adcs://" is required.</short>
|
||||
<description><![CDATA[
|
||||
This is the redirect address used when the hub wants to redirect a client for not using ADCS.
|
||||
For instance a hub at adc://adc.example.com might redirect to adcs://adc.example.com
|
||||
]]></description>
|
||||
<since>0.3.3</since>
|
||||
</option>
|
||||
|
||||
|
||||
<option name="tls_certificate" type="file" default="">
|
||||
<short>Certificate file</short>
|
||||
<description><![CDATA[
|
||||
Path to a TLS/SSL certificate (PEM format).
|
||||
]]></description>
|
||||
<since>0.3.0</since>
|
||||
</option>
|
||||
|
||||
<option name="tls_private_key" type="file" default="">
|
||||
<short>Private key file</short>
|
||||
<description><![CDATA[
|
||||
Path to a TLS/SSL private key (PEM format).
|
||||
]]></description>
|
||||
<since>0.3.0</since>
|
||||
</option>
|
||||
|
||||
<option name="file_acl" type="file" default="">
|
||||
<short>File containing access control lists</short>
|
||||
<description><![CDATA[
|
||||
This is an access control list (acl) file.
|
||||
In this file all registered users, bans, etc should be stored.
|
||||
If the file is missing, or empty no registered users, or ban records are used.
|
||||
]]></description>
|
||||
<since>0.1.3</since>
|
||||
<example><![CDATA[
|
||||
<p>
|
||||
Unix users: <br />
|
||||
file_acl = "/etc/uhub/users.conf"
|
||||
</p>
|
||||
<p>
|
||||
Windows users: <br />
|
||||
file_acl = "c:\uhub\users.conf"
|
||||
</p>
|
||||
]]></example>
|
||||
</option>
|
||||
|
||||
<option name="file_plugins" type="file" default="">
|
||||
<short>Plugin configuration file</short>
|
||||
<description><![CDATA[
|
||||
Plugin configuration file.
|
||||
]]></description>
|
||||
<since>0.3.3</since>
|
||||
<example><![CDATA[
|
||||
<p>
|
||||
file_plugins = "/etc/uhub/plugins.conf"
|
||||
</p>
|
||||
]]></example>
|
||||
</option>
|
||||
|
||||
<option name="msg_hub_full" type="message" default="Hub is full" >
|
||||
<description><![CDATA[This will be sent if the hub is full]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_hub_disabled" type="message" default="Hub is disabled" >
|
||||
<description><![CDATA[This will be sent if the hub is disabled (hub_enable = off)]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_hub_registered_users_only" type="message" default="Hub is for registered users only" >
|
||||
<description><![CDATA[This will be sent if the hub is configured to only accept registered users (registered_users_only = yes)]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_nick_missing" type="message" default="No nickname given">
|
||||
<description><![CDATA[This is an error message that will be sent to clients that do not provide a nickname.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_nick_multiple" type="message" default="Multiple nicknames given">
|
||||
<description><![CDATA[This is an error message that will be sent to clients that provide multiple nicknames.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_nick_invalid" type="message" default="Nickname is invalid">
|
||||
<description><![CDATA[This is an error message that will be sent to clients that provides an invalid nickname.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_nick_long" type="message" default="Nickname too long">
|
||||
<description><![CDATA[This is an error message that will be sent to clients that provides a too long nickname.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_nick_short" type="message" default="Nickname too short">
|
||||
<description><![CDATA[This is an error message that will be sent to clients that provides a too short nickname.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_nick_spaces" type="message" default="Nickname cannot start with spaces">
|
||||
<description><![CDATA[This is an error message that will be sent to clients that provides a nickname that starts with a space.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_nick_bad_chars" type="message" default="Nickname contains invalid characters">
|
||||
<description><![CDATA[This is an error message that will be sent to clients that provides invalid characters in the nickname.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_nick_not_utf8" type="message" default="Nickname is not valid UTF-8">
|
||||
<description><![CDATA[This is an error message that will be sent to clients that provides a nick name that is not valid UTF-8 encoded.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_nick_taken" type="message" default="Nickname is already in use">
|
||||
<description><![CDATA[This message will be sent to clients if their provided nickname is alredy in use on the hub.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_nick_restricted" type="message" default="Nickname cannot be used on this hub">
|
||||
<description><![CDATA[This message will be sent to clients if they provide a restricted nickname. Restricted names can be configured in the acl.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_cid_invalid" type="message" default="CID is not valid">
|
||||
<description><![CDATA[This is an error message that will be sent to clients that provides an invalid client ID (CID)]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_cid_missing" type="message" default="CID is not specified">
|
||||
<description><![CDATA[This is an error message that will be sent to clients that does not provide a client ID (CID)]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_cid_taken" type="message" default="CID is taken">
|
||||
<description><![CDATA[This is an error message that will be sent to clients that provides a client ID (CID) already in use on the hub.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_pid_missing" type="message" default="PID is not specified">
|
||||
<description><![CDATA[This is an error message that will be sent to clients that does not provide a private ID (PID)]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_inf_error_pid_invalid" type="message" default="PID is invalid">
|
||||
<description><![CDATA[This is an error message that will be sent to clients that provides an invalid private ID (PID)]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_ban_permanently" type="message" default="Banned permanently">
|
||||
<description><![CDATA[This message is sent to users if they are banned (see acl)]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_ban_temporarily" type="message" default="Banned temporarily">
|
||||
<description><![CDATA[This message is sent to users if they are banned temporarily]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
|
||||
<option name="msg_auth_invalid_password" type="message" default="Password is wrong">
|
||||
<description><![CDATA[This message is sent to users if they provide a wrong password.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_auth_user_not_found" type="message" default="User not found in password database">
|
||||
<description><![CDATA[This message is used if a user cannot be found in the password database.]]></description>
|
||||
<since>0.2.0</since> <!-- FIXME? -->
|
||||
</option>
|
||||
|
||||
<option name="msg_error_no_memory" type="message" default="No memory">
|
||||
<description><![CDATA[]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_user_share_size_low" type="message" default="User is not sharing enough">
|
||||
<description><![CDATA[This message is sent to users if they are not sharing enough.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_user_share_size_high" type="message" default="User is sharing too much">
|
||||
<description><![CDATA[This message is sent to users if they are sharing too much.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_user_slots_low" type="message" default="User have too few upload slots.">
|
||||
<description><![CDATA[This message is sent to users if they do not have enough upload slots.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_user_slots_high" type="message" default="User have too many upload slots.">
|
||||
<description><![CDATA[This message is sent to users if they have too many upload slots.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_user_hub_limit_low" type="message" default="User is on too few hubs.">
|
||||
<description><![CDATA[This message is sent to users if they are on too few other hubs.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_user_hub_limit_high" type="message" default="User is on too many hubs.">
|
||||
<description><![CDATA[This message is sent to users if they are on too many other hubs.]]></description>
|
||||
<since>0.2.0</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_user_flood_chat" type="message" default="Chat flood detected, messages are dropped.">
|
||||
<description><![CDATA[This message is sent once to users who are flooding the chat.]]></description>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_user_flood_connect" type="message" default="Connect flood detected, connection refused.">
|
||||
<description><![CDATA[This message is sent once to users who are sending too many connect requests too fast.]]></description>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_user_flood_search" type="message" default="Search flood detected, search is stopped.">
|
||||
<description><![CDATA[This message is sent once to users who are sending too many search requests too fast.]]></description>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_user_flood_update" type="message" default="Update flood detected.">
|
||||
<description><![CDATA[This message is sent once to users who are sending too many updates too fast.]]></description>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_user_flood_extras" type="message" default="Flood detected.">
|
||||
<description><![CDATA[This message is sent once to users who are sending too many messages to the hub that neither are chat, searhes, updates nor connection requests..]]></description>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_proto_no_common_hash" type="message" default="No common hash algorithm.">
|
||||
<description><![CDATA[This message is sent if a client connects that does support ADC/1.0 but not a hash algorithm that the hub supports.]]></description>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
<option name="msg_proto_obsolete_adc0" type="message" default="Client is using an obsolete ADC protocol version.">
|
||||
<description><![CDATA[This message is sent if a client connects that does not support ADC/1.0, but rather the obsolete ADC/0.1 version.]]></description>
|
||||
<since>0.3.1</since>
|
||||
</option>
|
||||
|
||||
</config>
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_EVENT_ID_H
|
||||
#define HAVE_UHUB_EVENT_ID_H
|
||||
|
||||
/* User join or quit messages */
|
||||
#define UHUB_EVENT_USER_JOIN 0x1001
|
||||
#define UHUB_EVENT_USER_QUIT 0x1002
|
||||
#define UHUB_EVENT_USER_DESTROY 0x1003
|
||||
|
||||
/* Send a broadcast message */
|
||||
#define UHUB_EVENT_BROADCAST 0x2000
|
||||
|
||||
/* Shutdown hub */
|
||||
#define UHUB_EVENT_HUB_SHUTDOWN 0x3001
|
||||
|
||||
/* Statistics, OOM, reconfigure */
|
||||
#define UHUB_EVENT_STATISTICS 0x4000
|
||||
#define UHUB_EVENT_OUT_OF_MEMORY 0x4001
|
||||
#define UHUB_EVENT_RECONFIGURE 0x4002
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_EVENT_ID_H */
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
|
||||
#ifdef EQ_DEBUG
|
||||
static void eq_debug(const char* prefix, struct event_data* data)
|
||||
{
|
||||
LOG_DUMP(">>> %s: %p, id: %x, flags=%d\n", prefix, data, data->id, data->flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int event_queue_initialize(struct event_queue** queue, event_queue_callback callback, void* ptr)
|
||||
{
|
||||
*queue = (struct event_queue*) hub_malloc_zero(sizeof(struct event_queue));
|
||||
if (!(*queue))
|
||||
return -1;
|
||||
|
||||
(*queue)->q1 = list_create();
|
||||
(*queue)->q2 = list_create();
|
||||
|
||||
if (!(*queue)->q1 || !(*queue)->q2)
|
||||
{
|
||||
list_destroy((*queue)->q1);
|
||||
list_destroy((*queue)->q2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*queue)->callback = callback;
|
||||
(*queue)->callback_data = ptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void event_queue_shutdown(struct event_queue* queue)
|
||||
{
|
||||
/* Should be empty at this point! */
|
||||
list_destroy(queue->q1);
|
||||
list_destroy(queue->q2);
|
||||
hub_free(queue);
|
||||
}
|
||||
|
||||
static void event_queue_cleanup_callback(void* ptr)
|
||||
{
|
||||
#ifdef EQ_DEBUG
|
||||
struct event_data* data = (struct event_data*) ptr;
|
||||
eq_debug("NUKE", data);
|
||||
#endif
|
||||
|
||||
hub_free((struct event_data*) ptr);
|
||||
}
|
||||
|
||||
int event_queue_process(struct event_queue* queue)
|
||||
{
|
||||
struct event_data* data;
|
||||
if (queue->locked)
|
||||
return 0;
|
||||
|
||||
/* lock primary queue, and handle the primary queue messages. */
|
||||
queue->locked = 1;
|
||||
|
||||
data = (struct event_data*) list_get_first(queue->q1);
|
||||
while (data)
|
||||
{
|
||||
#ifdef EQ_DEBUG
|
||||
eq_debug("EXEC", data);
|
||||
#endif
|
||||
queue->callback(queue->callback_data, data);
|
||||
data = (struct event_data*) list_get_next(queue->q1);
|
||||
}
|
||||
|
||||
list_clear(queue->q1, event_queue_cleanup_callback);
|
||||
assert(list_size(queue->q1) == 0);
|
||||
|
||||
/* unlock queue */
|
||||
queue->locked = 0;
|
||||
|
||||
/* transfer from secondary queue to the primary queue. */
|
||||
data = (struct event_data*) list_get_first(queue->q2);
|
||||
while (data)
|
||||
{
|
||||
list_remove(queue->q2, data);
|
||||
list_append(queue->q1, data);
|
||||
data = (struct event_data*) list_get_first(queue->q2);
|
||||
}
|
||||
|
||||
/* if more events exist, schedule it */
|
||||
if (list_size(queue->q1))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void event_queue_post(struct event_queue* queue, struct event_data* message)
|
||||
{
|
||||
struct linked_list* q = (!queue->locked) ? queue->q1 : queue->q2;
|
||||
struct event_data* data;
|
||||
|
||||
data = (struct event_data*) hub_malloc(sizeof(struct event_data));
|
||||
if (data)
|
||||
{
|
||||
data->id = message->id;
|
||||
data->ptr = message->ptr;
|
||||
data->flags = message->flags;
|
||||
|
||||
#ifdef EQ_DEBUG
|
||||
eq_debug("POST", data);
|
||||
#endif
|
||||
|
||||
list_append(q, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("event_queue_post: OUT OF MEMORY");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t event_queue_size(struct event_queue* queue)
|
||||
{
|
||||
return list_size(queue->q1) + list_size(queue->q2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_EVENT_QUEUE_H
|
||||
#define HAVE_UHUB_EVENT_QUEUE_H
|
||||
|
||||
struct event_data
|
||||
{
|
||||
int id;
|
||||
void* ptr;
|
||||
int flags;
|
||||
};
|
||||
|
||||
typedef void (*event_queue_callback)(void* callback_data, struct event_data* event_data);
|
||||
|
||||
struct event_queue
|
||||
{
|
||||
int locked;
|
||||
struct linked_list* q1; /* primary */
|
||||
struct linked_list* q2; /* secondary, when primary is locked */
|
||||
event_queue_callback callback;
|
||||
void* callback_data;
|
||||
};
|
||||
|
||||
extern int event_queue_initialize(struct event_queue** queue, event_queue_callback callback, void* ptr);
|
||||
extern int event_queue_process(struct event_queue* queue);
|
||||
extern void event_queue_shutdown(struct event_queue* queue);
|
||||
extern void event_queue_post(struct event_queue* queue, struct event_data* message);
|
||||
extern size_t event_queue_size(struct event_queue* queue);
|
||||
|
||||
#endif /* HAVE_UHUB_EVENT_QUEUE_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,87 +0,0 @@
|
||||
/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */
|
||||
|
||||
struct hub_config
|
||||
{
|
||||
int hub_enabled; /*<<< Is server enabled (default: 1) */
|
||||
int server_port; /*<<< Server port to bind to (default: 1511) */
|
||||
char* server_bind_addr; /*<<< Server bind address (default: any) */
|
||||
int server_listen_backlog; /*<<< Server listen backlog (default: 50) */
|
||||
char* server_alt_ports; /*<<< Comma separated list of alternative ports to listen to (default: ) */
|
||||
int show_banner; /*<<< Show banner on connect (default: 1) */
|
||||
int show_banner_sys_info; /*<<< Show banner on connect (default: 1) */
|
||||
int max_users; /*<<< Maximum number of users allowed on the hub (default: 500) */
|
||||
int registered_users_only; /*<<< Allow registered users only (default: 0) */
|
||||
int register_self; /*<<< Allow users to register themselves on the hub. (default: 0) */
|
||||
int obsolete_clients; /*<<< Support obsolete clients using a ADC protocol prior to 1.0 (default: 0) */
|
||||
int chat_is_privileged; /*<<< Allow chat for operators and above only (default: 0) */
|
||||
char* hub_name; /*<<< Name of hub (default: uhub) */
|
||||
char* hub_description; /*<<< Short hub description, topic or subject. (default: no description) */
|
||||
char* redirect_addr; /*<<< A common hub redirect address. (default: ) */
|
||||
int max_recv_buffer; /*<<< Max read buffer before parse, per user (default: 4096) */
|
||||
int max_send_buffer; /*<<< Max send buffer before disconnect, per user (default: 131072) */
|
||||
int max_send_buffer_soft; /*<<< Max send buffer before message drops, per user (default: 98304) */
|
||||
int low_bandwidth_mode; /*<<< Enable bandwidth saving measures (default: 0) */
|
||||
int max_chat_history; /*<<< Number of chat messages kept in history (default: 20) */
|
||||
int max_logout_log; /*<<< Number of log entries for people leaving the hub (default: 20) */
|
||||
int limit_max_hubs_user; /*<<< Max concurrent hubs as a guest user (default: 10) */
|
||||
int limit_max_hubs_reg; /*<<< Max concurrent hubs as a registered user (default: 10) */
|
||||
int limit_max_hubs_op; /*<<< Max concurrent hubs as a operator (or admin) (default: 10) */
|
||||
int limit_max_hubs; /*<<< Max total hub connections allowed, user/reg/op combined. (default: 25) */
|
||||
int limit_min_hubs_user; /*<<< Minimum concurrent hubs as a guest user (default: 0) */
|
||||
int limit_min_hubs_reg; /*<<< Minimum concurrent hubs as a registered user (default: 0) */
|
||||
int limit_min_hubs_op; /*<<< Minimum concurrent hubs as a operator (or admin) (default: 0) */
|
||||
int limit_min_share; /*<<< Limit minimum share size in megabytes (default: 0) */
|
||||
int limit_max_share; /*<<< Limit maximum share size in megabytes (default: 0) */
|
||||
int limit_min_slots; /*<<< Limit minimum number of upload slots open per user (default: 0) */
|
||||
int limit_max_slots; /*<<< Limit minimum number of upload slots open per user (default: 0) */
|
||||
int flood_ctl_interval; /*<<< Time interval in seconds for flood control check. (default: 0) */
|
||||
int flood_ctl_chat; /*<<< Max chat messages allowed in time interval (default: 0) */
|
||||
int flood_ctl_connect; /*<<< Max connections requests allowed in time interval (default: 0) */
|
||||
int flood_ctl_search; /*<<< Max search requests allowed in time interval (default: 0) */
|
||||
int flood_ctl_update; /*<<< Max updates allowed in time interval (default: 0) */
|
||||
int flood_ctl_extras; /*<<< Max extra messages allowed in time interval (default: 0) */
|
||||
int tls_enable; /*<<< Enable SSL/TLS support (default: 0) */
|
||||
int tls_require; /*<<< If SSL/TLS enabled, should it be required (default: 0) (default: 0) */
|
||||
char* tls_require_redirect_addr; /*<<< A redirect address in case a client connects using "adc://" when "adcs://" is required. (default: ) */
|
||||
char* tls_certificate; /*<<< Certificate file (default: ) */
|
||||
char* tls_private_key; /*<<< Private key file (default: ) */
|
||||
char* file_acl; /*<<< File containing access control lists (default: ) */
|
||||
char* file_plugins; /*<<< Plugin configuration file (default: ) */
|
||||
char* msg_hub_full; /*<<< "Hub is full" */
|
||||
char* msg_hub_disabled; /*<<< "Hub is disabled" */
|
||||
char* msg_hub_registered_users_only; /*<<< "Hub is for registered users only" */
|
||||
char* msg_inf_error_nick_missing; /*<<< "No nickname given" */
|
||||
char* msg_inf_error_nick_multiple; /*<<< "Multiple nicknames given" */
|
||||
char* msg_inf_error_nick_invalid; /*<<< "Nickname is invalid" */
|
||||
char* msg_inf_error_nick_long; /*<<< "Nickname too long" */
|
||||
char* msg_inf_error_nick_short; /*<<< "Nickname too short" */
|
||||
char* msg_inf_error_nick_spaces; /*<<< "Nickname cannot start with spaces" */
|
||||
char* msg_inf_error_nick_bad_chars; /*<<< "Nickname contains invalid characters" */
|
||||
char* msg_inf_error_nick_not_utf8; /*<<< "Nickname is not valid UTF-8" */
|
||||
char* msg_inf_error_nick_taken; /*<<< "Nickname is already in use" */
|
||||
char* msg_inf_error_nick_restricted; /*<<< "Nickname cannot be used on this hub" */
|
||||
char* msg_inf_error_cid_invalid; /*<<< "CID is not valid" */
|
||||
char* msg_inf_error_cid_missing; /*<<< "CID is not specified" */
|
||||
char* msg_inf_error_cid_taken; /*<<< "CID is taken" */
|
||||
char* msg_inf_error_pid_missing; /*<<< "PID is not specified" */
|
||||
char* msg_inf_error_pid_invalid; /*<<< "PID is invalid" */
|
||||
char* msg_ban_permanently; /*<<< "Banned permanently" */
|
||||
char* msg_ban_temporarily; /*<<< "Banned temporarily" */
|
||||
char* msg_auth_invalid_password; /*<<< "Password is wrong" */
|
||||
char* msg_auth_user_not_found; /*<<< "User not found in password database" */
|
||||
char* msg_error_no_memory; /*<<< "No memory" */
|
||||
char* msg_user_share_size_low; /*<<< "User is not sharing enough" */
|
||||
char* msg_user_share_size_high; /*<<< "User is sharing too much" */
|
||||
char* msg_user_slots_low; /*<<< "User have too few upload slots." */
|
||||
char* msg_user_slots_high; /*<<< "User have too many upload slots." */
|
||||
char* msg_user_hub_limit_low; /*<<< "User is on too few hubs." */
|
||||
char* msg_user_hub_limit_high; /*<<< "User is on too many hubs." */
|
||||
char* msg_user_flood_chat; /*<<< "Chat flood detected, messages are dropped." */
|
||||
char* msg_user_flood_connect; /*<<< "Connect flood detected, connection refused." */
|
||||
char* msg_user_flood_search; /*<<< "Search flood detected, search is stopped." */
|
||||
char* msg_user_flood_update; /*<<< "Update flood detected." */
|
||||
char* msg_user_flood_extras; /*<<< "Flood detected." */
|
||||
char* msg_proto_no_common_hash; /*<<< "No common hash algorithm." */
|
||||
char* msg_proto_obsolete_adc0; /*<<< "Client is using an obsolete ADC protocol version." */
|
||||
};
|
||||
|
||||
-1292
File diff suppressed because it is too large
Load Diff
-355
@@ -1,355 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_HUB_H
|
||||
#define HAVE_UHUB_HUB_H
|
||||
|
||||
enum status_message
|
||||
{
|
||||
status_msg_hub_full = -1, /* hub is full */
|
||||
status_msg_hub_disabled = -2, /* hub is disabled */
|
||||
status_msg_hub_registered_users_only = -3, /* hub is for registered users only */
|
||||
status_msg_inf_error_nick_missing = -4, /* no nickname given */
|
||||
status_msg_inf_error_nick_multiple = -5, /* multiple nicknames given */
|
||||
status_msg_inf_error_nick_invalid = -6, /* generic/unkown */
|
||||
status_msg_inf_error_nick_long = -7, /* nickname too long */
|
||||
status_msg_inf_error_nick_short = -8, /* nickname too short */
|
||||
status_msg_inf_error_nick_spaces = -9, /* nickname cannot start with spaces */
|
||||
status_msg_inf_error_nick_bad_chars = -10, /* nickname contains chars below ascii 32 */
|
||||
status_msg_inf_error_nick_not_utf8 = -11, /* nickname is not valid utf8 */
|
||||
status_msg_inf_error_nick_taken = -12, /* nickname is in use */
|
||||
status_msg_inf_error_nick_restricted = -13, /* nickname cannot be used on this hub */
|
||||
status_msg_inf_error_cid_invalid = -14, /* CID is not valid (generic error) */
|
||||
status_msg_inf_error_cid_missing = -15, /* CID is not specified */
|
||||
status_msg_inf_error_cid_taken = -16, /* CID is taken (already logged in?). */
|
||||
status_msg_inf_error_pid_missing = -17, /* PID is not specified */
|
||||
status_msg_inf_error_pid_invalid = -18, /* PID is invalid */
|
||||
status_msg_ban_permanently = -19, /* Banned permanently */
|
||||
status_msg_ban_temporarily = -20, /* Banned temporarily */
|
||||
status_msg_auth_invalid_password = -21, /* Password is wrong */
|
||||
status_msg_auth_user_not_found = -22, /* User not found in password database */
|
||||
status_msg_error_no_memory = -23, /* Hub is out of memory */
|
||||
|
||||
status_msg_user_share_size_low = -40, /* User is not sharing enough. */
|
||||
status_msg_user_share_size_high = -41, /* User is sharing too much. */
|
||||
status_msg_user_slots_low = -42, /* User has too few slots open. */
|
||||
status_msg_user_slots_high = -43, /* User has too many slots open. */
|
||||
status_msg_user_hub_limit_low = -44, /* Use is on too few hubs. */
|
||||
status_msg_user_hub_limit_high = -45, /* Use is on too many hubs. */
|
||||
|
||||
status_msg_proto_no_common_hash = -50, /* No common hash algorithms */
|
||||
status_msg_proto_obsolete_adc0 = -51, /* Client is using an obsolete protocol version */
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
enum hub_state
|
||||
{
|
||||
hub_status_uninitialized = 0, /**<<<"Hub is uninitialized" */
|
||||
hub_status_running = 1, /**<<<"Hub is running (normal operation)" */
|
||||
hub_status_restart = 2, /**<<<"Hub is restarting (re-reading configuration, etc)" */
|
||||
hub_status_shutdown = 3, /**<<<"Hub is shutting down, but not yet stopped. */
|
||||
hub_status_stopped = 4, /**<<<"Hub is stopped (Pretty much the same as initialized) */
|
||||
hub_status_disabled = 5, /**<<<"Hub is disabled (Running, but not accepting users) */
|
||||
};
|
||||
|
||||
/**
|
||||
* Always updated each minute.
|
||||
*/
|
||||
struct hub_stats
|
||||
{
|
||||
size_t net_tx;
|
||||
size_t net_rx;
|
||||
size_t net_tx_peak;
|
||||
size_t net_rx_peak;
|
||||
size_t net_tx_total;
|
||||
size_t net_rx_total;
|
||||
};
|
||||
|
||||
struct hub_logout_info
|
||||
{
|
||||
time_t time;
|
||||
char cid[MAX_CID_LEN+1];
|
||||
char nick[MAX_NICK_LEN+1];
|
||||
struct ip_addr_encap addr;
|
||||
enum user_quit_reason reason;
|
||||
};
|
||||
|
||||
struct hub_info
|
||||
{
|
||||
struct net_connection* server;
|
||||
struct linked_list* server_alt_ports;
|
||||
struct hub_stats stats;
|
||||
struct event_queue* queue;
|
||||
struct hub_config* config;
|
||||
struct hub_user_manager* users;
|
||||
struct acl_handle* acl;
|
||||
struct adc_message* command_info; /* The hub's INF command */
|
||||
struct adc_message* command_support; /* The hub's SUP command */
|
||||
struct adc_message* command_banner; /* The default welcome message */
|
||||
time_t tm_started;
|
||||
int status;
|
||||
char* recvbuf; /* Global receive buffer */
|
||||
char* sendbuf; /* Global send buffer */
|
||||
|
||||
struct linked_list* logout_info; /* Log of people logging out. */
|
||||
|
||||
struct command_base* commands; /* Hub command handler */
|
||||
struct uhub_plugins* plugins; /* Plug-ins loaded for this hub instance. */
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
SSL_METHOD* ssl_method;
|
||||
SSL_CTX* ssl_ctx;
|
||||
#endif /* SSL_SUPPORT */
|
||||
};
|
||||
|
||||
/**
|
||||
* This is the message pre-routing centre.
|
||||
*
|
||||
* Any message coming in to the hub comes through here first,
|
||||
* and will be routed further if valid.
|
||||
*
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
extern int hub_handle_message(struct hub_info* hub, struct hub_user* u, const char* message, size_t length);
|
||||
|
||||
/**
|
||||
* Handle protocol support/subscription messages received clients.
|
||||
*
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
extern int hub_handle_support(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd);
|
||||
|
||||
/**
|
||||
* Handle password messages received from clients.
|
||||
*
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
extern int hub_handle_password(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd);
|
||||
|
||||
/**
|
||||
* Handle chat messages received from clients.
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
extern int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd);
|
||||
|
||||
/**
|
||||
* Used internally by hub_handle_info
|
||||
* @return 1 if nickname is OK, or 0 if nickname is not accepted.
|
||||
*/
|
||||
extern int hub_handle_info_check_nick(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd);
|
||||
|
||||
/**
|
||||
* Used internally by hub_handle_info
|
||||
* @return 1 if CID/PID is OK, or 0 if not valid.
|
||||
*/
|
||||
extern int hub_handle_info_check_cid(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd);
|
||||
|
||||
/**
|
||||
* Send the support line for the hub to a particular user.
|
||||
* Only used during the initial handshake.
|
||||
*/
|
||||
extern void hub_send_support(struct hub_info* hub, struct hub_user* u);
|
||||
|
||||
/**
|
||||
* Send a message assigning a SID for a user.
|
||||
* This is only sent after hub_send_support() during initial handshake.
|
||||
*/
|
||||
extern void hub_send_sid(struct hub_info* hub, struct hub_user* u);
|
||||
|
||||
/**
|
||||
* Send a 'ping' message to user.
|
||||
*/
|
||||
extern void hub_send_ping(struct hub_info* hub, struct hub_user* user);
|
||||
|
||||
/**
|
||||
* Send a message containing hub information to a particular user.
|
||||
* This is sent during user connection, but can safely be sent at any
|
||||
* point later.
|
||||
*/
|
||||
extern void hub_send_hubinfo(struct hub_info* hub, struct hub_user* u);
|
||||
|
||||
/**
|
||||
* Send handshake. This basically calls
|
||||
* hub_send_support() and hub_send_sid()
|
||||
*/
|
||||
extern void hub_send_handshake(struct hub_info* hub, struct hub_user* u);
|
||||
|
||||
/**
|
||||
* Send a password challenge to a user.
|
||||
* This is only used if the user tries to access the hub using a
|
||||
* password protected nick name.
|
||||
*/
|
||||
extern void hub_send_password_challenge(struct hub_info* hub, struct hub_user* u);
|
||||
|
||||
/**
|
||||
* Sends a status_message to a user.
|
||||
*/
|
||||
extern void hub_send_status(struct hub_info*, struct hub_user* user, enum status_message msg, enum msg_status_level level);
|
||||
|
||||
/**
|
||||
* Warn user about flooding.
|
||||
*/
|
||||
extern void hub_send_flood_warning(struct hub_info*, struct hub_user* user, const char* message);
|
||||
|
||||
/**
|
||||
* Allocates memory, initializes the hub based on the configuration,
|
||||
* and returns a hub handle.
|
||||
* This hub handle must be passed to hub_shutdown_service() in order to cleanup before exiting.
|
||||
*
|
||||
* @return a pointer to the hub info.
|
||||
*/
|
||||
extern struct hub_info* hub_start_service(struct hub_config* config);
|
||||
|
||||
/**
|
||||
* This shuts down the hub.
|
||||
*/
|
||||
extern void hub_shutdown_service(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* This configures the hub.
|
||||
*/
|
||||
extern void hub_set_variables(struct hub_info* hub, struct acl_handle* acl);
|
||||
|
||||
/**
|
||||
* This frees the configuration of the hub.
|
||||
*/
|
||||
extern void hub_free_variables(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Returns a string for the given status_message (See enum status_message).
|
||||
*/
|
||||
extern const char* hub_get_status_message(struct hub_info* hub, enum status_message msg);
|
||||
extern const char* hub_get_status_message_log(struct hub_info* hub, enum status_message msg);
|
||||
|
||||
/**
|
||||
* Returns the number of logged in users on the hub.
|
||||
*/
|
||||
extern size_t hub_get_user_count(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Returns the maximum number of allowed users on the hub.
|
||||
*/
|
||||
extern size_t hub_get_max_user_count(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Returns the accumulated shared size for all logged in
|
||||
* users on the hub.
|
||||
*/
|
||||
extern uint64_t hub_get_shared_size(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Returns the accumulated number of files for all logged
|
||||
* in users on the hub.
|
||||
*/
|
||||
extern uint64_t hub_get_shared_files(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Returns the minimal share size limit as enforced by
|
||||
* this hub's configuration.
|
||||
*/
|
||||
extern uint64_t hub_get_min_share(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Returns the minimal share size limit as enforced by
|
||||
* this hub's configuration.
|
||||
*/
|
||||
extern uint64_t hub_get_max_share(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Returns the minimum upload slot limit as enforced by
|
||||
* this hub's configuration.
|
||||
* Users with fewer slots in total will not be allowed
|
||||
* to enter the hub.
|
||||
* @return limit or 0 if no limit.
|
||||
*/
|
||||
extern size_t hub_get_min_slots(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Returns the maximum upload slot limit as enforced by
|
||||
* this hub's configuration.
|
||||
* Users with more allowed upload slots will not be
|
||||
* allowed to enter the hub.
|
||||
* @return limit or 0 if no limit.
|
||||
*/
|
||||
extern size_t hub_get_max_slots(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Returns the maximum number of hubs a user can
|
||||
* be logged in to simultaneously as a regular user (guest).
|
||||
* Users on more hubs will not be allowed to stay on this hub.
|
||||
* @return limit or 0 if no limit.
|
||||
*/
|
||||
extern size_t hub_get_max_hubs_user(struct hub_info* hub);
|
||||
extern size_t hub_get_min_hubs_user(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Returns the maximum number of hubs a user can
|
||||
* be logged in to simultaneously as a registered user (password required).
|
||||
* Users on more hubs will not be allowed to stay on this hub.
|
||||
* @return limit or 0 if no limit.
|
||||
*/
|
||||
extern size_t hub_get_max_hubs_reg(struct hub_info* hub);
|
||||
extern size_t hub_get_min_hubs_reg(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Returns the maximum number of hubs a user can
|
||||
* be logged in to simultaneously as an operator.
|
||||
* Users who are operator on more than this amount of hubs
|
||||
* will not be allowed to stay on this hub.
|
||||
* @return limit or 0 if no limit.
|
||||
*/
|
||||
extern size_t hub_get_max_hubs_op(struct hub_info* hub);
|
||||
extern size_t hub_get_min_hubs_op(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Returns the maximum number of hubs a user can
|
||||
* be logged in to simultaneously regardless of the type of user.
|
||||
*/
|
||||
extern size_t hub_get_max_hubs_total(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Schedule runslice.
|
||||
*/
|
||||
extern void hub_schedule_runslice(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Run event loop.
|
||||
*/
|
||||
extern void hub_event_loop(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Schedule destroying a user.
|
||||
*/
|
||||
extern void hub_schedule_destroy_user(struct hub_info* hub, struct hub_user* user);
|
||||
|
||||
/**
|
||||
* Disconnect a user from the hub.
|
||||
*/
|
||||
extern void hub_disconnect_user(struct hub_info* hub, struct hub_user* user, int reason);
|
||||
|
||||
/**
|
||||
* Log a user logging out.
|
||||
*/
|
||||
extern void hub_logout_log(struct hub_info* hub, struct hub_user* user);
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_HUB_H */
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
#include "plugin_api/handle.h"
|
||||
|
||||
/* Notify plugins, etc */
|
||||
void on_login_success(struct hub_info* hub, struct hub_user* u)
|
||||
{
|
||||
/* Send user list of all existing users */
|
||||
if (!uman_send_user_list(hub, u))
|
||||
return;
|
||||
|
||||
/* Mark as being in the normal state, and add user to the user list */
|
||||
user_set_state(u, state_normal);
|
||||
uman_add(hub, u);
|
||||
|
||||
/* Announce new user to all connected users */
|
||||
if (user_is_logged_in(u))
|
||||
route_info_message(hub, u);
|
||||
|
||||
plugin_log_user_login_success(hub, u);
|
||||
|
||||
/* reset timeout */
|
||||
net_con_clear_timeout(u->connection);
|
||||
}
|
||||
|
||||
void on_login_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg)
|
||||
{
|
||||
plugin_log_user_login_error(hub, u, hub_get_status_message_log(hub, msg));
|
||||
hub_send_status(hub, u, msg, status_level_fatal);
|
||||
hub_disconnect_user(hub, u, quit_logon_error);
|
||||
}
|
||||
|
||||
void on_update_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg)
|
||||
{
|
||||
plugin_log_user_update_error(hub, u, hub_get_status_message_log(hub, msg));
|
||||
hub_send_status(hub, u, msg, status_level_fatal);
|
||||
hub_disconnect_user(hub, u, quit_update_error);
|
||||
}
|
||||
|
||||
void on_nick_change(struct hub_info* hub, struct hub_user* u, const char* nick)
|
||||
{
|
||||
if (user_is_logged_in(u))
|
||||
{
|
||||
plugin_log_user_nick_change(hub, u, nick);
|
||||
}
|
||||
}
|
||||
|
||||
void on_logout_user(struct hub_info* hub, struct hub_user* user)
|
||||
{
|
||||
const char* reason = user_get_quit_reason_string(user->quit_reason);
|
||||
|
||||
plugin_log_user_logout(hub, user, reason);
|
||||
hub_logout_log(hub, user);
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_HUB_EVENT_H
|
||||
#define HAVE_UHUB_HUB_EVENT_H
|
||||
|
||||
/**
|
||||
* This event is triggered whenever a user successfully logs in to the hub.
|
||||
*/
|
||||
extern void on_login_success(struct hub_info* hub, struct hub_user* u);
|
||||
|
||||
/**
|
||||
* This event is triggered whenever a user failed to log in to the hub.
|
||||
*/
|
||||
extern void on_login_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg);
|
||||
extern void on_update_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg);
|
||||
|
||||
/**
|
||||
* This event is triggered whenever a previously logged in user leaves the hub.
|
||||
*/
|
||||
extern void on_logout_user(struct hub_info* hub, struct hub_user* u);
|
||||
|
||||
/**
|
||||
* This event is triggered whenever a user changes his/her nickname.
|
||||
*/
|
||||
extern void on_nick_change(struct hub_info* hub, struct hub_user* u, const char* nick);
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_HUB_EVENT_H */
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
#include "hubio.h"
|
||||
|
||||
#ifdef DEBUG_SENDQ
|
||||
static void debug_msg(const char* prefix, struct adc_message* msg)
|
||||
{
|
||||
size_t n;
|
||||
char* buf = strdup(msg->cache);
|
||||
for (n = 0; n < msg->length; n++)
|
||||
{
|
||||
if (buf[n] == '\r' || buf[n] == '\n')
|
||||
buf[n] = '_';
|
||||
}
|
||||
LOG_TRACE("%s: [%s] (%d bytes)", prefix, buf, (int) msg->length);
|
||||
free(buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct hub_recvq* hub_recvq_create()
|
||||
{
|
||||
struct hub_recvq* q = hub_malloc_zero(sizeof(struct hub_recvq));
|
||||
return q;
|
||||
}
|
||||
|
||||
void hub_recvq_destroy(struct hub_recvq* q)
|
||||
{
|
||||
if (q)
|
||||
{
|
||||
hub_free(q->buf);
|
||||
hub_free(q);
|
||||
}
|
||||
}
|
||||
|
||||
size_t hub_recvq_get(struct hub_recvq* q, void* buf, size_t bufsize)
|
||||
{
|
||||
assert(bufsize >= q->size);
|
||||
if (q->size)
|
||||
{
|
||||
size_t n = q->size;
|
||||
memcpy(buf, q->buf, n);
|
||||
hub_free(q->buf);
|
||||
q->buf = 0;
|
||||
q->size = 0;
|
||||
return n;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t hub_recvq_set(struct hub_recvq* q, void* buf, size_t bufsize)
|
||||
{
|
||||
if (q->buf)
|
||||
{
|
||||
hub_free(q->buf);
|
||||
q->buf = 0;
|
||||
q->size = 0;
|
||||
}
|
||||
|
||||
if (!bufsize)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
q->buf = hub_malloc(bufsize);
|
||||
if (!q->buf)
|
||||
return 0;
|
||||
|
||||
q->size = bufsize;
|
||||
memcpy(q->buf, buf, bufsize);
|
||||
return bufsize;
|
||||
}
|
||||
|
||||
|
||||
struct hub_sendq* hub_sendq_create()
|
||||
{
|
||||
struct hub_sendq* q = hub_malloc_zero(sizeof(struct hub_sendq));
|
||||
if (!q)
|
||||
return 0;
|
||||
|
||||
q->queue = list_create();
|
||||
if (!q->queue)
|
||||
{
|
||||
hub_free(q);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
static void clear_send_queue_callback(void* ptr)
|
||||
{
|
||||
adc_msg_free((struct adc_message*) ptr);
|
||||
}
|
||||
|
||||
void hub_sendq_destroy(struct hub_sendq* q)
|
||||
{
|
||||
if (q)
|
||||
{
|
||||
list_clear(q->queue, &clear_send_queue_callback);
|
||||
list_destroy(q->queue);
|
||||
hub_free(q);
|
||||
}
|
||||
}
|
||||
|
||||
void hub_sendq_add(struct hub_sendq* q, struct adc_message* msg_)
|
||||
{
|
||||
struct adc_message* msg = adc_msg_incref(msg_);
|
||||
#ifdef DEBUG_SENDQ
|
||||
debug_msg("hub_sendq_add", msg);
|
||||
#endif
|
||||
assert(msg->cache && *msg->cache);
|
||||
list_append(q->queue, msg);
|
||||
q->size += msg->length;
|
||||
}
|
||||
|
||||
void hub_sendq_remove(struct hub_sendq* q, struct adc_message* msg)
|
||||
{
|
||||
#ifdef DEBUG_SENDQ
|
||||
debug_msg("hub_sendq_remove", msg);
|
||||
#endif
|
||||
list_remove(q->queue, msg);
|
||||
q->size -= msg->length;
|
||||
adc_msg_free(msg);
|
||||
q->offset = 0;
|
||||
}
|
||||
|
||||
int hub_sendq_send(struct hub_sendq* q, struct hub_user* user)
|
||||
{
|
||||
int ret;
|
||||
struct adc_message* msg = list_get_first(q->queue);
|
||||
if (!msg) return 0;
|
||||
assert(msg->cache && *msg->cache);
|
||||
ret = net_con_send(user->connection, msg->cache + q->offset, msg->length - q->offset);
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
q->offset += ret;
|
||||
if (msg->length - q->offset > 0)
|
||||
return 0;
|
||||
|
||||
hub_sendq_remove(q, msg);
|
||||
return 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hub_sendq_is_empty(struct hub_sendq* q)
|
||||
{
|
||||
return (q->size - q->offset) == 0;
|
||||
}
|
||||
|
||||
size_t hub_sendq_get_bytes(struct hub_sendq* q)
|
||||
{
|
||||
return q->size - q->offset;
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_HUB_IO_H
|
||||
#define HAVE_UHUB_HUB_IO_H
|
||||
|
||||
struct adc_message;
|
||||
struct linked_list;
|
||||
typedef int (*hub_recvq_write)(void* desc, const void* buf, size_t len);
|
||||
typedef int (*hub_recvq_read)(void* desc, void* buf, size_t len);
|
||||
|
||||
struct hub_sendq
|
||||
{
|
||||
size_t size; /** Size of send queue (in bytes, not messages) */
|
||||
size_t offset; /** Queue byte offset in the first message. Should be 0 unless a partial write. */
|
||||
#ifdef SSL_SUPPORT
|
||||
size_t last_send; /** When using SSL, one have to send the exact same buffer and length if a write cannot complete. */
|
||||
#endif
|
||||
struct linked_list* queue; /** List of queued messages */
|
||||
};
|
||||
|
||||
struct hub_recvq
|
||||
{
|
||||
char* buf;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a send queue
|
||||
*/
|
||||
extern struct hub_sendq* hub_sendq_create();
|
||||
|
||||
/**
|
||||
* Destroy a send queue, and delete any queued messages.
|
||||
*/
|
||||
extern void hub_sendq_destroy(struct hub_sendq*);
|
||||
|
||||
/**
|
||||
* Add a message to the send queue.
|
||||
*/
|
||||
extern void hub_sendq_add(struct hub_sendq*, struct adc_message* msg);
|
||||
|
||||
/**
|
||||
* Process the send queue, and send as many messages as possible.
|
||||
* @returns -1 on error, 0 if unable to send more, 1 if more can be sent.
|
||||
*/
|
||||
extern int hub_sendq_send(struct hub_sendq*, struct hub_user*);
|
||||
|
||||
/**
|
||||
* @returns 1 if send queue is empty, 0 otherwise.
|
||||
*/
|
||||
extern int hub_sendq_is_empty(struct hub_sendq*);
|
||||
|
||||
/**
|
||||
* @returns the number of bytes remaining to be sent in the queue.
|
||||
*/
|
||||
extern size_t hub_sendq_get_bytes(struct hub_sendq*);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a receive queue.
|
||||
*/
|
||||
extern struct hub_recvq* hub_recvq_create();
|
||||
|
||||
/**
|
||||
* Destroy a receive queue.
|
||||
*/
|
||||
extern void hub_recvq_destroy(struct hub_recvq*);
|
||||
|
||||
/**
|
||||
* Gets the buffer, copies it into buf and deallocates it.
|
||||
* NOTE: bufsize *MUST* be larger than the buffer, otherwise it asserts.
|
||||
* @return the number of bytes copied into buf.
|
||||
*/
|
||||
extern size_t hub_recvq_get(struct hub_recvq*, void* buf, size_t bufsize);
|
||||
|
||||
/**
|
||||
* Sets the buffer
|
||||
*/
|
||||
extern size_t hub_recvq_set(struct hub_recvq*, void* buf, size_t bufsize);
|
||||
|
||||
/**
|
||||
* @return 1 if size is zero, 0 otherwise.
|
||||
*/
|
||||
extern int hub_recvq_is_empty(struct hub_recvq* buf);
|
||||
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_HUB_IO_H */
|
||||
-802
@@ -1,802 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
|
||||
/*
|
||||
* These flags can only be set by the hub.
|
||||
* Make sure we don't allow clients to specify these themselves.
|
||||
*
|
||||
* NOTE: Some of them are legacy ADC flags and no longer used, these
|
||||
* should be removed at some point in the future when functionality no
|
||||
* longer depend on them.
|
||||
*/
|
||||
static void remove_server_restricted_flags(struct adc_message* cmd)
|
||||
{
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE); /* Client type flag (CT, obsoletes BO, RG, OP, HU) */
|
||||
adc_msg_remove_named_argument(cmd, "BO"); /* Obsolete: bot flag (CT) */
|
||||
adc_msg_remove_named_argument(cmd, "RG"); /* Obsolete: registered user flag (CT) */
|
||||
adc_msg_remove_named_argument(cmd, "OP"); /* Obsolete: operator flag (CT) */
|
||||
adc_msg_remove_named_argument(cmd, "HU"); /* Obsolete: hub flag (CT) */
|
||||
adc_msg_remove_named_argument(cmd, "HI"); /* Obsolete: hidden user flag */
|
||||
adc_msg_remove_named_argument(cmd, "TO"); /* Client to client token - should not be seen here */
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_REFERER);
|
||||
}
|
||||
|
||||
static int set_feature_cast_supports(struct hub_user* u, struct adc_message* cmd)
|
||||
{
|
||||
char *it, *tmp;
|
||||
|
||||
if (adc_msg_has_named_argument(cmd, ADC_INF_FLAG_SUPPORT))
|
||||
{
|
||||
tmp = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SUPPORT);
|
||||
if (!tmp)
|
||||
return -1; // FIXME: OOM
|
||||
|
||||
user_clear_feature_cast_support(u);
|
||||
|
||||
it = tmp;
|
||||
while (strlen(it) > 4)
|
||||
{
|
||||
it[4] = 0; /* FIXME: Not really needed */
|
||||
user_set_feature_cast_support(u, it);
|
||||
it = &it[5];
|
||||
}
|
||||
|
||||
if (*it)
|
||||
{
|
||||
user_set_feature_cast_support(u, it);
|
||||
}
|
||||
hub_free(tmp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int check_hash_tiger(const char* cid, const char* pid)
|
||||
{
|
||||
char x_pid[64];
|
||||
char raw_pid[64];
|
||||
uint64_t tiger_res[3];
|
||||
|
||||
memset(x_pid, 0, MAX_CID_LEN+1);
|
||||
|
||||
base32_decode(pid, (unsigned char*) raw_pid, MAX_CID_LEN);
|
||||
tiger((uint64_t*) raw_pid, TIGERSIZE, (uint64_t*) tiger_res);
|
||||
base32_encode((unsigned char*) tiger_res, TIGERSIZE, x_pid);
|
||||
x_pid[MAX_CID_LEN] = 0;
|
||||
if (strncasecmp(x_pid, cid, MAX_CID_LEN) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FIXME: Only works for tiger hash. If a client doesnt support tiger we cannot let it in!
|
||||
*/
|
||||
static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
size_t pos;
|
||||
char* cid = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_CLIENT_ID);
|
||||
char* pid = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);
|
||||
|
||||
if (!cid || !pid)
|
||||
{
|
||||
hub_free(cid);
|
||||
hub_free(pid);
|
||||
return status_msg_error_no_memory;
|
||||
}
|
||||
|
||||
if (strlen(cid) != MAX_CID_LEN)
|
||||
{
|
||||
hub_free(cid);
|
||||
hub_free(pid);
|
||||
return status_msg_inf_error_cid_invalid;
|
||||
}
|
||||
|
||||
if (strlen(pid) != MAX_CID_LEN)
|
||||
{
|
||||
hub_free(cid);
|
||||
hub_free(pid);
|
||||
return status_msg_inf_error_pid_invalid;
|
||||
}
|
||||
|
||||
for (pos = 0; pos < MAX_CID_LEN; pos++)
|
||||
{
|
||||
if (!is_valid_base32_char(cid[pos]))
|
||||
{
|
||||
hub_free(cid);
|
||||
hub_free(pid);
|
||||
return status_msg_inf_error_cid_invalid;
|
||||
}
|
||||
|
||||
if (!is_valid_base32_char(pid[pos]))
|
||||
{
|
||||
hub_free(cid);
|
||||
hub_free(pid);
|
||||
return status_msg_inf_error_pid_invalid;
|
||||
}
|
||||
}
|
||||
|
||||
if (!check_hash_tiger(cid, pid))
|
||||
{
|
||||
hub_free(cid);
|
||||
hub_free(pid);
|
||||
return status_msg_inf_error_cid_invalid;
|
||||
}
|
||||
|
||||
/* Set the cid in the user object */
|
||||
memcpy(user->id.cid, cid, MAX_CID_LEN);
|
||||
user->id.cid[MAX_CID_LEN] = 0;
|
||||
|
||||
hub_free(cid);
|
||||
hub_free(pid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int check_required_login_flags(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
num = adc_msg_has_named_argument(cmd, ADC_INF_FLAG_CLIENT_ID);
|
||||
if (num != 1)
|
||||
{
|
||||
if (!num)
|
||||
return status_msg_inf_error_cid_missing;
|
||||
return status_msg_inf_error_cid_invalid;
|
||||
}
|
||||
|
||||
num = adc_msg_has_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);
|
||||
if (num != 1)
|
||||
{
|
||||
if (!num)
|
||||
return status_msg_inf_error_pid_missing;
|
||||
return status_msg_inf_error_pid_invalid;
|
||||
}
|
||||
|
||||
num = adc_msg_has_named_argument(cmd, ADC_INF_FLAG_NICK);
|
||||
if (num != 1)
|
||||
{
|
||||
if (!num)
|
||||
return status_msg_inf_error_nick_missing;
|
||||
return status_msg_inf_error_nick_multiple;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This will check the ip address of the user, and
|
||||
* remove any wrong address, and replace it with the correct one
|
||||
* as seen by the hub.
|
||||
*/
|
||||
static int check_network(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
const char* address = user_get_address(user);
|
||||
|
||||
/* Check for NAT override address */
|
||||
if (acl_is_ip_nat_override(hub->acl, address))
|
||||
{
|
||||
char* client_given_ip = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
|
||||
if (client_given_ip && strcmp(client_given_ip, "0.0.0.0") != 0)
|
||||
{
|
||||
user_set_nat_override(user);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_UDP_PORT);
|
||||
hub_free(client_given_ip);
|
||||
return 0;
|
||||
}
|
||||
hub_free(client_given_ip);
|
||||
}
|
||||
|
||||
if (strchr(address, '.'))
|
||||
{
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_UDP_PORT);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
|
||||
adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR, address);
|
||||
}
|
||||
else if (strchr(address, ':'))
|
||||
{
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_UDP_PORT);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
|
||||
adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR, address);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void strip_network(struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_UDP_PORT);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_UDP_PORT);
|
||||
}
|
||||
|
||||
static int nick_length_ok(const char* nick)
|
||||
{
|
||||
size_t length = strlen(nick);
|
||||
if (length <= 1)
|
||||
{
|
||||
return nick_invalid_short;
|
||||
}
|
||||
|
||||
if (length > MAX_NICK_LEN)
|
||||
{
|
||||
return nick_invalid_long;
|
||||
}
|
||||
|
||||
return nick_ok;
|
||||
}
|
||||
|
||||
|
||||
static int nick_bad_characters(const char* nick)
|
||||
{
|
||||
const char* tmp;
|
||||
|
||||
/* Nick must not start with a space */
|
||||
if (nick[0] == ' ')
|
||||
return nick_invalid_spaces;
|
||||
|
||||
/* Check for ASCII values below 32 */
|
||||
for (tmp = nick; *tmp; tmp++)
|
||||
if ((*tmp < 32) && (*tmp > 0))
|
||||
return nick_invalid_bad_ascii;
|
||||
|
||||
return nick_ok;
|
||||
}
|
||||
|
||||
|
||||
static int nick_is_utf8(const char* nick)
|
||||
{
|
||||
/*
|
||||
* Nick should be valid utf-8, but
|
||||
* perhaps we should check if the nick is unicode normalized?
|
||||
*/
|
||||
if (!is_valid_utf8(nick))
|
||||
return nick_invalid_bad_utf8;
|
||||
return nick_ok;
|
||||
}
|
||||
|
||||
|
||||
static int check_nick(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
char* nick;
|
||||
char* tmp;
|
||||
enum nick_status status;
|
||||
|
||||
tmp = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_NICK);
|
||||
if (!tmp) return 0;
|
||||
nick = adc_msg_unescape(tmp);
|
||||
free(tmp); tmp = 0;
|
||||
if (!nick) return 0;
|
||||
|
||||
status = nick_length_ok(nick);
|
||||
if (status != nick_ok)
|
||||
{
|
||||
hub_free(nick);
|
||||
if (status == nick_invalid_short)
|
||||
return status_msg_inf_error_nick_short;
|
||||
return status_msg_inf_error_nick_long;
|
||||
}
|
||||
|
||||
status = nick_bad_characters(nick);
|
||||
if (status != nick_ok)
|
||||
{
|
||||
hub_free(nick);
|
||||
if (status == nick_invalid_spaces)
|
||||
return status_msg_inf_error_nick_spaces;
|
||||
return status_msg_inf_error_nick_bad_chars;
|
||||
}
|
||||
|
||||
status = nick_is_utf8(nick);
|
||||
if (status != nick_ok)
|
||||
{
|
||||
hub_free(nick);
|
||||
return status_msg_inf_error_nick_not_utf8;
|
||||
}
|
||||
|
||||
if (user_is_connecting(user))
|
||||
{
|
||||
memcpy(user->id.nick, nick, strlen(nick));
|
||||
user->id.nick[strlen(nick)] = 0;
|
||||
}
|
||||
|
||||
hub_free(nick);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int check_logged_in(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
struct hub_user* lookup1 = uman_get_user_by_nick(hub, user->id.nick);
|
||||
struct hub_user* lookup2 = uman_get_user_by_cid(hub, user->id.cid);
|
||||
|
||||
if (lookup1 == user)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lookup1 || lookup2)
|
||||
{
|
||||
if (lookup1 == lookup2)
|
||||
{
|
||||
LOG_DEBUG("check_logged_in: exact same user is logged in: %s", user->id.nick);
|
||||
hub_disconnect_user(hub, lookup1, quit_ghost_timeout);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lookup1)
|
||||
{
|
||||
LOG_DEBUG("check_logged_in: nickname is in use: %s", user->id.nick);
|
||||
return status_msg_inf_error_nick_taken;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("check_logged_in: CID is in use: %s", user->id.cid);
|
||||
return status_msg_inf_error_cid_taken;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* It is possible to do user-agent checking here.
|
||||
* But this is not something we want to do, and is deprecated in the ADC specification.
|
||||
* One should rather look at capabilities/features.
|
||||
*/
|
||||
static int check_user_agent(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
char* ua_encoded = 0;
|
||||
char* ua = 0;
|
||||
|
||||
/* Get client user agent version */
|
||||
ua_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT);
|
||||
if (ua_encoded)
|
||||
{
|
||||
ua = adc_msg_unescape(ua_encoded);
|
||||
if (ua)
|
||||
{
|
||||
memcpy(user->id.user_agent, ua, MIN(strlen(ua), MAX_UA_LEN));
|
||||
hub_free(ua);
|
||||
}
|
||||
}
|
||||
hub_free(ua_encoded);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int check_acl(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
if (acl_is_cid_banned(hub->acl, user->id.cid))
|
||||
{
|
||||
return status_msg_ban_permanently;
|
||||
}
|
||||
|
||||
if (acl_is_user_banned(hub->acl, user->id.nick))
|
||||
{
|
||||
return status_msg_ban_permanently;
|
||||
}
|
||||
|
||||
if (acl_is_user_denied(hub->acl, user->id.nick))
|
||||
{
|
||||
return status_msg_inf_error_nick_restricted;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
char* arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_SIZE);
|
||||
if (arg)
|
||||
{
|
||||
int64_t shared_size = atoll(arg);
|
||||
if (shared_size < 0)
|
||||
shared_size = 0;
|
||||
|
||||
if (user_is_logged_in(user))
|
||||
{
|
||||
hub->users->shared_size -= user->limits.shared_size;
|
||||
hub->users->shared_size += shared_size;
|
||||
}
|
||||
user->limits.shared_size = shared_size;
|
||||
hub_free(arg);
|
||||
arg = 0;
|
||||
}
|
||||
|
||||
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES);
|
||||
if (arg)
|
||||
{
|
||||
int shared_files = atoi(arg);
|
||||
if (shared_files < 0)
|
||||
shared_files = 0;
|
||||
|
||||
if (user_is_logged_in(user))
|
||||
{
|
||||
hub->users->shared_files -= user->limits.shared_files;
|
||||
hub->users->shared_files += shared_files;
|
||||
}
|
||||
user->limits.shared_files = shared_files;
|
||||
hub_free(arg);
|
||||
arg = 0;
|
||||
}
|
||||
|
||||
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL);
|
||||
if (arg)
|
||||
{
|
||||
int num = atoi(arg);
|
||||
if (num < 0) num = 0;
|
||||
user->limits.hub_count_user = num;
|
||||
hub_free(arg);
|
||||
arg = 0;
|
||||
}
|
||||
|
||||
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_REGISTER);
|
||||
if (arg)
|
||||
{
|
||||
int num = atoi(arg);
|
||||
if (num < 0) num = 0;
|
||||
user->limits.hub_count_registered = num;
|
||||
hub_free(arg);
|
||||
arg = 0;
|
||||
}
|
||||
|
||||
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_OPERATOR);
|
||||
if (arg)
|
||||
{
|
||||
int num = atoi(arg);
|
||||
if (num < 0) num = 0;
|
||||
user->limits.hub_count_operator = num;
|
||||
hub_free(arg);
|
||||
arg = 0;
|
||||
}
|
||||
|
||||
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_UPLOAD_SLOTS);
|
||||
if (arg)
|
||||
{
|
||||
int num = atoi(arg);
|
||||
if (num < 0) num = 0;
|
||||
user->limits.upload_slots = num;
|
||||
hub_free(arg);
|
||||
arg = 0;
|
||||
}
|
||||
|
||||
/* summarize total slots */
|
||||
user->limits.hub_count_total = user->limits.hub_count_user + user->limits.hub_count_registered + user->limits.hub_count_operator;
|
||||
|
||||
if (!user_is_protected(user))
|
||||
{
|
||||
if (user->limits.shared_size < hub_get_min_share(hub) && hub_get_min_share(hub))
|
||||
{
|
||||
return status_msg_user_share_size_low;
|
||||
}
|
||||
|
||||
if (user->limits.shared_size > hub_get_max_share(hub) && hub_get_max_share(hub))
|
||||
{
|
||||
return status_msg_user_share_size_high;
|
||||
}
|
||||
|
||||
if ((user->limits.hub_count_user > hub_get_max_hubs_user(hub) && hub_get_max_hubs_user(hub)) ||
|
||||
(user->limits.hub_count_registered > hub_get_max_hubs_reg(hub) && hub_get_max_hubs_reg(hub)) ||
|
||||
(user->limits.hub_count_operator > hub_get_max_hubs_op(hub) && hub_get_max_hubs_op(hub)) ||
|
||||
(user->limits.hub_count_total > hub_get_max_hubs_total(hub) && hub_get_max_hubs_total(hub)))
|
||||
{
|
||||
return status_msg_user_hub_limit_high;
|
||||
}
|
||||
|
||||
if ((user->limits.hub_count_user < hub_get_min_hubs_user(hub) && hub_get_min_hubs_user(hub)) ||
|
||||
(user->limits.hub_count_registered < hub_get_min_hubs_reg(hub) && hub_get_min_hubs_reg(hub)) ||
|
||||
(user->limits.hub_count_operator < hub_get_min_hubs_op(hub) && hub_get_min_hubs_op(hub)))
|
||||
{
|
||||
return status_msg_user_hub_limit_low;
|
||||
}
|
||||
|
||||
if (user->limits.upload_slots < hub_get_min_slots(hub) && hub_get_min_slots(hub))
|
||||
{
|
||||
return status_msg_user_slots_low;
|
||||
}
|
||||
|
||||
if (user->limits.upload_slots > hub_get_max_slots(hub) && hub_get_max_slots(hub))
|
||||
{
|
||||
return status_msg_user_slots_high;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the expected credentials, and returns 1 if authentication is needed,
|
||||
* or 0 if not.
|
||||
* If the hub is configured to allow only registered users and the user
|
||||
* is not recognized this will return 1.
|
||||
*/
|
||||
static int set_credentials(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
int ret = 0;
|
||||
struct auth_info* info = acl_get_access_info(hub, user->id.nick);
|
||||
|
||||
if (info)
|
||||
{
|
||||
user->credentials = info->credentials;
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
user->credentials = auth_cred_guest;
|
||||
}
|
||||
hub_free(info);
|
||||
|
||||
switch (user->credentials)
|
||||
{
|
||||
case auth_cred_none:
|
||||
break;
|
||||
|
||||
case auth_cred_bot:
|
||||
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT);
|
||||
break;
|
||||
|
||||
case auth_cred_guest:
|
||||
/* Nothing to be added to the info message */
|
||||
break;
|
||||
|
||||
case auth_cred_user:
|
||||
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_REGISTERED_USER);
|
||||
break;
|
||||
|
||||
case auth_cred_operator:
|
||||
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR);
|
||||
break;
|
||||
|
||||
case auth_cred_super:
|
||||
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER);
|
||||
break;
|
||||
|
||||
case auth_cred_admin:
|
||||
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_ADMIN);
|
||||
break;
|
||||
|
||||
case auth_cred_link:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int check_is_hub_full(struct hub_info* hub, struct hub_user* user)
|
||||
{
|
||||
/*
|
||||
* If hub is full, don't let users in, but we still want to allow
|
||||
* operators and admins to enter the hub.
|
||||
*/
|
||||
if (hub->config->max_users && hub->users->count >= (size_t) hub->config->max_users && !user_is_protected(user))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int check_registered_users_only(struct hub_info* hub, struct hub_user* user)
|
||||
{
|
||||
if (hub->config->registered_users_only && !user_is_registered(user))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hub_handle_info_common(struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
/* Remove server restricted flags */
|
||||
remove_server_restricted_flags(cmd);
|
||||
|
||||
/* Update/set the feature cast flags. */
|
||||
set_feature_cast_supports(user, cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hub_handle_info_low_bandwidth(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
if (hub->config->low_bandwidth_mode)
|
||||
{
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_REGISTER);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_OPERATOR);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_UPLOAD_SPEED);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_DOWNLOAD_SPEED);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_AUTO_SLOTS);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_AUTO_SLOTS_MAX);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_AWAY);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_DESCRIPTION);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_EMAIL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define INF_CHECK(FUNC, HUB, USER, CMD) \
|
||||
do { \
|
||||
int ret = FUNC(HUB, USER, CMD); \
|
||||
if (ret < 0) \
|
||||
return ret; \
|
||||
} while(0)
|
||||
|
||||
static int hub_perform_login_checks(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
/* Make syntax checks. */
|
||||
INF_CHECK(check_required_login_flags, hub, user, cmd);
|
||||
INF_CHECK(check_cid, hub, user, cmd);
|
||||
INF_CHECK(check_nick, hub, user, cmd);
|
||||
INF_CHECK(check_network, hub, user, cmd);
|
||||
INF_CHECK(check_user_agent, hub, user, cmd);
|
||||
INF_CHECK(check_acl, hub, user, cmd);
|
||||
INF_CHECK(check_logged_in, hub, user, cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform additional INF checks used at time of login.
|
||||
*
|
||||
* @return 0 if success, <0 if error, >0 if authentication needed.
|
||||
*/
|
||||
int hub_handle_info_login(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
int code = 0;
|
||||
|
||||
INF_CHECK(hub_perform_login_checks, hub, user, cmd);
|
||||
|
||||
/* Private ID must never be broadcasted - drop it! */
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);
|
||||
|
||||
code = set_credentials(hub, user, cmd);
|
||||
|
||||
/* Note: this must be done *after* set_credentials. */
|
||||
if (check_is_hub_full(hub, user))
|
||||
{
|
||||
return status_msg_hub_full;
|
||||
}
|
||||
|
||||
if (check_registered_users_only(hub, user))
|
||||
{
|
||||
return status_msg_hub_registered_users_only;
|
||||
}
|
||||
|
||||
INF_CHECK(check_limits, hub, user, cmd);
|
||||
|
||||
/* strip off stuff if low_bandwidth_mode is enabled */
|
||||
hub_handle_info_low_bandwidth(hub, user, cmd);
|
||||
|
||||
/* Set initial user info */
|
||||
user_set_info(user, cmd);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
* If user is in the connecting state, we need to do fairly
|
||||
* strict checking of all arguments.
|
||||
* This means we disconnect users when they provide invalid data
|
||||
* during the login sequence.
|
||||
* When users are merely updating their data after successful login
|
||||
* we can just ignore any invalid data and not broadcast it.
|
||||
*
|
||||
* The data we need to check is:
|
||||
* - nick name (valid, not taken, etc)
|
||||
* - CID/PID (valid, not taken, etc).
|
||||
* - IP addresses (IPv4 and IPv6)
|
||||
*/
|
||||
int hub_handle_info(struct hub_info* hub, struct hub_user* user, const struct adc_message* cmd_unmodified)
|
||||
{
|
||||
int ret;
|
||||
struct adc_message* cmd = adc_msg_copy(cmd_unmodified);
|
||||
if (!cmd) return -1; /* OOM */
|
||||
|
||||
cmd->priority = 1;
|
||||
|
||||
hub_handle_info_common(user, cmd);
|
||||
|
||||
/* If user is logging in, perform more checks,
|
||||
otherwise only a few things need to be checked.
|
||||
*/
|
||||
if (user_is_connecting(user))
|
||||
{
|
||||
/*
|
||||
* Don't allow the user to send multiple INF messages in this stage!
|
||||
* Since that can have serious side-effects.
|
||||
*/
|
||||
if (user->info)
|
||||
{
|
||||
adc_msg_free(cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = hub_handle_info_login(hub, user, cmd);
|
||||
if (ret < 0)
|
||||
{
|
||||
on_login_failure(hub, user, ret);
|
||||
adc_msg_free(cmd);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Post a message, the user has joined */
|
||||
struct event_data post;
|
||||
memset(&post, 0, sizeof(post));
|
||||
post.id = UHUB_EVENT_USER_JOIN;
|
||||
post.ptr = user;
|
||||
post.flags = ret; /* 0 - all OK, 1 - need authentication */
|
||||
event_queue_post(hub->queue, &post);
|
||||
adc_msg_free(cmd);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* These must not be allowed updated, let's remove them! */
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_CLIENT_ID);
|
||||
|
||||
/*
|
||||
* If the nick is not accepted, do not relay it.
|
||||
* Otherwise, the nickname will be updated.
|
||||
*/
|
||||
if (adc_msg_has_named_argument(cmd, ADC_INF_FLAG_NICK))
|
||||
{
|
||||
#ifdef ALLOW_CHANGE_NICK
|
||||
if (!check_nick(hub, user, cmd))
|
||||
#endif
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_NICK);
|
||||
}
|
||||
|
||||
ret = check_limits(hub, user, cmd);
|
||||
if (ret < 0)
|
||||
{
|
||||
on_update_failure(hub, user, ret);
|
||||
adc_msg_free(cmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strip_network(user, cmd);
|
||||
hub_handle_info_low_bandwidth(hub, user, cmd);
|
||||
|
||||
user_update_info(user, cmd);
|
||||
|
||||
if (!adc_msg_is_empty(cmd))
|
||||
{
|
||||
route_message(hub, user, cmd);
|
||||
}
|
||||
|
||||
adc_msg_free(cmd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_INF_PARSER_H
|
||||
#define HAVE_UHUB_INF_PARSER_H
|
||||
|
||||
enum nick_status
|
||||
{
|
||||
nick_ok = 0,
|
||||
nick_invalid_short = -1,
|
||||
nick_invalid_long = -2,
|
||||
nick_invalid_spaces = -3,
|
||||
nick_invalid_bad_ascii = -4,
|
||||
nick_invalid_bad_utf8 = -5,
|
||||
nick_invalid = -6, /* some unknown reason */
|
||||
nick_not_allowed = -7, /* Not allowed according to configuration */
|
||||
nick_banned = -8, /* Nickname is banned */
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle info messages as received from clients.
|
||||
* This can be an initial info message, which might end up requiring password
|
||||
* authentication, etc.
|
||||
* All sorts of validation is performed here.
|
||||
* - Nickname valid?
|
||||
* - CID/PID valid?
|
||||
* - Network IP address valid?
|
||||
*
|
||||
* This can be triggered multiple times, as users can update their information,
|
||||
* in such case nickname and CID/PID changes are not allowed.
|
||||
*
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
extern int hub_handle_info(struct hub_info* hub, struct hub_user* u, const struct adc_message* cmd);
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_INF_PARSER_H */
|
||||
|
||||
-482
@@ -1,482 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
|
||||
static int arg_verbose = 5;
|
||||
static int arg_fork = 0;
|
||||
static int arg_check_config = 0;
|
||||
static int arg_dump_config = 0;
|
||||
static int arg_have_config = 0;
|
||||
static const char* arg_uid = 0;
|
||||
static const char* arg_gid = 0;
|
||||
static const char* arg_config = 0;
|
||||
static const char* arg_log = 0;
|
||||
static const char* arg_pid = 0;
|
||||
static int arg_log_syslog = 0;
|
||||
|
||||
|
||||
#if !defined(WIN32)
|
||||
extern struct hub_info* g_hub;
|
||||
void hub_handle_signal(int sig)
|
||||
{
|
||||
struct hub_info* hub = g_hub;
|
||||
|
||||
switch (sig)
|
||||
{
|
||||
case SIGINT:
|
||||
LOG_INFO("Interrupted. Shutting down...");
|
||||
hub->status = hub_status_shutdown;
|
||||
break;
|
||||
|
||||
case SIGTERM:
|
||||
LOG_INFO("Terminated. Shutting down...");
|
||||
hub->status = hub_status_shutdown;
|
||||
break;
|
||||
|
||||
case SIGPIPE:
|
||||
break;
|
||||
|
||||
case SIGHUP:
|
||||
hub->status = hub_status_restart;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_TRACE("hub_handle_signal(): caught unknown signal: %d", signal);
|
||||
hub->status = hub_status_shutdown;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int signals[] =
|
||||
{
|
||||
SIGINT, /* Interrupt the application */
|
||||
SIGTERM, /* Terminate the application */
|
||||
SIGPIPE, /* prevent sigpipe from kills the application */
|
||||
SIGHUP, /* reload configuration */
|
||||
0
|
||||
};
|
||||
|
||||
void setup_signal_handlers(struct hub_info* hub)
|
||||
{
|
||||
sigset_t sig_set;
|
||||
struct sigaction act;
|
||||
int i;
|
||||
|
||||
sigemptyset(&sig_set);
|
||||
act.sa_mask = sig_set;
|
||||
act.sa_flags = SA_ONSTACK | SA_RESTART;
|
||||
act.sa_handler = hub_handle_signal;
|
||||
|
||||
for (i = 0; signals[i]; i++)
|
||||
{
|
||||
if (sigaction(signals[i], &act, 0) != 0)
|
||||
{
|
||||
LOG_ERROR("Error setting signal handler %d", signals[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void shutdown_signal_handlers(struct hub_info* hub)
|
||||
{
|
||||
}
|
||||
#endif /* !WIN32 */
|
||||
|
||||
|
||||
int main_loop()
|
||||
{
|
||||
struct hub_config configuration;
|
||||
struct acl_handle acl;
|
||||
struct hub_info* hub = 0;
|
||||
|
||||
if (net_initialize() == -1)
|
||||
return -1;
|
||||
|
||||
do
|
||||
{
|
||||
if (hub)
|
||||
{
|
||||
LOG_INFO("Reloading configuration files...");
|
||||
LOG_DEBUG("Hub status: %d", (int) hub->status);
|
||||
|
||||
/* Reinitialize logs */
|
||||
hub_log_shutdown();
|
||||
hub_log_initialize(arg_log, arg_log_syslog);
|
||||
hub_set_log_verbosity(arg_verbose);
|
||||
}
|
||||
|
||||
if (read_config(arg_config, &configuration, !arg_have_config) == -1)
|
||||
return -1;
|
||||
|
||||
if (acl_initialize(&configuration, &acl) == -1)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Don't restart networking when re-reading configuration.
|
||||
* This might not be possible either, since we might have
|
||||
* dropped our privileges to do so.
|
||||
*/
|
||||
if (!hub)
|
||||
{
|
||||
hub = hub_start_service(&configuration);
|
||||
if (!hub)
|
||||
return -1;
|
||||
#if !defined(WIN32)
|
||||
setup_signal_handlers(hub);
|
||||
#endif
|
||||
}
|
||||
|
||||
hub_set_variables(hub, &acl);
|
||||
|
||||
hub_event_loop(hub);
|
||||
|
||||
hub_free_variables(hub);
|
||||
acl_shutdown(&acl);
|
||||
free_config(&configuration);
|
||||
|
||||
} while (hub->status == hub_status_restart);
|
||||
|
||||
#if !defined(WIN32)
|
||||
shutdown_signal_handlers(hub);
|
||||
#endif
|
||||
|
||||
if (hub)
|
||||
{
|
||||
hub_shutdown_service(hub);
|
||||
}
|
||||
|
||||
net_destroy();
|
||||
hub_log_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int check_configuration(int dump)
|
||||
{
|
||||
struct hub_config configuration;
|
||||
int ret = read_config(arg_config, &configuration, 0);
|
||||
|
||||
if (dump)
|
||||
{
|
||||
if (ret != -1)
|
||||
{
|
||||
dump_config(&configuration, dump > 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, "ERROR\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stdout, "OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void print_version()
|
||||
{
|
||||
fprintf(stdout, PRODUCT_STRING "\n");
|
||||
fprintf(stdout, COPYRIGHT "\n"
|
||||
"This is free software with ABSOLUTELY NO WARRANTY.\n\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
void print_usage(char* program)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [options]\n\n", program);
|
||||
fprintf(stderr,
|
||||
"Options:\n"
|
||||
" -v Verbose mode. Add more -v's for higher verbosity.\n"
|
||||
" -q Quiet mode - no output\n"
|
||||
" -f Fork to background\n"
|
||||
" -l <file> Log messages to given file (default: stderr)\n"
|
||||
" -L Log messages to syslog\n"
|
||||
" -c <file> Specify configuration file (default: " SERVER_CONFIG ")\n"
|
||||
" -C Check configuration and return\n"
|
||||
" -s Show configuration parameters\n"
|
||||
" -S Show configuration parameters, but ignore defaults\n"
|
||||
" -h This message\n"
|
||||
#ifndef WIN32
|
||||
" -u <user> Run as given user\n"
|
||||
" -g <group> Run with given group permissions\n"
|
||||
" -p <file> Store pid in file (process id)\n"
|
||||
#endif
|
||||
" -V Show version number.\n"
|
||||
);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
void parse_command_line(int argc, char** argv)
|
||||
{
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "vqfc:l:hu:g:VCsSLp:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'V':
|
||||
print_version();
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
arg_verbose++;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
arg_verbose -= 99;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
arg_fork = 1;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
arg_config = optarg;
|
||||
arg_have_config = 1;
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
arg_check_config = 1;
|
||||
arg_have_config = 1;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
arg_dump_config = 1;
|
||||
arg_check_config = 1;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
arg_dump_config = 2;
|
||||
arg_check_config = 1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
arg_log = optarg;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
arg_log_syslog = 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
print_usage(argv[0]);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
arg_uid = optarg;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
arg_gid = optarg;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
arg_pid = optarg;
|
||||
break;
|
||||
|
||||
default:
|
||||
print_usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (arg_config == NULL)
|
||||
{
|
||||
arg_config = SERVER_CONFIG;
|
||||
}
|
||||
|
||||
hub_log_initialize(arg_log, arg_log_syslog);
|
||||
hub_set_log_verbosity(arg_verbose);
|
||||
}
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
int drop_privileges()
|
||||
{
|
||||
struct group* perm_group = 0;
|
||||
struct passwd* perm_user = 0;
|
||||
gid_t perm_gid = 0;
|
||||
uid_t perm_uid = 0;
|
||||
int gid_ok = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (arg_gid)
|
||||
{
|
||||
ret = 0;
|
||||
while ((perm_group = getgrent()) != NULL)
|
||||
{
|
||||
if (strcmp(perm_group->gr_name, arg_gid) == 0)
|
||||
{
|
||||
perm_gid = perm_group->gr_gid;
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
endgrent();
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
LOG_FATAL("Unable to determine group id, check group name.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_TRACE("Setting group id %d (%s)", (int) perm_gid, arg_gid);
|
||||
ret = setgid(perm_gid);
|
||||
if (ret == -1)
|
||||
{
|
||||
LOG_FATAL("Unable to change group id, permission denied.");
|
||||
return -1;
|
||||
}
|
||||
gid_ok = 1;
|
||||
}
|
||||
|
||||
if (arg_uid)
|
||||
{
|
||||
ret = 0;
|
||||
while ((perm_user = getpwent()) != NULL)
|
||||
{
|
||||
if (strcmp(perm_user->pw_name, arg_uid) == 0)
|
||||
{
|
||||
perm_uid = perm_user->pw_uid;
|
||||
if (!gid_ok)
|
||||
perm_gid = perm_user->pw_gid;
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
endpwent();
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
LOG_FATAL("Unable to determine user id, check user name.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!gid_ok) {
|
||||
LOG_TRACE("Setting group id %d (%s)", (int) perm_gid, arg_gid);
|
||||
ret = setgid(perm_gid);
|
||||
if (ret == -1)
|
||||
{
|
||||
LOG_FATAL("Unable to change group id, permission denied.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_TRACE("Setting user id %d (%s)", (int) perm_uid, arg_uid);
|
||||
ret = setuid(perm_uid);
|
||||
if (ret == -1)
|
||||
{
|
||||
LOG_FATAL("Unable to change user id, permission denied.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pidfile_create()
|
||||
{
|
||||
if (arg_pid)
|
||||
{
|
||||
FILE* pidfile = fopen(arg_pid, "w");
|
||||
if (!pidfile)
|
||||
{
|
||||
LOG_FATAL("Unable to write pid file: %s\n", arg_pid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(pidfile, "%d", (int) getpid());
|
||||
fclose(pidfile);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pidfile_destroy()
|
||||
{
|
||||
if (arg_pid)
|
||||
{
|
||||
return unlink(arg_pid);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
parse_command_line(argc, argv);
|
||||
|
||||
if (arg_check_config)
|
||||
{
|
||||
return check_configuration(arg_dump_config);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
if (arg_fork)
|
||||
{
|
||||
ret = fork();
|
||||
if (ret == -1)
|
||||
{
|
||||
LOG_FATAL("Unable to fork to background!");
|
||||
return -1;
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
/* child process - detatch from TTY */
|
||||
fclose(stdin);
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* parent process */
|
||||
LOG_DEBUG("Forked to background\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pidfile_create() == -1)
|
||||
return -1;
|
||||
|
||||
if (drop_privileges() == -1)
|
||||
return -1;
|
||||
#endif /* WIN32 */
|
||||
|
||||
ret = main_loop();
|
||||
|
||||
#ifndef WIN32
|
||||
pidfile_destroy();
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,220 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <uhub.h>
|
||||
#include "hubio.h"
|
||||
#include "probe.h"
|
||||
|
||||
/* FIXME: This should not be needed! */
|
||||
extern struct hub_info* g_hub;
|
||||
|
||||
int handle_net_read(struct hub_user* user)
|
||||
{
|
||||
static char buf[MAX_RECV_BUF];
|
||||
struct hub_recvq* q = user->recv_queue;
|
||||
size_t buf_size = hub_recvq_get(q, buf, MAX_RECV_BUF);
|
||||
ssize_t size;
|
||||
|
||||
if (user_flag_get(user, flag_maxbuf))
|
||||
buf_size = 0;
|
||||
size = net_con_recv(user->connection, buf + buf_size, MAX_RECV_BUF - buf_size);
|
||||
|
||||
if (size > 0)
|
||||
buf_size += size;
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
if (size == -1)
|
||||
return quit_disconnected;
|
||||
else
|
||||
return quit_socket_error;
|
||||
}
|
||||
else if (size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
char* lastPos = 0;
|
||||
char* start = buf;
|
||||
char* pos = 0;
|
||||
size_t remaining = buf_size;
|
||||
|
||||
while ((pos = memchr(start, '\n', remaining)))
|
||||
{
|
||||
lastPos = pos;
|
||||
pos[0] = '\0';
|
||||
|
||||
#ifdef DEBUG_SENDQ
|
||||
LOG_DUMP("PROC: \"%s\" (%d)\n", start, (int) (pos - start));
|
||||
#endif
|
||||
|
||||
if (user_flag_get(user, flag_maxbuf))
|
||||
{
|
||||
user_flag_unset(user, flag_maxbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((pos - start) > 0) && g_hub->config->max_recv_buffer > (pos - start))
|
||||
{
|
||||
if (hub_handle_message(g_hub, user, start, (pos - start)) == -1)
|
||||
{
|
||||
return quit_protocol_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pos[0] = '\n'; /* FIXME: not needed */
|
||||
pos ++;
|
||||
remaining -= (pos - start);
|
||||
start = pos;
|
||||
}
|
||||
|
||||
if (lastPos || remaining)
|
||||
{
|
||||
if (remaining < (size_t) g_hub->config->max_recv_buffer)
|
||||
{
|
||||
hub_recvq_set(q, lastPos ? lastPos : buf, remaining);
|
||||
}
|
||||
else
|
||||
{
|
||||
hub_recvq_set(q, 0, 0);
|
||||
user_flag_set(user, flag_maxbuf);
|
||||
LOG_WARN("Received message past max_recv_buffer, dropping message.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hub_recvq_set(q, 0, 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_net_write(struct hub_user* user)
|
||||
{
|
||||
int ret = 0;
|
||||
while (hub_sendq_get_bytes(user->send_queue))
|
||||
{
|
||||
ret = hub_sendq_send(user->send_queue, user);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
return quit_socket_error;
|
||||
|
||||
if (hub_sendq_get_bytes(user->send_queue))
|
||||
{
|
||||
user_net_io_want_write(user);
|
||||
}
|
||||
else
|
||||
{
|
||||
user_net_io_want_read(user);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void net_event(struct net_connection* con, int event, void *arg)
|
||||
{
|
||||
struct hub_user* user = (struct hub_user*) arg;
|
||||
int flag_close = 0;
|
||||
|
||||
#ifdef DEBUG_SENDQ
|
||||
LOG_TRACE("net_event() : fd=%d, ev=%d, arg=%p", con->sd, (int) event, arg);
|
||||
#endif
|
||||
|
||||
if (event == NET_EVENT_TIMEOUT)
|
||||
{
|
||||
if (user_is_connecting(user))
|
||||
{
|
||||
hub_disconnect_user(g_hub, user, quit_timeout);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (event & NET_EVENT_READ)
|
||||
{
|
||||
flag_close = handle_net_read(user);
|
||||
if (flag_close)
|
||||
{
|
||||
hub_disconnect_user(g_hub, user, flag_close);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (event & NET_EVENT_WRITE)
|
||||
{
|
||||
flag_close = handle_net_write(user);
|
||||
if (flag_close)
|
||||
{
|
||||
hub_disconnect_user(g_hub, user, flag_close);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void net_on_accept(struct net_connection* con, int event, void *arg)
|
||||
{
|
||||
struct hub_info* hub = (struct hub_info*) arg;
|
||||
struct hub_probe* probe = 0;
|
||||
struct ip_addr_encap ipaddr;
|
||||
int server_fd = net_con_get_sd(con);
|
||||
plugin_st status;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int fd = net_accept(server_fd, &ipaddr);
|
||||
if (fd == -1)
|
||||
{
|
||||
#ifdef WINSOCK
|
||||
if (net_error() == WSAEWOULDBLOCK)
|
||||
#else
|
||||
if (net_error() == EWOULDBLOCK)
|
||||
#endif
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Accept error: %d %s", net_error(), strerror(net_error()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
status = plugin_check_ip_early(hub, &ipaddr);
|
||||
if (status == st_deny)
|
||||
{
|
||||
plugin_log_connection_denied(hub, &ipaddr);
|
||||
net_close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
plugin_log_connection_accepted(hub, &ipaddr);
|
||||
|
||||
probe = probe_create(hub, fd, &ipaddr);
|
||||
if (!probe)
|
||||
{
|
||||
LOG_ERROR("Unable to create probe after socket accepted. Out of memory?");
|
||||
net_close(fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_NET_EVENT_H
|
||||
#define HAVE_UHUB_NET_EVENT_H
|
||||
|
||||
/**
|
||||
* Network callback to accept incoming connections.
|
||||
*/
|
||||
extern void net_on_accept(struct net_connection* con, int event, void *arg);
|
||||
extern void net_event(struct net_connection* con, int event, void *arg);
|
||||
|
||||
extern int handle_net_read(struct hub_user* user);
|
||||
extern int handle_net_write(struct hub_user* user);
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_NET_EVENT_H */
|
||||
|
||||
@@ -1,162 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
#include "plugin_api/command_api.h"
|
||||
|
||||
struct plugin_callback_data
|
||||
{
|
||||
struct linked_list* commands;
|
||||
};
|
||||
|
||||
static struct plugin_callback_data* get_callback_data(struct plugin_handle* plugin)
|
||||
{
|
||||
struct plugin_callback_data* data;
|
||||
uhub_assert(plugin && plugin->handle && plugin->handle->internals);
|
||||
data = (struct plugin_callback_data*) plugin->handle->internals;
|
||||
return data;
|
||||
}
|
||||
|
||||
static int plugin_command_dispatch(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct plugin_handle* plugin = (struct plugin_handle*) cmd->ptr;
|
||||
struct plugin_callback_data* data = get_callback_data(plugin);
|
||||
struct plugin_command_handle* cmdh;
|
||||
struct plugin_user* puser = (struct plugin_user*) user; // FIXME: Use a proper conversion function instead.
|
||||
struct plugin_command* pcommand = (struct plugin_command*) cmd; // FIXME: Use a proper conversion function instead.
|
||||
|
||||
LOG_PLUGIN("plugin_command_dispatch: cmd=%s", cmd->prefix);
|
||||
|
||||
cmdh = (struct plugin_command_handle*) list_get_first(data->commands);
|
||||
while (cmdh)
|
||||
{
|
||||
if (strcmp(cmdh->prefix, cmd->prefix) == 0)
|
||||
return cmdh->handler(plugin, puser, pcommand);
|
||||
|
||||
cmdh = (struct plugin_command_handle*) list_get_next(data->commands);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct plugin_callback_data* plugin_callback_data_create()
|
||||
{
|
||||
struct plugin_callback_data* data = (struct plugin_callback_data*) hub_malloc_zero(sizeof(struct plugin_callback_data));
|
||||
LOG_PLUGIN("plugin_callback_data_create()");
|
||||
data->commands = list_create();
|
||||
return data;
|
||||
}
|
||||
|
||||
void plugin_callback_data_destroy(struct plugin_callback_data* data)
|
||||
{
|
||||
LOG_PLUGIN("plugin_callback_data_destroy()");
|
||||
if (data->commands)
|
||||
{
|
||||
uhub_assert(list_size(data->commands) == 0);
|
||||
list_destroy(data->commands);
|
||||
}
|
||||
|
||||
hub_free(data);
|
||||
}
|
||||
|
||||
static struct hub_user* convert_user_type(struct plugin_user* user)
|
||||
{
|
||||
struct hub_user* huser = (struct hub_user*) user;
|
||||
return huser;
|
||||
}
|
||||
|
||||
static int cbfunc_send_message(struct plugin_handle* plugin, struct plugin_user* user, const char* message)
|
||||
{
|
||||
// struct plugin_callback_data* data = get_callback_data(plugin);
|
||||
char* buffer = adc_msg_escape(message);
|
||||
struct adc_message* command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
|
||||
adc_msg_add_argument(command, buffer);
|
||||
route_to_user(plugin_get_hub(plugin), convert_user_type(user), command);
|
||||
adc_msg_free(command);
|
||||
hub_free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cbfunc_send_status(struct plugin_handle* plugin, struct plugin_user* user, int code, const char* message)
|
||||
{
|
||||
// struct plugin_callback_data* data = get_callback_data(plugin);
|
||||
char code_str[4];
|
||||
char* buffer = adc_msg_escape(message);
|
||||
struct adc_message* command = adc_msg_construct(ADC_CMD_ISTA, strlen(buffer) + 10);
|
||||
snprintf(code_str, sizeof(code_str), "%03d", code);
|
||||
adc_msg_add_argument(command, code_str);
|
||||
adc_msg_add_argument(command, buffer);
|
||||
route_to_user(plugin_get_hub(plugin), convert_user_type(user), command);
|
||||
adc_msg_free(command);
|
||||
hub_free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cbfunc_user_disconnect(struct plugin_handle* plugin, struct plugin_user* user)
|
||||
{
|
||||
// struct plugin_callback_data* data = get_callback_data(plugin);
|
||||
hub_disconnect_user(plugin_get_hub(plugin), convert_user_type(user), quit_kicked);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbfunc_command_add(struct plugin_handle* plugin, struct plugin_command_handle* cmdh)
|
||||
{
|
||||
struct plugin_callback_data* data = get_callback_data(plugin);
|
||||
struct command_handle* command = (struct command_handle*) hub_malloc_zero(sizeof(struct command_handle));
|
||||
|
||||
command->prefix = cmdh->prefix;
|
||||
command->length = cmdh->length;
|
||||
command->args = cmdh->args;
|
||||
command->cred = cmdh->cred;
|
||||
command->description = cmdh->description;
|
||||
command->origin = cmdh->origin;
|
||||
command->handler = plugin_command_dispatch;
|
||||
|
||||
cmdh->internal_handle = command;
|
||||
list_append(data->commands, cmdh);
|
||||
command_add(plugin_get_hub(plugin)->commands, command, (void*) plugin);
|
||||
printf("*** Add plugin command: %s (%p, %p)\n", command->prefix, command, cmdh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cbfunc_command_del(struct plugin_handle* plugin, struct plugin_command_handle* cmdh)
|
||||
{
|
||||
struct plugin_callback_data* data = get_callback_data(plugin);
|
||||
struct command_handle* command = (struct command_handle*) cmdh->internal_handle;
|
||||
|
||||
printf("*** Del plugin command: %s (%p, %p)\n", command->prefix, command, cmdh);
|
||||
list_remove(data->commands, cmdh);
|
||||
command_del(plugin_get_hub(plugin)->commands, command);
|
||||
hub_free(command);
|
||||
cmdh->internal_handle = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void plugin_register_callback_functions(struct plugin_handle* handle)
|
||||
{
|
||||
handle->hub.send_message = cbfunc_send_message;
|
||||
handle->hub.send_status_message = cbfunc_send_status;
|
||||
handle->hub.user_disconnect = cbfunc_user_disconnect;
|
||||
handle->hub.command_add = cbfunc_command_add;
|
||||
handle->hub.command_del = cbfunc_command_del;
|
||||
}
|
||||
|
||||
void plugin_unregister_callback_functions(struct plugin_handle* handle)
|
||||
{
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_PLUGIN_CALLBACK_H
|
||||
#define HAVE_UHUB_PLUGIN_CALLBACK_H
|
||||
|
||||
struct plugin_handle;
|
||||
struct uhub_plugin;
|
||||
|
||||
extern struct plugin_callback_data* plugin_callback_data_create();
|
||||
extern void plugin_callback_data_destroy(struct plugin_callback_data* data);
|
||||
|
||||
extern void plugin_register_callback_functions(struct plugin_handle* plugin);
|
||||
extern void plugin_unregister_callback_functions(struct plugin_handle* plugin);
|
||||
|
||||
#endif /* HAVE_UHUB_PLUGIN_CALLBACK_H */
|
||||
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
#include "plugin_api/handle.h"
|
||||
|
||||
#define PLUGIN_DEBUG(hub, name) LOG_PLUGIN("Invoke %s on %d plugins", name, (int) (hub->plugins ? list_size(hub->plugins->loaded) : -1));
|
||||
|
||||
|
||||
#define INVOKE(HUB, FUNCNAME, CODE) \
|
||||
PLUGIN_DEBUG(HUB, # FUNCNAME) \
|
||||
if (HUB->plugins && HUB->plugins->loaded) \
|
||||
{ \
|
||||
struct plugin_handle* plugin = (struct plugin_handle*) list_get_first(HUB->plugins->loaded); \
|
||||
while (plugin) \
|
||||
{ \
|
||||
if (plugin->funcs.FUNCNAME) \
|
||||
CODE \
|
||||
plugin = (struct plugin_handle*) list_get_next(HUB->plugins->loaded); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define PLUGIN_INVOKE_STATUS_1(HUB, FUNCNAME, ARG1) \
|
||||
do { \
|
||||
plugin_st status = st_default; \
|
||||
INVOKE(HUB, FUNCNAME, { \
|
||||
status = plugin->funcs.FUNCNAME(plugin, ARG1); \
|
||||
if (status != st_default) \
|
||||
break; \
|
||||
}); \
|
||||
return status; \
|
||||
} while(0)
|
||||
|
||||
#define PLUGIN_INVOKE_STATUS_2(HUB, FUNCNAME, ARG1, ARG2) \
|
||||
do { \
|
||||
plugin_st status = st_default; \
|
||||
INVOKE(HUB, FUNCNAME, { \
|
||||
status = plugin->funcs.FUNCNAME(plugin, ARG1, ARG2); \
|
||||
if (status != st_default) \
|
||||
break; \
|
||||
}); \
|
||||
return status; \
|
||||
} while(0)
|
||||
|
||||
#define PLUGIN_INVOKE_STATUS_3(HUB, FUNCNAME, ARG1, ARG2, ARG3) \
|
||||
do { \
|
||||
plugin_st status = st_default; \
|
||||
INVOKE(HUB, FUNCNAME, { \
|
||||
status = plugin->funcs.FUNCNAME(plugin, ARG1, ARG2, ARG3); \
|
||||
if (status != st_default) \
|
||||
break; \
|
||||
}); \
|
||||
return status; \
|
||||
} while(0)
|
||||
|
||||
#define PLUGIN_INVOKE_1(HUB, FUNCNAME, ARG1) INVOKE(HUB, FUNCNAME, { plugin->funcs.FUNCNAME(plugin, ARG1); })
|
||||
#define PLUGIN_INVOKE_2(HUB, FUNCNAME, ARG1, ARG2) INVOKE(HUB, FUNCNAME, { plugin->funcs.FUNCNAME(plugin, ARG1, ARG2); })
|
||||
#define PLUGIN_INVOKE_3(HUB, FUNCNAME, ARG1, ARG2, ARG3) INVOKE(HUB, FUNCNAME, { plugin->funcs.FUNCNAME(plugin, ARG1, ARG2, ARG3); })
|
||||
|
||||
|
||||
static struct plugin_user* convert_user_type(struct hub_user* user)
|
||||
{
|
||||
struct plugin_user* puser = (struct plugin_user*) user;
|
||||
return puser;
|
||||
}
|
||||
|
||||
plugin_st plugin_check_ip_early(struct hub_info* hub, struct ip_addr_encap* addr)
|
||||
{
|
||||
PLUGIN_INVOKE_STATUS_1(hub, login_check_ip_early, addr);
|
||||
}
|
||||
|
||||
plugin_st plugin_check_ip_late(struct hub_info* hub, struct ip_addr_encap* addr)
|
||||
{
|
||||
PLUGIN_INVOKE_STATUS_1(hub, login_check_ip_late, addr);
|
||||
}
|
||||
|
||||
void plugin_log_connection_accepted(struct hub_info* hub, struct ip_addr_encap* ipaddr)
|
||||
{
|
||||
PLUGIN_INVOKE_1(hub, on_connection_accepted, ipaddr);
|
||||
}
|
||||
|
||||
void plugin_log_connection_denied(struct hub_info* hub, struct ip_addr_encap* ipaddr)
|
||||
{
|
||||
PLUGIN_INVOKE_1(hub, on_connection_refused, ipaddr);
|
||||
}
|
||||
|
||||
void plugin_log_user_login_success(struct hub_info* hub, struct hub_user* who)
|
||||
{
|
||||
struct plugin_user* user = convert_user_type(who);
|
||||
PLUGIN_INVOKE_1(hub, on_user_login, user);
|
||||
}
|
||||
|
||||
void plugin_log_user_login_error(struct hub_info* hub, struct hub_user* who, const char* reason)
|
||||
{
|
||||
struct plugin_user* user = convert_user_type(who);
|
||||
PLUGIN_INVOKE_2(hub, on_user_login_error, user, reason);
|
||||
}
|
||||
|
||||
void plugin_log_user_logout(struct hub_info* hub, struct hub_user* who, const char* reason)
|
||||
{
|
||||
struct plugin_user* user = convert_user_type(who);
|
||||
PLUGIN_INVOKE_2(hub, on_user_logout, user, reason);
|
||||
}
|
||||
|
||||
void plugin_log_user_nick_change(struct hub_info* hub, struct hub_user* who, const char* new_nick)
|
||||
{
|
||||
struct plugin_user* user = convert_user_type(who);
|
||||
PLUGIN_INVOKE_2(hub, on_user_nick_change, user, new_nick);
|
||||
}
|
||||
|
||||
void plugin_log_user_update_error(struct hub_info* hub, struct hub_user* who, const char* reason)
|
||||
{
|
||||
struct plugin_user* user = convert_user_type(who);
|
||||
PLUGIN_INVOKE_2(hub, on_user_update_error, user, reason);
|
||||
}
|
||||
|
||||
void plugin_log_chat_message(struct hub_info* hub, struct hub_user* who, const char* message, int flags)
|
||||
{
|
||||
struct plugin_user* user = convert_user_type(who);
|
||||
PLUGIN_INVOKE_3(hub, on_user_chat_message, user, message, flags);
|
||||
}
|
||||
|
||||
plugin_st plugin_handle_chat_message(struct hub_info* hub, struct hub_user* from, const char* message, int flags)
|
||||
{
|
||||
struct plugin_user* user = convert_user_type(from);
|
||||
PLUGIN_INVOKE_STATUS_2(hub, on_chat_msg, user, message);
|
||||
}
|
||||
|
||||
plugin_st plugin_handle_private_message(struct hub_info* hub, struct hub_user* from, struct hub_user* to, const char* message, int flags)
|
||||
{
|
||||
struct plugin_user* user1 = convert_user_type(from);
|
||||
struct plugin_user* user2 = convert_user_type(to);
|
||||
PLUGIN_INVOKE_STATUS_3(hub, on_private_msg, user1, user2, message);
|
||||
}
|
||||
|
||||
plugin_st plugin_handle_search(struct hub_info* hub, struct hub_user* from, const char* data)
|
||||
{
|
||||
struct plugin_user* user = convert_user_type(from);
|
||||
PLUGIN_INVOKE_STATUS_2(hub, on_search, user, data);
|
||||
}
|
||||
|
||||
plugin_st plugin_handle_search_result(struct hub_info* hub, struct hub_user* from, struct hub_user* to, const char* data)
|
||||
{
|
||||
struct plugin_user* user1 = convert_user_type(from);
|
||||
struct plugin_user* user2 = convert_user_type(to);
|
||||
PLUGIN_INVOKE_STATUS_3(hub, on_search_result, user1, user2, data);
|
||||
}
|
||||
|
||||
plugin_st plugin_handle_connect(struct hub_info* hub, struct hub_user* from, struct hub_user* to)
|
||||
{
|
||||
struct plugin_user* user1 = convert_user_type(from);
|
||||
struct plugin_user* user2 = convert_user_type(to);
|
||||
PLUGIN_INVOKE_STATUS_2(hub, on_p2p_connect, user1, user2);
|
||||
}
|
||||
|
||||
plugin_st plugin_handle_revconnect(struct hub_info* hub, struct hub_user* from, struct hub_user* to)
|
||||
{
|
||||
struct plugin_user* user1 = convert_user_type(from);
|
||||
struct plugin_user* user2 = convert_user_type(to);
|
||||
PLUGIN_INVOKE_STATUS_2(hub, on_p2p_revconnect, user1, user2);
|
||||
}
|
||||
|
||||
plugin_st plugin_auth_get_user(struct hub_info* hub, const char* nickname, struct auth_info* info)
|
||||
{
|
||||
PLUGIN_INVOKE_STATUS_2(hub, auth_get_user, nickname, info);
|
||||
}
|
||||
|
||||
plugin_st plugin_auth_register_user(struct hub_info* hub, struct auth_info* info)
|
||||
{
|
||||
PLUGIN_INVOKE_STATUS_1(hub, auth_register_user, info);
|
||||
}
|
||||
|
||||
plugin_st plugin_auth_update_user(struct hub_info* hub, struct auth_info* info)
|
||||
{
|
||||
PLUGIN_INVOKE_STATUS_1(hub, auth_update_user, info);
|
||||
}
|
||||
|
||||
plugin_st plugin_auth_delete_user(struct hub_info* hub, struct auth_info* info)
|
||||
{
|
||||
PLUGIN_INVOKE_STATUS_1(hub, auth_delete_user, info);
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_PLUGIN_INVOKE_H
|
||||
#define HAVE_UHUB_PLUGIN_INVOKE_H
|
||||
|
||||
#include "uhub.h"
|
||||
#include "plugin_api/handle.h"
|
||||
|
||||
struct hub_info;
|
||||
struct ip_addr_encap;
|
||||
|
||||
/* All log related functions */
|
||||
void plugin_log_connection_accepted(struct hub_info* hub, struct ip_addr_encap* addr);
|
||||
void plugin_log_connection_denied(struct hub_info* hub, struct ip_addr_encap* addr);
|
||||
void plugin_log_user_login_success(struct hub_info* hub, struct hub_user* user);
|
||||
void plugin_log_user_login_error(struct hub_info* hub, struct hub_user* user, const char* reason);
|
||||
void plugin_log_user_logout(struct hub_info* hub, struct hub_user* user, const char* reason);
|
||||
void plugin_log_user_nick_change(struct hub_info* hub, struct hub_user* user, const char* new_nick);
|
||||
void plugin_log_user_update_error(struct hub_info* hub, struct hub_user* user, const char* reason);
|
||||
void plugin_log_chat_message(struct hub_info* hub, struct hub_user* from, const char* message, int flags);
|
||||
|
||||
/* IP ban related */
|
||||
plugin_st plugin_check_ip_early(struct hub_info* hub, struct ip_addr_encap* addr);
|
||||
plugin_st plugin_check_ip_late(struct hub_info* hub, struct ip_addr_encap* addr);
|
||||
|
||||
/* Nickname allow/deny handling */
|
||||
plugin_st plugin_check_nickname_valid(struct hub_info* hub, const char* nick);
|
||||
plugin_st plugin_check_nickname_reserved(struct hub_info* hub, const char* nick);
|
||||
|
||||
/* Handle chat messages */
|
||||
plugin_st plugin_handle_chat_message(struct hub_info* hub, struct hub_user* from, const char* message, int flags);
|
||||
plugin_st plugin_handle_private_message(struct hub_info* hub, struct hub_user* from, struct hub_user* to, const char* message, int flags);
|
||||
|
||||
/* Handle searches */
|
||||
plugin_st plugin_handle_search(struct hub_info* hub, struct hub_user* user, const char* data);
|
||||
plugin_st plugin_handle_search_result(struct hub_info* hub, struct hub_user* from, struct hub_user* to, const char* data);
|
||||
|
||||
/* Handle p2p connections */
|
||||
plugin_st plugin_handle_connect(struct hub_info* hub, struct hub_user* from, struct hub_user* to);
|
||||
plugin_st plugin_handle_revconnect(struct hub_info* hub, struct hub_user* from, struct hub_user* to);
|
||||
|
||||
/* Authentication related */
|
||||
plugin_st plugin_auth_get_user(struct hub_info* hub, const char* nickname, struct auth_info* info);
|
||||
plugin_st plugin_auth_register_user(struct hub_info* hub, struct auth_info* user);
|
||||
plugin_st plugin_auth_update_user(struct hub_info* hub, struct auth_info* user);
|
||||
plugin_st plugin_auth_delete_user(struct hub_info* hub, struct auth_info* user);
|
||||
|
||||
#endif // HAVE_UHUB_PLUGIN_INVOKE_H
|
||||
|
||||
@@ -1,258 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
|
||||
#include "plugin_api/handle.h"
|
||||
|
||||
struct plugin_callback_data;
|
||||
|
||||
struct plugin_hub_internals
|
||||
{
|
||||
struct hub_info* hub;
|
||||
plugin_unregister_f unregister; /* The unregister function. */
|
||||
struct plugin_callback_data* callback_data; /* callback data that is unique for the plugin */
|
||||
};
|
||||
|
||||
static struct plugin_hub_internals* get_internals(struct plugin_handle* handle)
|
||||
{
|
||||
struct plugin_hub_internals* internals;
|
||||
assert(handle && handle->handle && handle->handle->internals);
|
||||
internals = (struct plugin_hub_internals*) handle->handle->internals;
|
||||
return internals;
|
||||
}
|
||||
|
||||
struct uhub_plugin* plugin_open(const char* filename)
|
||||
{
|
||||
struct uhub_plugin* plugin;
|
||||
LOG_PLUGIN("plugin_open: \"%s\"", filename);
|
||||
|
||||
plugin = (struct uhub_plugin*) hub_malloc_zero(sizeof(struct uhub_plugin));
|
||||
if (!plugin)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DLOPEN
|
||||
plugin->handle = dlopen(filename, RTLD_LAZY);
|
||||
#else
|
||||
plugin->handle = LoadLibraryExA(filename, NULL, 0);
|
||||
#endif
|
||||
|
||||
if (!plugin->handle)
|
||||
{
|
||||
#ifdef HAVE_DLOPEN
|
||||
LOG_ERROR("Unable to open plugin %s: %s", filename, dlerror());
|
||||
#else
|
||||
LOG_ERROR("Unable to open plugin %s: %d", filename, GetLastError());
|
||||
#endif
|
||||
hub_free(plugin);
|
||||
return 0;
|
||||
}
|
||||
|
||||
plugin->filename = strdup(filename);
|
||||
plugin->internals = hub_malloc_zero(sizeof(struct plugin_hub_internals));
|
||||
return plugin;
|
||||
}
|
||||
|
||||
void plugin_close(struct uhub_plugin* plugin)
|
||||
{
|
||||
struct plugin_hub_internals* internals = (struct plugin_hub_internals*) plugin->internals;
|
||||
|
||||
LOG_PLUGIN("plugin_close: \"%s\"", plugin->filename);
|
||||
plugin_callback_data_destroy(internals->callback_data);
|
||||
hub_free(internals);
|
||||
plugin->internals = NULL;
|
||||
|
||||
#ifdef HAVE_DLOPEN
|
||||
dlclose(plugin->handle);
|
||||
#else
|
||||
FreeLibrary((HMODULE) plugin->handle);
|
||||
#endif
|
||||
hub_free(plugin->filename);
|
||||
hub_free(plugin);
|
||||
}
|
||||
|
||||
void* plugin_lookup_symbol(struct uhub_plugin* plugin, const char* symbol)
|
||||
{
|
||||
#ifdef HAVE_DLOPEN
|
||||
void* addr = dlsym(plugin->handle, symbol);
|
||||
return addr;
|
||||
#else
|
||||
FARPROC addr = GetProcAddress((HMODULE) plugin->handle, symbol);
|
||||
return (void*) addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct plugin_handle* plugin_load(const char* filename, const char* config, struct hub_info* hub)
|
||||
{
|
||||
plugin_register_f register_f;
|
||||
plugin_unregister_f unregister_f;
|
||||
int ret;
|
||||
struct plugin_handle* handle = (struct plugin_handle*) hub_malloc_zero(sizeof(struct plugin_handle));
|
||||
struct uhub_plugin* plugin = plugin_open(filename);
|
||||
struct plugin_hub_internals* internals = (struct plugin_hub_internals*) plugin->internals;
|
||||
|
||||
if (!plugin)
|
||||
return NULL;
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
plugin_close(plugin);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle->handle = plugin;
|
||||
register_f = plugin_lookup_symbol(plugin, "plugin_register");
|
||||
unregister_f = plugin_lookup_symbol(plugin, "plugin_unregister");
|
||||
|
||||
// register hub internals
|
||||
internals->unregister = unregister_f;
|
||||
internals->hub = hub;
|
||||
internals->callback_data = plugin_callback_data_create();
|
||||
|
||||
// setup callback functions, where the plugin can contact the hub.
|
||||
plugin_register_callback_functions(handle);
|
||||
|
||||
if (register_f && unregister_f)
|
||||
{
|
||||
ret = register_f(handle, config);
|
||||
if (ret == 0)
|
||||
{
|
||||
if (handle->plugin_api_version == PLUGIN_API_VERSION && handle->plugin_funcs_size == sizeof(struct plugin_funcs))
|
||||
{
|
||||
LOG_INFO("Loaded plugin: %s: %s, version %s.", filename, handle->name, handle->version);
|
||||
LOG_PLUGIN("Plugin API version: %d (func table size: " PRINTF_SIZE_T ")", handle->plugin_api_version, handle->plugin_funcs_size);
|
||||
return handle;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Unable to load plugin: %s - API version mistmatch", filename);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Unable to load plugin: %s - Failed to initialize: %s", filename, handle->error_msg);
|
||||
}
|
||||
}
|
||||
|
||||
plugin_close(plugin);
|
||||
hub_free(handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void plugin_unload(struct plugin_handle* plugin)
|
||||
{
|
||||
struct plugin_hub_internals* internals = get_internals(plugin);
|
||||
plugin_unregister_callback_functions(plugin);
|
||||
internals->unregister(plugin);
|
||||
plugin_close(plugin->handle);
|
||||
hub_free(plugin);
|
||||
}
|
||||
|
||||
static int plugin_parse_line(char* line, int line_count, void* ptr_data)
|
||||
{
|
||||
struct hub_info* hub = (struct hub_info*) ptr_data;
|
||||
struct uhub_plugins* handle = hub->plugins;
|
||||
struct cfg_tokens* tokens = cfg_tokenize(line);
|
||||
struct plugin_handle* plugin;
|
||||
char *directive, *soname, *params;
|
||||
|
||||
if (cfg_token_count(tokens) == 0)
|
||||
{
|
||||
cfg_tokens_free(tokens);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cfg_token_count(tokens) < 2)
|
||||
{
|
||||
cfg_tokens_free(tokens);
|
||||
return -1;
|
||||
}
|
||||
|
||||
directive = cfg_token_get_first(tokens);
|
||||
soname = cfg_token_get_next(tokens);
|
||||
params = cfg_token_get_next(tokens);
|
||||
|
||||
if (strcmp(directive, "plugin") == 0 && soname && *soname)
|
||||
{
|
||||
if (!params)
|
||||
params = "";
|
||||
|
||||
LOG_PLUGIN("Load plugin: \"%s\", params=\"%s\"", soname, params);
|
||||
plugin = plugin_load(soname, params, hub);
|
||||
if (plugin)
|
||||
{
|
||||
list_append(handle->loaded, plugin);
|
||||
cfg_tokens_free(tokens);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
cfg_tokens_free(tokens);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int plugin_initialize(struct hub_config* config, struct hub_info* hub)
|
||||
{
|
||||
int ret;
|
||||
|
||||
hub->plugins->loaded = list_create();
|
||||
if (!hub->plugins->loaded)
|
||||
return -1;
|
||||
|
||||
if (config)
|
||||
{
|
||||
if (!*config->file_plugins)
|
||||
return 0;
|
||||
|
||||
ret = file_read_lines(config->file_plugins, hub, &plugin_parse_line);
|
||||
if (ret == -1)
|
||||
{
|
||||
list_clear(hub->plugins->loaded, hub_free);
|
||||
list_destroy(hub->plugins->loaded);
|
||||
hub->plugins->loaded = 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void plugin_shutdown(struct uhub_plugins* handle)
|
||||
{
|
||||
struct plugin_handle* plugin = (struct plugin_handle*) list_get_first(handle->loaded);
|
||||
while (plugin)
|
||||
{
|
||||
list_remove(handle->loaded, plugin);
|
||||
plugin_unload(plugin);
|
||||
plugin = (struct plugin_handle*) list_get_first(handle->loaded);
|
||||
}
|
||||
|
||||
list_destroy(handle->loaded);
|
||||
}
|
||||
|
||||
// Used internally only
|
||||
struct hub_info* plugin_get_hub(struct plugin_handle* plugin)
|
||||
{
|
||||
struct plugin_hub_internals* data = get_internals(plugin);
|
||||
return data->hub;
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_PLUGIN_LOADER_H
|
||||
#define HAVE_UHUB_PLUGIN_LOADER_H
|
||||
|
||||
#include "plugin_api/handle.h"
|
||||
|
||||
struct hub_config;
|
||||
struct hub_info;
|
||||
struct linked_list;
|
||||
struct plugin_handle;
|
||||
|
||||
struct uhub_plugin
|
||||
{
|
||||
void* handle;
|
||||
plugin_unregister_f unregister;
|
||||
char* filename;
|
||||
void* internals; // Hub internal stuff
|
||||
};
|
||||
|
||||
struct uhub_plugins
|
||||
{
|
||||
struct linked_list* loaded;
|
||||
};
|
||||
|
||||
// High level plugin loader ode
|
||||
extern struct plugin_handle* plugin_load(const char* filename, const char* config, struct hub_info* hub);
|
||||
extern void plugin_unload(struct plugin_handle* plugin);
|
||||
|
||||
// extern void plugin_unload(struct plugin_handle*);
|
||||
extern int plugin_initialize(struct hub_config* config, struct hub_info* hub);
|
||||
extern void plugin_shutdown(struct uhub_plugins* handle);
|
||||
|
||||
// Low level plugin loader code (used internally)
|
||||
extern struct uhub_plugin* plugin_open(const char* filename);
|
||||
extern void plugin_close(struct uhub_plugin*);
|
||||
extern void* plugin_lookup_symbol(struct uhub_plugin*, const char* symbol);
|
||||
|
||||
// Used internally only
|
||||
extern struct hub_info* plugin_get_hub(struct plugin_handle*);
|
||||
|
||||
#endif /* HAVE_UHUB_PLUGIN_LOADER_H */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user