mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 23:49:07 +02:00
* adds lnet subdir to fppkg for lnetpkg
git-svn-id: trunk@5802 -
This commit is contained in:
parent
f745a62679
commit
c6f7301087
20
.gitattributes
vendored
20
.gitattributes
vendored
@ -8186,6 +8186,26 @@ utils/fppkg/fppkg.lpi svneol=native#text/plain
|
|||||||
utils/fppkg/fppkg.pp svneol=native#text/plain
|
utils/fppkg/fppkg.pp svneol=native#text/plain
|
||||||
utils/fppkg/fprepos.pp svneol=native#text/plain
|
utils/fppkg/fprepos.pp svneol=native#text/plain
|
||||||
utils/fppkg/fpxmlrep.pp svneol=native#text/plain
|
utils/fppkg/fpxmlrep.pp svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/LICENSE -text
|
||||||
|
utils/fppkg/lnet/fastcgi.pp svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/lcommon.pp svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/lcontainers.inc svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/lcontainersh.inc svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/lcontrolstack.pp svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/levents.pp svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/lftp.pp svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/lnet.pp svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/lstrbuffer.pp svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/ltelnet.pp svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/lwebserver.pp svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/openssl.pp -text svneol=unset#text/plain
|
||||||
|
utils/fppkg/lnet/sys/lepolleventer.inc svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/sys/lepolleventerh.inc svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/sys/lkqueueeventer.inc svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/sys/lkqueueeventerh.inc svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/sys/lspawnfcgiunix.inc svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/sys/lspawnfcgiwin.inc svneol=native#text/plain
|
||||||
|
utils/fppkg/lnet/sys/osunits.inc svneol=native#text/plain
|
||||||
utils/fppkg/pkgdownload.pp svneol=native#text/plain
|
utils/fppkg/pkgdownload.pp svneol=native#text/plain
|
||||||
utils/fppkg/pkghandler.pp svneol=native#text/plain
|
utils/fppkg/pkghandler.pp svneol=native#text/plain
|
||||||
utils/fppkg/pkglibcurl.pp svneol=native#text/plain
|
utils/fppkg/pkglibcurl.pp svneol=native#text/plain
|
||||||
|
481
utils/fppkg/lnet/LICENSE
Normal file
481
utils/fppkg/lnet/LICENSE
Normal file
@ -0,0 +1,481 @@
|
|||||||
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the library GPL. It is
|
||||||
|
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Library General Public License, applies to some
|
||||||
|
specially designated Free Software Foundation software, and to any
|
||||||
|
other libraries whose authors decide to use it. You can use it for
|
||||||
|
your libraries, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link a program with the library, you must provide
|
||||||
|
complete object files to the recipients so that they can relink them
|
||||||
|
with the library, after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
Our method of protecting your rights has two steps: (1) copyright
|
||||||
|
the library, and (2) offer you this license which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
Also, for each distributor's protection, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
library. If the library is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original
|
||||||
|
version, so that any problems introduced by others will not reflect on
|
||||||
|
the original authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that companies distributing free
|
||||||
|
software will individually obtain patent licenses, thus in effect
|
||||||
|
transforming the program into proprietary software. To prevent this,
|
||||||
|
we have made it clear that any patent must be licensed for everyone's
|
||||||
|
free use or not licensed at all.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary
|
||||||
|
GNU General Public License, which was designed for utility programs. This
|
||||||
|
license, the GNU Library General Public License, applies to certain
|
||||||
|
designated libraries. This license is quite different from the ordinary
|
||||||
|
one; be sure to read it in full, and don't assume that anything in it is
|
||||||
|
the same as in the ordinary license.
|
||||||
|
|
||||||
|
The reason we have a separate public license for some libraries is that
|
||||||
|
they blur the distinction we usually make between modifying or adding to a
|
||||||
|
program and simply using it. Linking a program with a library, without
|
||||||
|
changing the library, is in some sense simply using the library, and is
|
||||||
|
analogous to running a utility program or application program. However, in
|
||||||
|
a textual and legal sense, the linked executable is a combined work, a
|
||||||
|
derivative of the original library, and the ordinary General Public License
|
||||||
|
treats it as such.
|
||||||
|
|
||||||
|
Because of this blurred distinction, using the ordinary General
|
||||||
|
Public License for libraries did not effectively promote software
|
||||||
|
sharing, because most developers did not use the libraries. We
|
||||||
|
concluded that weaker conditions might promote sharing better.
|
||||||
|
|
||||||
|
However, unrestricted linking of non-free programs would deprive the
|
||||||
|
users of those programs of all benefit from the free status of the
|
||||||
|
libraries themselves. This Library General Public License is intended to
|
||||||
|
permit developers of non-free programs to use free libraries, while
|
||||||
|
preserving your freedom as a user of such programs to change the free
|
||||||
|
libraries that are incorporated in them. (We have not seen how to achieve
|
||||||
|
this as regards changes in header files, but we have achieved it as regards
|
||||||
|
changes in the actual functions of the Library.) The hope is that this
|
||||||
|
will lead to faster development of free libraries.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, while the latter only
|
||||||
|
works together with the library.
|
||||||
|
|
||||||
|
Note that it is possible for a library to be covered by the ordinary
|
||||||
|
General Public License rather than by this special one.
|
||||||
|
|
||||||
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library which
|
||||||
|
contains a notice placed by the copyright holder or other authorized
|
||||||
|
party saying it may be distributed under the terms of this Library
|
||||||
|
General Public License (also called "this License"). Each licensee is
|
||||||
|
addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also compile or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
c) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
d) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the source code distributed need not include anything that is normally
|
||||||
|
distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Library General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with this library; if not, write to the Free
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
146
utils/fppkg/lnet/fastcgi.pp
Normal file
146
utils/fppkg/lnet/fastcgi.pp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
unit fastcgi;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
{
|
||||||
|
Automatically converted by H2Pas 0.99.16 from fastcgi.h
|
||||||
|
The following command line parameters were used:
|
||||||
|
fastcgi.h
|
||||||
|
}
|
||||||
|
|
||||||
|
{$IFDEF FPC}
|
||||||
|
{$PACKRECORDS C}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
* Listening socket file number
|
||||||
|
}
|
||||||
|
|
||||||
|
const
|
||||||
|
FCGI_LISTENSOCK_FILENO = 0;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
PFCGI_Header = ^FCGI_Header;
|
||||||
|
FCGI_Header = record
|
||||||
|
version : byte;
|
||||||
|
reqtype : byte;
|
||||||
|
requestIdB1 : byte;
|
||||||
|
requestIdB0 : byte;
|
||||||
|
contentLengthB1 : byte;
|
||||||
|
contentLengthB0 : byte;
|
||||||
|
paddingLength : byte;
|
||||||
|
reserved : byte;
|
||||||
|
end;
|
||||||
|
{
|
||||||
|
* Number of bytes in a FCGI_Header. Future versions of the protocol
|
||||||
|
* will not reduce this number.
|
||||||
|
}
|
||||||
|
|
||||||
|
const
|
||||||
|
FCGI_HEADER_LEN = 8;
|
||||||
|
|
||||||
|
{
|
||||||
|
* Value for version component of FCGI_Header
|
||||||
|
}
|
||||||
|
FCGI_VERSION_1 = 1;
|
||||||
|
|
||||||
|
{
|
||||||
|
* Values for type component of FCGI_Header
|
||||||
|
}
|
||||||
|
FCGI_BEGIN_REQUEST = 1;
|
||||||
|
FCGI_ABORT_REQUEST = 2;
|
||||||
|
FCGI_END_REQUEST = 3;
|
||||||
|
FCGI_PARAMS = 4;
|
||||||
|
FCGI_STDIN = 5;
|
||||||
|
FCGI_STDOUT = 6;
|
||||||
|
FCGI_STDERR = 7;
|
||||||
|
FCGI_DATA = 8;
|
||||||
|
FCGI_GET_VALUES = 9;
|
||||||
|
FCGI_GET_VALUES_RESULT = 10;
|
||||||
|
FCGI_UNKNOWN_TYPE = 11;
|
||||||
|
FCGI_MAXTYPE = FCGI_UNKNOWN_TYPE;
|
||||||
|
|
||||||
|
{
|
||||||
|
* Value for requestId component of FCGI_Header
|
||||||
|
}
|
||||||
|
FCGI_NULL_REQUEST_ID = 0;
|
||||||
|
|
||||||
|
type
|
||||||
|
FCGI_BeginRequestBody = record
|
||||||
|
roleB1 : byte;
|
||||||
|
roleB0 : byte;
|
||||||
|
flags : byte;
|
||||||
|
reserved : array[0..4] of byte;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FCGI_BeginRequestRecord = record
|
||||||
|
header : FCGI_Header;
|
||||||
|
body : FCGI_BeginRequestBody;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{
|
||||||
|
* Mask for flags component of FCGI_BeginRequestBody
|
||||||
|
}
|
||||||
|
|
||||||
|
const
|
||||||
|
FCGI_KEEP_CONN = 1;
|
||||||
|
|
||||||
|
{
|
||||||
|
* Values for role component of FCGI_BeginRequestBody
|
||||||
|
}
|
||||||
|
|
||||||
|
FCGI_RESPONDER = 1;
|
||||||
|
FCGI_AUTHORIZER = 2;
|
||||||
|
FCGI_FILTER = 3;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
FCGI_EndRequestBody = record
|
||||||
|
appStatusB3 : byte;
|
||||||
|
appStatusB2 : byte;
|
||||||
|
appStatusB1 : byte;
|
||||||
|
appStatusB0 : byte;
|
||||||
|
protocolStatus : byte;
|
||||||
|
reserved : array[0..2] of byte;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FCGI_EndRequestRecord = record
|
||||||
|
header : FCGI_Header;
|
||||||
|
body : FCGI_EndRequestBody;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{
|
||||||
|
* Values for protocolStatus component of FCGI_EndRequestBody
|
||||||
|
}
|
||||||
|
|
||||||
|
const
|
||||||
|
FCGI_REQUEST_COMPLETE = 0;
|
||||||
|
FCGI_CANT_MPX_CONN = 1;
|
||||||
|
FCGI_OVERLOADED = 2;
|
||||||
|
FCGI_UNKNOWN_ROLE = 3;
|
||||||
|
|
||||||
|
{
|
||||||
|
* Variable names for FCGI_GET_VALUES / FCGI_GET_VALUES_RESULT records
|
||||||
|
}
|
||||||
|
|
||||||
|
FCGI_MAX_CONNS = 'FCGI_MAX_CONNS';
|
||||||
|
FCGI_MAX_REQS = 'FCGI_MAX_REQS';
|
||||||
|
FCGI_MPXS_CONNS = 'FCGI_MPXS_CONNS';
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
FCGI_UnknownTypeBody = record
|
||||||
|
_type : byte;
|
||||||
|
reserved : array[0..6] of byte;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FCGI_UnknownTypeRecord = record
|
||||||
|
header : FCGI_Header;
|
||||||
|
body : FCGI_UnknownTypeBody;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
end.
|
338
utils/fppkg/lnet/lcommon.pp
Normal file
338
utils/fppkg/lnet/lcommon.pp
Normal file
@ -0,0 +1,338 @@
|
|||||||
|
{ lCommon
|
||||||
|
|
||||||
|
CopyRight (C) 2004-2006 Ales Katona
|
||||||
|
|
||||||
|
This library is Free software; you can rediStribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This program is diStributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; withOut even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a Copy of the GNU Library General Public License
|
||||||
|
along with This library; if not, Write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
This license has been modified. See File LICENSE.ADDON for more inFormation.
|
||||||
|
Should you find these sources without a LICENSE File, please contact
|
||||||
|
me at ales@chello.sk
|
||||||
|
}
|
||||||
|
|
||||||
|
unit lCommon;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
{$inline on}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
{$i sys/osunits.inc}
|
||||||
|
|
||||||
|
const
|
||||||
|
{$IFDEF WINDOWS}
|
||||||
|
SOL_SOCKET = $ffff;
|
||||||
|
LMSG = 0;
|
||||||
|
SOCKET_ERROR = WinSock2.SOCKET_ERROR;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
{$IFDEF OS2}
|
||||||
|
SOL_SOCKET = WinSock.SOL_SOCKET;
|
||||||
|
LMSG = 0;
|
||||||
|
SOCKET_ERROR = WinSock.SOCKET_ERROR;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
{$IFDEF NETWARE}
|
||||||
|
SOL_SOCKET = WinSock.SOL_SOCKET;
|
||||||
|
LMSG = 0;
|
||||||
|
SOCKET_ERROR = WinSock.SOCKET_ERROR;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
{$IFDEF UNIX}
|
||||||
|
INVALID_SOCKET = -1;
|
||||||
|
SOCKET_ERROR = -1;
|
||||||
|
{$IFDEF LINUX} // TODO: fix this crap, some don't even have MSD_NOSIGNAL
|
||||||
|
LMSG = MSG_NOSIGNAL;
|
||||||
|
{$ELSE}
|
||||||
|
LMSG = $20000; // FPC BUG in 2.0.4-
|
||||||
|
{$ENDIF}
|
||||||
|
{$ENDIF}
|
||||||
|
{ Default Values }
|
||||||
|
LDEFAULT_BACKLOG = 5;
|
||||||
|
BUFFER_SIZE = 65536;
|
||||||
|
|
||||||
|
{ Base functions }
|
||||||
|
{$IFNDEF UNIX}
|
||||||
|
function fpSelect(const nfds: Integer; const readfds, writefds, exceptfds: PFDSet;
|
||||||
|
const timeout: PTimeVal): Integer; inline;
|
||||||
|
function fpFD_ISSET(const Socket: Integer; var FDSet: TFDSet): Integer; inline;
|
||||||
|
procedure fpFD_SET(const Socket: Integer; var FDSet: TFDSet); inline;
|
||||||
|
procedure fpFD_ZERO(var FDSet: TFDSet); inline;
|
||||||
|
{$ENDIF}
|
||||||
|
{ DNS }
|
||||||
|
function GetHostName(const Address: string): string;
|
||||||
|
function GetHostIP(const Name: string): string;
|
||||||
|
|
||||||
|
function LStrError(const Ernum: Longint; const UseUTF8: Boolean = False): string;
|
||||||
|
function LSocketError: Longint;
|
||||||
|
|
||||||
|
function SetBlocking(const aHandle: Integer; const aValue: Boolean): Boolean;
|
||||||
|
|
||||||
|
function IsBlockError(const anError: Integer): Boolean; inline;
|
||||||
|
|
||||||
|
function TZSeconds: Integer; inline;
|
||||||
|
|
||||||
|
function StrToHostAddr(const IP: string): Cardinal; inline;
|
||||||
|
function HostAddrToStr(const Entry: Cardinal): string; inline;
|
||||||
|
function StrToNetAddr(const IP: string): Cardinal; inline;
|
||||||
|
function NetAddrToStr(const Entry: Cardinal): string; inline;
|
||||||
|
|
||||||
|
procedure FillAddressInfo(var aAddrInfo: TInetSockAddr; const aFamily: sa_family_t;
|
||||||
|
const Address: string; const aPort: Word); inline;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
lNet
|
||||||
|
|
||||||
|
{$IFNDEF UNIX}
|
||||||
|
|
||||||
|
{$IFDEF WINDOWS}
|
||||||
|
, Windows;
|
||||||
|
|
||||||
|
function LStrError(const Ernum: Longint; const UseUTF8: Boolean = False): string;
|
||||||
|
var
|
||||||
|
Tmp: string;
|
||||||
|
TmpW: widestring;
|
||||||
|
begin
|
||||||
|
Result:='[' + IntToStr(Ernum) + '] ';
|
||||||
|
if USEUtf8 then begin
|
||||||
|
SetLength(TmpW, 256);
|
||||||
|
SetLength(TmpW, FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM or
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS or
|
||||||
|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
||||||
|
nil, Ernum, 0, @TmpW[1], 256, nil));
|
||||||
|
Tmp:=UTF8Encode(TmpW);
|
||||||
|
end else begin
|
||||||
|
SetLength(Tmp, 256);
|
||||||
|
SetLength(Tmp, FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS or
|
||||||
|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
||||||
|
nil, Ernum, 0, @Tmp[1], 256, nil));
|
||||||
|
end;
|
||||||
|
if Length(Tmp) > 2 then
|
||||||
|
Delete(Tmp, Length(Tmp)-1, 2);
|
||||||
|
Result:=Tmp;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TZSeconds: integer; inline;
|
||||||
|
var
|
||||||
|
lInfo: Windows.TIME_ZONE_INFORMATION;
|
||||||
|
begin
|
||||||
|
{ lInfo.Bias is in minutes }
|
||||||
|
if Windows.GetTimeZoneInformation(@lInfo) <> $FFFFFFFF then
|
||||||
|
Result := lInfo.Bias * 60
|
||||||
|
else
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$ELSE}
|
||||||
|
; // uses
|
||||||
|
|
||||||
|
function LStrError(const Ernum: Longint; const UseUTF8: Boolean = False): string;
|
||||||
|
begin
|
||||||
|
Result:=IntToStr(Ernum); // TODO: fix for non-windows winsock users
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TZSeconds: integer; inline;
|
||||||
|
begin
|
||||||
|
Result:=0; // todo: fix for non-windows non unix
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
function LSocketError: Longint;
|
||||||
|
begin
|
||||||
|
Result:=WSAGetLastError;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CleanError(const Ernum: Longint): Byte;
|
||||||
|
begin
|
||||||
|
Result:=Byte(Ernum - 10000);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpSelect(const nfds: Integer; const readfds, writefds, exceptfds: PFDSet;
|
||||||
|
const timeout: PTimeVal): Longint; inline;
|
||||||
|
begin
|
||||||
|
Result:=Select(nfds, readfds, writefds, exceptfds, timeout);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpFD_ISSET(const Socket: Longint; var FDSet: TFDSet): Integer; inline;
|
||||||
|
begin
|
||||||
|
Result:=0;
|
||||||
|
if FD_ISSET(Socket, FDSet) then
|
||||||
|
Result:=1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure fpFD_SET(const Socket: Longint; var FDSet: TFDSet); inline;
|
||||||
|
begin
|
||||||
|
FD_SET(Socket, FDSet);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure fpFD_ZERO(var FDSet: TFDSet); inline;
|
||||||
|
begin
|
||||||
|
FD_ZERO(FDSet);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetHostName(const Address: string): string;
|
||||||
|
var
|
||||||
|
HE: PHostEnt;
|
||||||
|
Addr: DWord;
|
||||||
|
begin
|
||||||
|
Result:='';
|
||||||
|
HE:=nil;
|
||||||
|
Addr:=inet_addr(PChar(Address));
|
||||||
|
HE:=gethostbyaddr(@Addr, SizeOf(Addr), AF_INET);
|
||||||
|
if Assigned(HE) then
|
||||||
|
Result:=HE^.h_name;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetHostIP(const Name: string): string;
|
||||||
|
var
|
||||||
|
HE: PHostEnt;
|
||||||
|
P: PDWord;
|
||||||
|
begin
|
||||||
|
Result:='';
|
||||||
|
HE:=nil;
|
||||||
|
HE:=gethostbyname(PChar(Name));
|
||||||
|
if Assigned(HE) then begin
|
||||||
|
P:=Pointer(HE^.h_addr_list[0]);
|
||||||
|
Result:=NetAddrToStr(P^);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function SetBlocking(const aHandle: Integer; const aValue: Boolean): Boolean;
|
||||||
|
const
|
||||||
|
BlockAr: array[Boolean] of DWord = (1, 0);
|
||||||
|
var
|
||||||
|
opt: DWord;
|
||||||
|
begin
|
||||||
|
opt:=BlockAr[aValue];
|
||||||
|
if ioctlsocket(aHandle, FIONBIO, opt) = SOCKET_ERROR then
|
||||||
|
Exit(False);
|
||||||
|
Result:=True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function IsBlockError(const anError: Integer): Boolean; inline;
|
||||||
|
begin
|
||||||
|
Result:=anError = WSAEWOULDBLOCK;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$ELSE}
|
||||||
|
|
||||||
|
// unix
|
||||||
|
|
||||||
|
,Errors, UnixUtil;
|
||||||
|
|
||||||
|
function LStrError(const Ernum: Longint; const UseUTF8: Boolean = False): string;
|
||||||
|
begin
|
||||||
|
Result:='[' + IntToStr(Ernum) + '] ' + Errors.StrError(Ernum);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function LSocketError: Longint;
|
||||||
|
begin
|
||||||
|
Result:=fpgeterrno;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CleanError(const Ernum: Longint): Longint; inline;
|
||||||
|
begin
|
||||||
|
Result:=Byte(Ernum);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetHostName(const Address: string): string;
|
||||||
|
var
|
||||||
|
HE: THostEntry;
|
||||||
|
begin
|
||||||
|
Result:='';
|
||||||
|
if GetHostbyAddr(in_addr(StrToHostAddr(Address)), HE) then
|
||||||
|
Result:=HE.Name
|
||||||
|
else if ResolveHostbyAddr(in_addr(StrToHostAddr(Address)), HE) then
|
||||||
|
Result:=HE.Name;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetHostIP(const Name: string): string;
|
||||||
|
var
|
||||||
|
HE: THostEntry;
|
||||||
|
begin
|
||||||
|
Result:='';
|
||||||
|
if GetHostByName(Name, HE) then
|
||||||
|
Result:=HostAddrToStr(Cardinal(HE.Addr)) // for localhost
|
||||||
|
else if ResolveHostByName(Name, HE) then
|
||||||
|
Result:=NetAddrToStr(Cardinal(HE.Addr));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function SetBlocking(const aHandle: Integer; const aValue: Boolean): Boolean;
|
||||||
|
var
|
||||||
|
opt: cInt;
|
||||||
|
begin
|
||||||
|
opt:=fpfcntl(aHandle, F_GETFL);
|
||||||
|
if opt = SOCKET_ERROR then
|
||||||
|
Exit(False);
|
||||||
|
|
||||||
|
if aValue then
|
||||||
|
opt:=opt and not O_NONBLOCK
|
||||||
|
else
|
||||||
|
opt:=opt or O_NONBLOCK;
|
||||||
|
|
||||||
|
if fpfcntl(aHandle, F_SETFL, opt) = SOCKET_ERROR then
|
||||||
|
Exit(False);
|
||||||
|
Result:=True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function IsBlockError(const anError: Integer): Boolean; inline;
|
||||||
|
begin
|
||||||
|
Result:=(anError = ESysEWOULDBLOCK) or (anError = ESysENOBUFS);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TZSeconds: Integer; inline;
|
||||||
|
begin
|
||||||
|
Result := unixutil.TZSeconds;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
function StrToHostAddr(const IP: string): Cardinal; inline;
|
||||||
|
begin
|
||||||
|
Result:=Cardinal(Sockets.StrToHostAddr(IP));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function HostAddrToStr(const Entry: Cardinal): string; inline;
|
||||||
|
begin
|
||||||
|
Result:=Sockets.HostAddrToStr(in_addr(Entry));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function StrToNetAddr(const IP: string): Cardinal; inline;
|
||||||
|
begin
|
||||||
|
Result:=Cardinal(Sockets.StrToNetAddr(IP));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function NetAddrToStr(const Entry: Cardinal): string; inline;
|
||||||
|
begin
|
||||||
|
Result:=Sockets.NetAddrToStr(in_addr(Entry));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure FillAddressInfo(var aAddrInfo: TInetSockAddr; const aFamily: sa_family_t;
|
||||||
|
const Address: string; const aPort: Word); inline;
|
||||||
|
begin
|
||||||
|
aAddrInfo.family:=AF_INET;
|
||||||
|
aAddrInfo.Port:=htons(aPort);
|
||||||
|
aAddrInfo.Addr:=StrToNetAddr(Address);
|
||||||
|
|
||||||
|
if (Address <> LADDR_ANY) and (aAddrInfo.Addr = 0) then
|
||||||
|
aAddrInfo.Addr:=StrToNetAddr(GetHostIP(Address));
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
50
utils/fppkg/lnet/lcontainers.inc
Normal file
50
utils/fppkg/lnet/lcontainers.inc
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
constructor TLFront.Create(const DefaultItem: __front_type__);
|
||||||
|
begin
|
||||||
|
FEmptyItem:=DefaultItem;
|
||||||
|
Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLFront.GetEmpty: Boolean;
|
||||||
|
begin
|
||||||
|
Result:=FCount = 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLFront.First: __front_type__;
|
||||||
|
begin
|
||||||
|
Result:=FEmptyItem;
|
||||||
|
if FCount > 0 then
|
||||||
|
Result:=FItems[FBottom];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLFront.Remove: __front_type__;
|
||||||
|
begin
|
||||||
|
Result:=FEmptyItem;
|
||||||
|
if FCount > 0 then begin
|
||||||
|
Result:=FItems[FBottom];
|
||||||
|
Dec(FCount);
|
||||||
|
Inc(FBottom);
|
||||||
|
if FBottom >= MAX_FRONT_ITEMS then
|
||||||
|
FBottom:=0;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLFront.Insert(const Value: __front_type__): Boolean;
|
||||||
|
begin
|
||||||
|
Result:=False;
|
||||||
|
if FCount < MAX_FRONT_ITEMS then begin
|
||||||
|
if FTop >= MAX_FRONT_ITEMS then
|
||||||
|
FTop:=0;
|
||||||
|
FItems[FTop]:=Value;
|
||||||
|
Inc(FCount);
|
||||||
|
Inc(FTop);
|
||||||
|
Result:=True;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLFront.Clear;
|
||||||
|
begin
|
||||||
|
FCount:=0;
|
||||||
|
FBottom:=0;
|
||||||
|
FTop:=0;
|
||||||
|
end;
|
||||||
|
|
32
utils/fppkg/lnet/lcontainersh.inc
Normal file
32
utils/fppkg/lnet/lcontainersh.inc
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{ This include is a little a-la-templates hack
|
||||||
|
|
||||||
|
here are all the "default" type defines which you need to
|
||||||
|
redefine yourself after including this file. You only redefine those
|
||||||
|
which are used ofcourse }
|
||||||
|
|
||||||
|
{$ifndef __front_type__}
|
||||||
|
{$ERROR Undefined type for quasi-template!}
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
const
|
||||||
|
MAX_FRONT_ITEMS = 10;
|
||||||
|
|
||||||
|
type
|
||||||
|
TLFront = class // it's a queue ladies and gents
|
||||||
|
protected
|
||||||
|
FEmptyItem: __front_type__;
|
||||||
|
FItems: array[0..MAX_FRONT_ITEMS-1] of __front_type__;
|
||||||
|
FTop, FBottom: Integer;
|
||||||
|
FCount: Integer;
|
||||||
|
function GetEmpty: Boolean;
|
||||||
|
public
|
||||||
|
constructor Create(const DefaultItem: __front_type__);
|
||||||
|
function First: __front_type__;
|
||||||
|
function Remove: __front_type__;
|
||||||
|
function Insert(const Value: __front_type__): Boolean;
|
||||||
|
procedure Clear;
|
||||||
|
property Count: Integer read FCount;
|
||||||
|
property Empty: Boolean read GetEmpty;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
102
utils/fppkg/lnet/lcontrolstack.pp
Normal file
102
utils/fppkg/lnet/lcontrolstack.pp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
{ Control stack
|
||||||
|
|
||||||
|
CopyRight (C) 2004-2006 Ales Katona
|
||||||
|
|
||||||
|
This library is Free software; you can rediStribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This program is diStributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; withOut even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a Copy of the GNU Library General Public License
|
||||||
|
along with This library; if not, Write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
This license has been modified. See File LICENSE for more inFormation.
|
||||||
|
Should you find these sources withOut a LICENSE File, please contact
|
||||||
|
me at ales@chello.sk
|
||||||
|
}
|
||||||
|
|
||||||
|
unit lControlStack;
|
||||||
|
|
||||||
|
{$mode objfpc}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
const
|
||||||
|
TL_CSLENGTH = 3;
|
||||||
|
|
||||||
|
type
|
||||||
|
TLOnFull = procedure of object;
|
||||||
|
|
||||||
|
TLControlStack = class
|
||||||
|
private
|
||||||
|
FItems: array of Char;
|
||||||
|
FIndex: Byte;
|
||||||
|
FOnFull: TLOnFull;
|
||||||
|
function GetFull: Boolean;
|
||||||
|
function GetItem(const i: Byte): Char;
|
||||||
|
procedure SetItem(const i: Byte; const Value: Char);
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
procedure Clear;
|
||||||
|
procedure Push(const Value: Char);
|
||||||
|
property ItemIndex: Byte read FIndex;
|
||||||
|
property Items[i: Byte]: Char read GetItem write SetItem; default;
|
||||||
|
property Full: Boolean read GetFull;
|
||||||
|
property OnFull: TLOnFull read FOnFull write FOnFull;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
lTelnet;
|
||||||
|
|
||||||
|
constructor TLControlStack.Create;
|
||||||
|
begin
|
||||||
|
FOnFull:=nil;
|
||||||
|
FIndex:=0;
|
||||||
|
SetLength(FItems, TL_CSLENGTH);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLControlStack.GetFull: Boolean;
|
||||||
|
begin
|
||||||
|
Result:=False;
|
||||||
|
if FIndex >= TL_CSLENGTH then
|
||||||
|
Result:=True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLControlStack.GetItem(const i: Byte): Char;
|
||||||
|
begin
|
||||||
|
Result:=TS_NOP;
|
||||||
|
if i < TL_CSLENGTH then
|
||||||
|
Result:=FItems[i];
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLControlStack.SetItem(const i: Byte; const Value: Char);
|
||||||
|
begin
|
||||||
|
if i < TL_CSLENGTH then
|
||||||
|
FItems[i]:=Value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLControlStack.Clear;
|
||||||
|
begin
|
||||||
|
FIndex:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLControlStack.Push(const Value: Char);
|
||||||
|
begin
|
||||||
|
if FIndex < TL_CSLENGTH then begin
|
||||||
|
FItems[FIndex]:=Value;
|
||||||
|
Inc(FIndex);
|
||||||
|
if Full and Assigned(FOnFull) then
|
||||||
|
FOnFull;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
566
utils/fppkg/lnet/levents.pp
Normal file
566
utils/fppkg/lnet/levents.pp
Normal file
@ -0,0 +1,566 @@
|
|||||||
|
{ lNet Events abstration
|
||||||
|
|
||||||
|
CopyRight (C) 2006 Ales Katona
|
||||||
|
|
||||||
|
This library is Free software; you can rediStribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This program is diStributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; withOut even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a Copy of the GNU Library General Public License
|
||||||
|
along with This library; if not, Write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
This license has been modified. See File LICENSE.ADDON for more inFormation.
|
||||||
|
Should you find these sources without a LICENSE File, please contact
|
||||||
|
me at ales@chello.sk
|
||||||
|
}
|
||||||
|
|
||||||
|
unit lEvents;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
{$inline on}
|
||||||
|
{$define nochoice} // let's presume we don't have "optimized" eventer
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
{$ifdef Linux}
|
||||||
|
{$undef nochoice} // undefine for all "Optimized" targets
|
||||||
|
Linux, Contnrs,
|
||||||
|
{$endif}
|
||||||
|
{$ifdef BSD}
|
||||||
|
{$undef nochoice}
|
||||||
|
BSD,
|
||||||
|
{$endif}
|
||||||
|
{$i sys/osunits.inc}
|
||||||
|
|
||||||
|
type
|
||||||
|
TLHandle = class;
|
||||||
|
TLEventer = class;
|
||||||
|
|
||||||
|
TLHandleEvent = procedure (aHandle: TLHandle) of object;
|
||||||
|
TLHandleErrorEvent = procedure (aHandle: TLHandle; const msg: string) of object;
|
||||||
|
TLEventerErrorCallback = procedure (const msg: string; Sender: TLEventer) of object;
|
||||||
|
|
||||||
|
TArrayP = array of Pointer;
|
||||||
|
|
||||||
|
{ TLHandle }
|
||||||
|
|
||||||
|
TLHandle = class(TObject)
|
||||||
|
protected
|
||||||
|
FHandle: THandle;
|
||||||
|
FEventer: TLEventer; // "queue holder"
|
||||||
|
FOnRead: TLHandleEvent;
|
||||||
|
FOnWrite: TLHandleEvent;
|
||||||
|
FOnError: TLHandleErrorEvent;
|
||||||
|
FIgnoreWrite: Boolean; // so we can do edge-triggered
|
||||||
|
FIgnoreRead: Boolean; // so we can do edge-triggered
|
||||||
|
FIgnoreError: Boolean; // so we can do edge-triggered
|
||||||
|
FDispose: Boolean; // will free in the after-cycle
|
||||||
|
FFreeing: Boolean; // used to see if it's in the "to be freed" list
|
||||||
|
FPrev: TLHandle;
|
||||||
|
FNext: TLHandle;
|
||||||
|
FFreeNext: TLHandle;
|
||||||
|
FUserData: Pointer;
|
||||||
|
FInternalData: Pointer;
|
||||||
|
procedure SetIgnoreError(const aValue: Boolean);
|
||||||
|
procedure SetIgnoreWrite(const aValue: Boolean);
|
||||||
|
procedure SetIgnoreRead(const aValue: Boolean);
|
||||||
|
public
|
||||||
|
constructor Create; virtual;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure Free; virtual; // this is a trick
|
||||||
|
property Prev: TLHandle read FPrev write FPrev;
|
||||||
|
property Next: TLHandle read FNext write FNext;
|
||||||
|
property FreeNext: TLHandle read FFreeNext write FFreeNext;
|
||||||
|
property IgnoreWrite: Boolean read FIgnoreWrite write SetIgnoreWrite;
|
||||||
|
property IgnoreRead: Boolean read FIgnoreRead write SetIgnoreRead;
|
||||||
|
property IgnoreError: Boolean read FIgnoreError write SetIgnoreError;
|
||||||
|
property OnRead: TLHandleEvent read FOnRead write FOnRead;
|
||||||
|
property OnWrite: TLHandleEvent read FOnWrite write FOnWrite;
|
||||||
|
property OnError: TLHandleErrorEvent read FOnError write FOnError;
|
||||||
|
property UserData: Pointer read FUserData write FUserData;
|
||||||
|
property Dispose: Boolean read FDispose write FDispose;
|
||||||
|
property Handle: THandle read FHandle write FHandle;
|
||||||
|
property Eventer: TLEventer read FEventer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TLTimer }
|
||||||
|
{
|
||||||
|
TLTimer = class(TObject)
|
||||||
|
protected
|
||||||
|
FOnTimer: TNotifyEvent;
|
||||||
|
FInterval: TDateTime;
|
||||||
|
FTimeout: TDateTime;
|
||||||
|
FPeriodic: Boolean;
|
||||||
|
FEnabled: Boolean;
|
||||||
|
FNext: TLTimer;
|
||||||
|
|
||||||
|
function GetInterval: Integer;
|
||||||
|
procedure SetEnabled(NewEnabled: Boolean);
|
||||||
|
procedure SetInterval(NewInterval: Integer);
|
||||||
|
public
|
||||||
|
procedure CallAction;
|
||||||
|
property Enabled: Boolean read FEnabled write SetEnabled;
|
||||||
|
property Interval: Integer read GetInterval write SetInterval;
|
||||||
|
property Periodic: Boolean read FPeriodic write FPeriodic;
|
||||||
|
property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
{ TLTimeoutManager }
|
||||||
|
{
|
||||||
|
TLSetTimeout = procedure(NewTimeout: DWord) of object;
|
||||||
|
|
||||||
|
TLTimeoutManager = class
|
||||||
|
protected
|
||||||
|
FFirst: TLTimer;
|
||||||
|
FLast: TLTimer;
|
||||||
|
FTimeout: DWord;
|
||||||
|
FSetTimeout: TLSetTimeout;
|
||||||
|
public
|
||||||
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
procedure AddTimer(ATimer: TLTimer);
|
||||||
|
procedure RemoveTimer(ATimer: TLTimer);
|
||||||
|
|
||||||
|
procedure CallAction;
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
{ TLEventer }
|
||||||
|
|
||||||
|
TLEventer = class
|
||||||
|
protected
|
||||||
|
FRoot: TLHandle;
|
||||||
|
FCount: Integer;
|
||||||
|
FOnError: TLEventerErrorCallback;
|
||||||
|
FReferences: Integer;
|
||||||
|
FFreeRoot: TLHandle; // the root of "free" list if any
|
||||||
|
FFreeIter: TLHandle; // the last of "free" list if any
|
||||||
|
FInLoop: Boolean;
|
||||||
|
function GetTimeout: DWord; virtual;
|
||||||
|
procedure SetTimeout(const Value: DWord); virtual;
|
||||||
|
function Bail(const msg: string; const Ernum: Integer): Boolean;
|
||||||
|
procedure AddForFree(aHandle: TLHandle);
|
||||||
|
procedure FreeHandles;
|
||||||
|
procedure HandleIgnoreError(aHandle: TLHandle); virtual;
|
||||||
|
procedure HandleIgnoreWrite(aHandle: TLHandle); virtual;
|
||||||
|
procedure HandleIgnoreRead(aHandle: TLHandle); virtual;
|
||||||
|
function GetInternalData(aHandle: TLHandle): Pointer;
|
||||||
|
procedure SetInternalData(aHandle: TLHandle; const aData: Pointer);
|
||||||
|
procedure SetHandleEventer(aHandle: TLHandle);
|
||||||
|
public
|
||||||
|
constructor Create; virtual;
|
||||||
|
destructor Destroy; override;
|
||||||
|
function AddHandle(aHandle: TLHandle): Boolean; virtual;
|
||||||
|
function CallAction: Boolean; virtual;
|
||||||
|
procedure RemoveHandle(aHandle: TLHandle); virtual;
|
||||||
|
procedure UnplugHandle(aHandle: TLHandle); virtual;
|
||||||
|
procedure LoadFromEventer(aEventer: TLEventer); virtual;
|
||||||
|
procedure Clear;
|
||||||
|
procedure AddRef;
|
||||||
|
procedure DeleteRef;
|
||||||
|
property Timeout: DWord read GetTimeout write SetTimeout;
|
||||||
|
property OnError: TLEventerErrorCallback read FOnError write FOnError;
|
||||||
|
property Count: Integer read FCount;
|
||||||
|
end;
|
||||||
|
TLEventerClass = class of TLEventer;
|
||||||
|
|
||||||
|
{ TLSelectEventer }
|
||||||
|
|
||||||
|
TLSelectEventer = class(TLEventer)
|
||||||
|
protected
|
||||||
|
FTimeout: TTimeVal;
|
||||||
|
FReadFDSet: TFDSet;
|
||||||
|
FWriteFDSet: TFDSet;
|
||||||
|
FErrorFDSet: TFDSet;
|
||||||
|
function GetTimeout: DWord; override;
|
||||||
|
procedure SetTimeout(const Value: DWord); override;
|
||||||
|
procedure ClearSets;
|
||||||
|
public
|
||||||
|
constructor Create; override;
|
||||||
|
function CallAction: Boolean; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$i sys/lkqueueeventerh.inc}
|
||||||
|
{$i sys/lepolleventerh.inc}
|
||||||
|
|
||||||
|
function BestEventerClass: TLEventerClass;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
lCommon;
|
||||||
|
|
||||||
|
{ TLHandle }
|
||||||
|
|
||||||
|
procedure TLHandle.SetIgnoreError(const aValue: Boolean);
|
||||||
|
begin
|
||||||
|
if FIgnoreError <> aValue then begin
|
||||||
|
FIgnoreError:=aValue;
|
||||||
|
if Assigned(FEventer) then
|
||||||
|
FEventer.HandleIgnoreError(Self);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLHandle.SetIgnoreWrite(const aValue: Boolean);
|
||||||
|
begin
|
||||||
|
if FIgnoreWrite <> aValue then begin
|
||||||
|
FIgnoreWrite:=aValue;
|
||||||
|
if Assigned(FEventer) then
|
||||||
|
FEventer.HandleIgnoreWrite(Self);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLHandle.SetIgnoreRead(const aValue: Boolean);
|
||||||
|
begin
|
||||||
|
if FIgnoreRead <> aValue then begin
|
||||||
|
FIgnoreRead:=aValue;
|
||||||
|
if Assigned(FEventer) then
|
||||||
|
FEventer.HandleIgnoreRead(Self);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TLHandle.Create;
|
||||||
|
begin
|
||||||
|
FOnRead:=nil;
|
||||||
|
FOnWrite:=nil;
|
||||||
|
FOnError:=nil;
|
||||||
|
FUserData:=nil;
|
||||||
|
FEventer:=nil;
|
||||||
|
FPrev:=nil;
|
||||||
|
FNext:=nil;
|
||||||
|
FFreeNext:=nil;
|
||||||
|
FFreeing:=False;
|
||||||
|
FDispose:=False;
|
||||||
|
FIgnoreWrite:=False;
|
||||||
|
FIgnoreRead:=False;
|
||||||
|
FIgnoreError:=False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TLHandle.Destroy;
|
||||||
|
begin
|
||||||
|
if Assigned(FEventer) then
|
||||||
|
FEventer.UnplugHandle(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLHandle.Free;
|
||||||
|
begin
|
||||||
|
if Assigned(FEventer) and FEventer.FInLoop then
|
||||||
|
FEventer.AddForFree(Self)
|
||||||
|
else
|
||||||
|
inherited Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TLTimer }
|
||||||
|
{
|
||||||
|
function TLTimer.GetInterval: Integer;
|
||||||
|
begin
|
||||||
|
Result := Round(FInterval * MSecsPerDay);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTimer.SetEnabled(NewEnabled: integer);
|
||||||
|
begin
|
||||||
|
FTimeout := Now + Interval;
|
||||||
|
FEnabled := true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTimer.SetInterval(const aValue: Integer);
|
||||||
|
begin
|
||||||
|
FInterval := AValue / MSecsPerDay;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTimer.CallAction;
|
||||||
|
begin
|
||||||
|
if FEnabled and Assigned(FOnTimer) and (Now - FStarted >= FInterval) then
|
||||||
|
begin
|
||||||
|
FOnTimer(Self);
|
||||||
|
if not FOneShot then
|
||||||
|
FStarted := Now
|
||||||
|
else
|
||||||
|
FEnabled := false;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
{ TLEventer }
|
||||||
|
|
||||||
|
constructor TLEventer.Create;
|
||||||
|
begin
|
||||||
|
FRoot:=nil;
|
||||||
|
FFreeRoot:=nil;
|
||||||
|
FFreeIter:=nil;
|
||||||
|
FInLoop:=False;
|
||||||
|
FCount:=0;
|
||||||
|
FReferences:=1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TLEventer.Destroy;
|
||||||
|
begin
|
||||||
|
Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLEventer.GetTimeout: DWord;
|
||||||
|
begin
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.SetTimeout(const Value: DWord);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLEventer.Bail(const msg: string; const Ernum: Integer): Boolean;
|
||||||
|
begin
|
||||||
|
Result := False; // always false, substitute for caller's result
|
||||||
|
if Assigned(FOnError) then
|
||||||
|
FOnError(msg + ': ' + LStrError(Ernum), Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.AddForFree(aHandle: TLHandle);
|
||||||
|
begin
|
||||||
|
if not aHandle.FFreeing then begin
|
||||||
|
aHandle.FFreeing:=True;
|
||||||
|
if not Assigned(FFreeIter) then begin
|
||||||
|
FFreeIter:=aHandle;
|
||||||
|
FFreeRoot:=aHandle;
|
||||||
|
end else begin
|
||||||
|
FFreeIter.FreeNext:=aHandle;
|
||||||
|
FFreeIter:=aHandle;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.FreeHandles;
|
||||||
|
var
|
||||||
|
Temp, Temp2: TLHandle;
|
||||||
|
begin
|
||||||
|
Temp:=FFreeRoot;
|
||||||
|
while Assigned(Temp) do begin
|
||||||
|
Temp2:=Temp.FreeNext;
|
||||||
|
Temp.Free;
|
||||||
|
Temp:=Temp2;
|
||||||
|
end;
|
||||||
|
FFreeRoot:=nil;
|
||||||
|
FFreeIter:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.HandleIgnoreError(aHandle: TLHandle);
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.HandleIgnoreWrite(aHandle: TLHandle);
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.HandleIgnoreRead(aHandle: TLHandle);
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLEventer.GetInternalData(aHandle: TLHandle): Pointer;
|
||||||
|
begin
|
||||||
|
Result:=aHandle.FInternalData;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.SetInternalData(aHandle: TLHandle; const aData: Pointer);
|
||||||
|
begin
|
||||||
|
aHandle.FInternalData:=aData;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.SetHandleEventer(aHandle: TLHandle);
|
||||||
|
begin
|
||||||
|
aHandle.FEventer:=Self;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLEventer.AddHandle(aHandle: TLHandle): Boolean;
|
||||||
|
begin
|
||||||
|
Result:=False;
|
||||||
|
if not Assigned(aHandle.FEventer) then begin
|
||||||
|
if not Assigned(FRoot) then begin
|
||||||
|
FRoot:=aHandle;
|
||||||
|
end else begin
|
||||||
|
if Assigned(FRoot.FNext) then begin
|
||||||
|
FRoot.FNext.FPrev:=aHandle;
|
||||||
|
aHandle.FNext:=FRoot.FNext;
|
||||||
|
end;
|
||||||
|
FRoot.FNext:=aHandle;
|
||||||
|
aHandle.FPrev:=FRoot;
|
||||||
|
end;
|
||||||
|
aHandle.FEventer:=Self;
|
||||||
|
Inc(FCount);
|
||||||
|
Result:=True;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLEventer.CallAction: Boolean;
|
||||||
|
begin
|
||||||
|
Result:=True;
|
||||||
|
// override in ancestor
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.RemoveHandle(aHandle: TLHandle);
|
||||||
|
begin
|
||||||
|
aHandle.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.UnplugHandle(aHandle: TLHandle);
|
||||||
|
begin
|
||||||
|
if aHandle.FEventer = Self then begin
|
||||||
|
aHandle.FEventer:=nil; // avoid recursive AV
|
||||||
|
if Assigned(aHandle.FPrev) then begin
|
||||||
|
aHandle.FPrev.FNext:=aHandle.FNext;
|
||||||
|
if Assigned(aHandle.FNext) then
|
||||||
|
aHandle.FNext.FPrev:=aHandle.FPrev;
|
||||||
|
end else if Assigned(aHandle.FNext) then begin
|
||||||
|
aHandle.FNext.FPrev:=aHandle.FPrev;
|
||||||
|
if aHandle = FRoot then
|
||||||
|
FRoot:=aHandle.FNext;
|
||||||
|
end else FRoot:=nil;
|
||||||
|
if FCount > 0 then
|
||||||
|
Dec(FCount);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.LoadFromEventer(aEventer: TLEventer);
|
||||||
|
begin
|
||||||
|
Clear;
|
||||||
|
FRoot:=aEventer.FRoot;
|
||||||
|
FOnError:=aEventer.FOnError;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.Clear;
|
||||||
|
var
|
||||||
|
Temp1, Temp2: TLHandle;
|
||||||
|
begin
|
||||||
|
Temp1:=FRoot;
|
||||||
|
Temp2:=FRoot;
|
||||||
|
while Assigned(Temp2) do begin
|
||||||
|
Temp1:=Temp2;
|
||||||
|
Temp2:=Temp1.FNext;
|
||||||
|
Temp1.Free;
|
||||||
|
end;
|
||||||
|
FRoot:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.AddRef;
|
||||||
|
begin
|
||||||
|
Inc(FReferences);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEventer.DeleteRef;
|
||||||
|
begin
|
||||||
|
if FReferences > 0 then
|
||||||
|
Dec(FReferences);
|
||||||
|
if FReferences = 0 then
|
||||||
|
Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TLSelectEventer }
|
||||||
|
|
||||||
|
constructor TLSelectEventer.Create;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
FTimeout.tv_sec:=0;
|
||||||
|
FTimeout.tv_usec:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLSelectEventer.GetTimeout: DWord;
|
||||||
|
begin
|
||||||
|
Result:=(FTimeout.tv_sec * 1000) + FTimeout.tv_usec;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLSelectEventer.SetTimeout(const Value: DWord);
|
||||||
|
begin
|
||||||
|
FTimeout.tv_sec:=Value div 1000;
|
||||||
|
FTimeout.tv_usec:=Value mod 1000;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLSelectEventer.ClearSets;
|
||||||
|
begin
|
||||||
|
fpFD_ZERO(FReadFDSet);
|
||||||
|
fpFD_ZERO(FWriteFDSet);
|
||||||
|
fpFD_ZERO(FErrorFDSet);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLSelectEventer.CallAction: Boolean;
|
||||||
|
var
|
||||||
|
Temp, Temp2: TLHandle;
|
||||||
|
MaxHandle, n: Integer;
|
||||||
|
TempTime: TTimeVal;
|
||||||
|
begin
|
||||||
|
if Assigned(FRoot) then begin
|
||||||
|
FInLoop:=True;
|
||||||
|
Temp:=FRoot;
|
||||||
|
MaxHandle:=0;
|
||||||
|
ClearSets;
|
||||||
|
while Assigned(Temp) do begin
|
||||||
|
if (not Temp.FDispose ) // handle still valid
|
||||||
|
and ( (not Temp.IgnoreWrite) // check write or
|
||||||
|
or (not Temp.IgnoreRead ) // check read or
|
||||||
|
or (not Temp.IgnoreError)) // check for errors
|
||||||
|
then begin
|
||||||
|
if not Temp.IgnoreWrite then
|
||||||
|
fpFD_SET(Temp.FHandle, FWriteFDSet);
|
||||||
|
if not Temp.IgnoreRead then
|
||||||
|
fpFD_SET(Temp.FHandle, FReadFDSet);
|
||||||
|
if not Temp.IgnoreError then
|
||||||
|
fpFD_SET(Temp.FHandle, FErrorFDSet);
|
||||||
|
if Temp.FHandle > MaxHandle then
|
||||||
|
MaxHandle:=Temp.FHandle;
|
||||||
|
end;
|
||||||
|
Temp2:=Temp;
|
||||||
|
Temp:=Temp.FNext;
|
||||||
|
if Temp2.FDispose then
|
||||||
|
Temp2.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TempTime:=FTimeout;
|
||||||
|
n:=fpSelect(MaxHandle + 1, @FReadFDSet, @FWriteFDSet, @FErrorFDSet, @TempTime);
|
||||||
|
|
||||||
|
if n < 0 then
|
||||||
|
Bail('Error on select', LSocketError);
|
||||||
|
Result:=n > 0;
|
||||||
|
|
||||||
|
if Result then begin
|
||||||
|
Temp:=FRoot;
|
||||||
|
while Assigned(Temp) do begin
|
||||||
|
if not Temp.FDispose and (fpFD_ISSET(Temp.FHandle, FWriteFDSet) <> 0) then
|
||||||
|
if Assigned(Temp.FOnWrite) and not Temp.IgnoreWrite then
|
||||||
|
Temp.FOnWrite(Temp);
|
||||||
|
if not Temp.FDispose and (fpFD_ISSET(Temp.FHandle, FReadFDSet) <> 0) then
|
||||||
|
if Assigned(Temp.FOnRead) and not Temp.IgnoreRead then
|
||||||
|
Temp.FOnRead(Temp);
|
||||||
|
if not Temp.FDispose and (fpFD_ISSET(Temp.FHandle, FErrorFDSet) <> 0) then
|
||||||
|
if Assigned(Temp.FOnError) and not Temp.IgnoreError then
|
||||||
|
Temp.FOnError(Temp, 'Handle error' + LStrError(LSocketError));
|
||||||
|
Temp2:=Temp;
|
||||||
|
Temp:=Temp.FNext;
|
||||||
|
if Temp2.FDispose then
|
||||||
|
AddForFree(Temp2);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
FInLoop:=False;
|
||||||
|
if Assigned(FFreeRoot) then
|
||||||
|
FreeHandles;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$i sys/lkqueueeventer.inc}
|
||||||
|
{$i sys/lepolleventer.inc}
|
||||||
|
|
||||||
|
{$ifdef nochoice}
|
||||||
|
|
||||||
|
function BestEventerClass: TLEventerClass;
|
||||||
|
begin
|
||||||
|
Result:=TLSelectEventer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
end.
|
1065
utils/fppkg/lnet/lftp.pp
Normal file
1065
utils/fppkg/lnet/lftp.pp
Normal file
File diff suppressed because it is too large
Load Diff
1266
utils/fppkg/lnet/lnet.pp
Normal file
1266
utils/fppkg/lnet/lnet.pp
Normal file
File diff suppressed because it is too large
Load Diff
91
utils/fppkg/lnet/lstrbuffer.pp
Normal file
91
utils/fppkg/lnet/lstrbuffer.pp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
{ Efficient string buffer helper
|
||||||
|
|
||||||
|
Copyright (C) 2006 Micha Nelissen
|
||||||
|
|
||||||
|
This library is Free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This program is diStributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; withOut even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a Copy of the GNU Library General Public License
|
||||||
|
along with This library; if not, Write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
This license has been modified. See file LICENSE.ADDON for more information.
|
||||||
|
Should you find these sources without a LICENSE File, please contact
|
||||||
|
me at ales@chello.sk
|
||||||
|
}
|
||||||
|
|
||||||
|
unit lStrBuffer;
|
||||||
|
|
||||||
|
{$mode objfpc}{$h+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
type
|
||||||
|
PStringBuffer = ^TStringBuffer;
|
||||||
|
TStringBuffer = record
|
||||||
|
Memory: pchar;
|
||||||
|
Pos: pchar;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function InitStringBuffer(InitialSize: integer): TStringBuffer;
|
||||||
|
procedure AppendString(var ABuffer: TStringBuffer; const ASource: string); overload;
|
||||||
|
procedure AppendString(var ABuffer: TStringBuffer; const ASource: shortstring); overload;
|
||||||
|
procedure AppendString(var ABuffer: TStringBuffer; ASource: pointer; ALength: PtrUInt); overload;
|
||||||
|
procedure AppendString(var ABuffer: TStringBuffer; ASource: pchar); overload;
|
||||||
|
procedure AppendChar(var ABuffer: TStringBuffer; AChar: char);
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
function InitStringBuffer(InitialSize: integer): TStringBuffer;
|
||||||
|
begin
|
||||||
|
Result.Memory := GetMem(InitialSize);
|
||||||
|
Result.Pos := Result.Memory;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure AppendString(var ABuffer: TStringBuffer; ASource: pointer; ALength: PtrUInt);
|
||||||
|
var
|
||||||
|
lPos, lSize: PtrUInt;
|
||||||
|
begin
|
||||||
|
if ALength = 0 then exit;
|
||||||
|
lPos := PtrUInt(ABuffer.Pos - ABuffer.Memory);
|
||||||
|
lSize := PtrUInt(MemSize(ABuffer.Memory));
|
||||||
|
{ reserve 2 extra spaces }
|
||||||
|
if lPos + ALength + 2 >= lSize then
|
||||||
|
begin
|
||||||
|
ReallocMem(ABuffer.Memory, lPos + ALength + lSize);
|
||||||
|
ABuffer.Pos := ABuffer.Memory + lPos;
|
||||||
|
end;
|
||||||
|
Move(ASource^, ABuffer.Pos^, ALength);
|
||||||
|
Inc(ABuffer.Pos, ALength);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure AppendString(var ABuffer: TStringBuffer; ASource: pchar);
|
||||||
|
begin
|
||||||
|
if ASource = nil then exit;
|
||||||
|
AppendString(ABuffer, ASource, StrLen(ASource));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure AppendString(var ABuffer: TStringBuffer; const ASource: shortstring);
|
||||||
|
begin
|
||||||
|
AppendString(ABuffer, @ASource[1], Length(ASource));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure AppendString(var ABuffer: TStringBuffer; const ASource: string);
|
||||||
|
begin
|
||||||
|
AppendString(ABuffer, PChar(ASource), Length(ASource));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure AppendChar(var ABuffer: TStringBuffer; AChar: char);
|
||||||
|
begin
|
||||||
|
ABuffer.Pos^ := AChar;
|
||||||
|
Inc(ABuffer.Pos);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
491
utils/fppkg/lnet/ltelnet.pp
Normal file
491
utils/fppkg/lnet/ltelnet.pp
Normal file
@ -0,0 +1,491 @@
|
|||||||
|
{ lTelnet CopyRight (C) 2004-2006 Ales Katona
|
||||||
|
|
||||||
|
This library is Free software; you can rediStribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This program is diStributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; withOut even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a Copy of the GNU Library General Public License
|
||||||
|
along with This library; if not, Write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
This license has been modified. See File LICENSE for more inFormation.
|
||||||
|
Should you find these sources withOut a LICENSE File, please contact
|
||||||
|
me at ales@chello.sk
|
||||||
|
}
|
||||||
|
|
||||||
|
unit lTelnet;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
//{$define debug}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, lNet, lControlStack;
|
||||||
|
|
||||||
|
const
|
||||||
|
// Telnet printer signals
|
||||||
|
TS_NUL = #0;
|
||||||
|
TS_ECHO = #1;
|
||||||
|
TS_SGA = #3; // Surpass go-ahead
|
||||||
|
TS_BEL = #7;
|
||||||
|
TS_BS = #8;
|
||||||
|
TS_HT = #9;
|
||||||
|
TS_LF = #10;
|
||||||
|
TS_VT = #11;
|
||||||
|
TS_FF = #12;
|
||||||
|
TS_CR = #13;
|
||||||
|
// Telnet control signals
|
||||||
|
TS_NAWS = #31;
|
||||||
|
TS_DATA_MARK = #128;
|
||||||
|
TS_BREAK = #129;
|
||||||
|
TS_HYI = #133; // Hide Your Input
|
||||||
|
// Data types codes
|
||||||
|
TS_STDTELNET = #160;
|
||||||
|
TS_TRANSPARENT = #161;
|
||||||
|
TS_EBCDIC = #162;
|
||||||
|
// Control bytes
|
||||||
|
TS_SE = #240;
|
||||||
|
TS_NOP = #241;
|
||||||
|
TS_GA = #249; // go ahead currently ignored(full duplex)
|
||||||
|
TS_SB = #250;
|
||||||
|
TS_WILL = #251;
|
||||||
|
TS_WONT = #252;
|
||||||
|
TS_DO = #253;
|
||||||
|
TS_DONT = #254;
|
||||||
|
// Mother of all power
|
||||||
|
TS_IAC = #255;
|
||||||
|
|
||||||
|
type
|
||||||
|
TLTelnetClient = class;
|
||||||
|
|
||||||
|
TLTelnetControlChars = set of Char;
|
||||||
|
|
||||||
|
TLHowEnum = (TE_WILL = 251, TE_WONT, TE_DO, TE_DONW);
|
||||||
|
|
||||||
|
{ TLTelnet }
|
||||||
|
|
||||||
|
TLTelnet = class(TLComponent, ILDirect)
|
||||||
|
protected
|
||||||
|
FStack: TLControlStack;
|
||||||
|
FConnection: TLTcp;
|
||||||
|
FPossible: TLTelnetControlChars;
|
||||||
|
FActive: TLTelnetControlChars;
|
||||||
|
FOutput: TMemoryStream;
|
||||||
|
FOperation: Char;
|
||||||
|
FCommandCharIndex: Byte;
|
||||||
|
FOnReceive: TLSocketEvent;
|
||||||
|
FOnConnect: TLSocketEvent;
|
||||||
|
FOnDisconnect: TLSocketEvent;
|
||||||
|
FOnError: TLSocketErrorEvent;
|
||||||
|
FCommandArgs: string[3];
|
||||||
|
FOrders: TLTelnetControlChars;
|
||||||
|
FConnected: Boolean;
|
||||||
|
function Question(const Command: Char; const Value: Boolean): Char;
|
||||||
|
|
||||||
|
function GetTimeout: DWord;
|
||||||
|
procedure SetTimeout(const Value: DWord);
|
||||||
|
|
||||||
|
function GetSocketClass: TLSocketClass;
|
||||||
|
procedure SetSocketClass(Value: TLSocketClass);
|
||||||
|
|
||||||
|
procedure StackFull;
|
||||||
|
|
||||||
|
procedure DoubleIAC(var s: string);
|
||||||
|
|
||||||
|
procedure TelnetParse(const msg: string);
|
||||||
|
|
||||||
|
procedure React(const Operation, Command: Char); virtual; abstract;
|
||||||
|
|
||||||
|
procedure SendCommand(const Command: Char; const Value: Boolean); virtual; abstract;
|
||||||
|
public
|
||||||
|
constructor Create(aOwner: TComponent); override;
|
||||||
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
function Get(var aData; const aSize: Integer; aSocket: TLSocket = nil): Integer; virtual; abstract;
|
||||||
|
function GetMessage(out msg: string; aSocket: TLSocket = nil): Integer; virtual; abstract;
|
||||||
|
|
||||||
|
function Send(const aData; const aSize: Integer; aSocket: TLSocket = nil): Integer; virtual; abstract;
|
||||||
|
function SendMessage(const msg: string; aSocket: TLSocket = nil): Integer; virtual; abstract;
|
||||||
|
|
||||||
|
function OptionIsSet(const Option: Char): Boolean;
|
||||||
|
function RegisterOption(const aOption: Char; const aCommand: Boolean): Boolean;
|
||||||
|
procedure SetOption(const Option: Char);
|
||||||
|
procedure UnSetOption(const Option: Char);
|
||||||
|
|
||||||
|
procedure Disconnect; override;
|
||||||
|
|
||||||
|
procedure SendCommand(const aCommand: Char; const How: TLHowEnum); virtual;
|
||||||
|
public
|
||||||
|
property Output: TMemoryStream read FOutput;
|
||||||
|
property Connected: Boolean read FConnected;
|
||||||
|
property Timeout: DWord read GetTimeout write SetTimeout;
|
||||||
|
property OnReceive: TLSocketEvent read FOnReceive write FOnReceive;
|
||||||
|
property OnDisconnect: TLSocketEvent read FOnDisconnect write FOnDisconnect;
|
||||||
|
property OnConnect: TLSocketEvent read FOnConnect write FOnConnect;
|
||||||
|
property OnError: TLSocketErrorEvent read FOnError write FOnError;
|
||||||
|
property Connection: TLTCP read FConnection;
|
||||||
|
property SocketClass: TLSocketClass read GetSocketClass write SetSocketClass;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TLTelnetClient }
|
||||||
|
|
||||||
|
{ TLTelnetClient }
|
||||||
|
|
||||||
|
TLTelnetClient = class(TLTelnet, ILClient)
|
||||||
|
protected
|
||||||
|
FLocalEcho: Boolean;
|
||||||
|
procedure OnEr(const msg: string; aSocket: TLSocket);
|
||||||
|
procedure OnDs(aSocket: TLSocket);
|
||||||
|
procedure OnRe(aSocket: TLSocket);
|
||||||
|
procedure OnCo(aSocket: TLSocket);
|
||||||
|
|
||||||
|
procedure React(const Operation, Command: Char); override;
|
||||||
|
|
||||||
|
procedure SendCommand(const Command: Char; const Value: Boolean); override;
|
||||||
|
public
|
||||||
|
constructor Create(aOwner: TComponent); override;
|
||||||
|
|
||||||
|
function Connect(const anAddress: string; const aPort: Word): Boolean;
|
||||||
|
function Connect: Boolean;
|
||||||
|
|
||||||
|
function Get(var aData; const aSize: Integer; aSocket: TLSocket = nil): Integer; override;
|
||||||
|
function GetMessage(out msg: string; aSocket: TLSocket = nil): Integer; override;
|
||||||
|
|
||||||
|
function Send(const aData; const aSize: Integer; aSocket: TLSocket = nil): Integer; override;
|
||||||
|
function SendMessage(const msg: string; aSocket: TLSocket = nil): Integer; override;
|
||||||
|
|
||||||
|
procedure CallAction; override;
|
||||||
|
public
|
||||||
|
property LocalEcho: Boolean read FLocalEcho write FLocalEcho;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
SysUtils;
|
||||||
|
|
||||||
|
var
|
||||||
|
zz: Char;
|
||||||
|
TNames: array[Char] of string;
|
||||||
|
|
||||||
|
//*******************************TLTelnetClient********************************
|
||||||
|
|
||||||
|
constructor TLTelnet.Create(aOwner: TComponent);
|
||||||
|
begin
|
||||||
|
inherited Create(aOwner);
|
||||||
|
FConnection := TLTCP.Create(aOwner);
|
||||||
|
FOutput := TMemoryStream.Create;
|
||||||
|
FCommandCharIndex := 0;
|
||||||
|
FStack := TLControlStack.Create;
|
||||||
|
FStack.OnFull := @StackFull;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TLTelnet.Destroy;
|
||||||
|
begin
|
||||||
|
Disconnect;
|
||||||
|
FOutput.Free;
|
||||||
|
FConnection.Free;
|
||||||
|
FStack.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLTelnet.Question(const Command: Char; const Value: Boolean): Char;
|
||||||
|
begin
|
||||||
|
Result := TS_NOP;
|
||||||
|
if Value then begin
|
||||||
|
if Command in FOrders then
|
||||||
|
Result := TS_DO
|
||||||
|
else
|
||||||
|
Result := TS_WILL;
|
||||||
|
end else begin
|
||||||
|
if Command in FOrders then
|
||||||
|
Result := TS_DONT
|
||||||
|
else
|
||||||
|
Result := TS_WONT;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLTelnet.GetSocketClass: TLSocketClass;
|
||||||
|
begin
|
||||||
|
Result := FConnection.SocketClass;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLTelnet.GetTimeout: DWord;
|
||||||
|
begin
|
||||||
|
Result := FConnection.Timeout;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnet.SetSocketClass(Value: TLSocketClass);
|
||||||
|
begin
|
||||||
|
FConnection.SocketClass := Value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnet.SetTimeout(const Value: DWord);
|
||||||
|
begin
|
||||||
|
FConnection.Timeout := Value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnet.StackFull;
|
||||||
|
begin
|
||||||
|
{$ifdef debug}
|
||||||
|
Writeln('**STACKFULL**');
|
||||||
|
{$endif}
|
||||||
|
if FStack[1] = TS_IAC then
|
||||||
|
begin
|
||||||
|
FOutput.WriteByte(Byte(FStack[1]));
|
||||||
|
FOutput.WriteByte(Byte(FStack[2]));
|
||||||
|
end else React(FStack[1], FStack[2]);
|
||||||
|
FStack.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnet.DoubleIAC(var s: string);
|
||||||
|
var
|
||||||
|
i: Longint;
|
||||||
|
begin
|
||||||
|
i := 0;
|
||||||
|
if Length(s) > 0 then
|
||||||
|
while i < Length(s) do begin
|
||||||
|
Inc(i);
|
||||||
|
if s[i] = TS_IAC then begin
|
||||||
|
Insert(TS_IAC, s, i);
|
||||||
|
Inc(i, 2);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnet.TelnetParse(const msg: string);
|
||||||
|
var
|
||||||
|
i: Longint;
|
||||||
|
begin
|
||||||
|
for i := 1 to Length(msg) do
|
||||||
|
if (FStack.ItemIndex > 0) or (msg[i] = TS_IAC) then begin
|
||||||
|
if msg[i] = TS_GA then
|
||||||
|
FStack.Clear
|
||||||
|
else
|
||||||
|
FStack.Push(msg[i])
|
||||||
|
end else
|
||||||
|
FOutput.WriteByte(Byte(msg[i]));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLTelnet.OptionIsSet(const Option: Char): Boolean;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
Result := Option in FActive;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLTelnet.RegisterOption(const aOption: Char;
|
||||||
|
const aCommand: Boolean): Boolean;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
if not (aOption in FPossible) then begin
|
||||||
|
FPossible := FPossible + [aOption];
|
||||||
|
if aCommand then
|
||||||
|
FOrders := FOrders + [aOption];
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnet.SetOption(const Option: Char);
|
||||||
|
begin
|
||||||
|
if Option in FPossible then
|
||||||
|
SendCommand(Option, True);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnet.UnSetOption(const Option: Char);
|
||||||
|
begin
|
||||||
|
if Option in FPossible then
|
||||||
|
SendCommand(Option, False);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnet.Disconnect;
|
||||||
|
begin
|
||||||
|
FConnection.Disconnect;
|
||||||
|
FConnected := False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnet.SendCommand(const aCommand: Char; const How: TLHowEnum);
|
||||||
|
begin
|
||||||
|
{$ifdef debug}
|
||||||
|
Writeln('**SENT** ', TNames[Char(How)], ' ', TNames[aCommand]);
|
||||||
|
{$endif}
|
||||||
|
FConnection.SendMessage(TS_IAC + Char(How) + aCommand);
|
||||||
|
end;
|
||||||
|
|
||||||
|
//****************************TLTelnetClient*****************************
|
||||||
|
|
||||||
|
constructor TLTelnetClient.Create(aOwner: TComponent);
|
||||||
|
begin
|
||||||
|
inherited Create(aOwner);
|
||||||
|
FConnection.OnError := @OnEr;
|
||||||
|
FConnection.OnDisconnect := @OnDs;
|
||||||
|
FConnection.OnReceive := @OnRe;
|
||||||
|
FConnection.OnConnect := @OnCo;
|
||||||
|
FConnected := False;
|
||||||
|
FPossible := [TS_ECHO, TS_HYI, TS_SGA];
|
||||||
|
FActive := [];
|
||||||
|
FOrders := [];
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnetClient.OnEr(const msg: string; aSocket: TLSocket);
|
||||||
|
begin
|
||||||
|
if Assigned(FOnError) then
|
||||||
|
FOnError(msg, aSocket)
|
||||||
|
else
|
||||||
|
FOutput.Write(Pointer(msg)^, Length(msg));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnetClient.OnDs(aSocket: TLSocket);
|
||||||
|
begin
|
||||||
|
if Assigned(FOnDisconnect) then
|
||||||
|
FOnDisconnect(aSocket);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnetClient.OnRe(aSocket: TLSocket);
|
||||||
|
var
|
||||||
|
s: string;
|
||||||
|
begin
|
||||||
|
if aSocket.GetMessage(s) > 0 then begin
|
||||||
|
TelnetParse(s);
|
||||||
|
if Assigned(FOnReceive) then
|
||||||
|
FOnReceive(aSocket);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnetClient.OnCo(aSocket: TLSocket);
|
||||||
|
begin
|
||||||
|
FConnected := True;
|
||||||
|
if Assigned(FOnConnect) then
|
||||||
|
FOnConnect(aSocket);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnetClient.React(const Operation, Command: Char);
|
||||||
|
|
||||||
|
procedure Accept(const Operation, Command: Char);
|
||||||
|
begin
|
||||||
|
FActive := FActive + [Command];
|
||||||
|
{$ifdef debug}
|
||||||
|
Writeln('**SENT** ', TNames[Operation], ' ', TNames[Command]);
|
||||||
|
{$endif}
|
||||||
|
FConnection.SendMessage(TS_IAC + Operation + Command);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure Refuse(const Operation, Command: Char);
|
||||||
|
begin
|
||||||
|
FActive := FActive - [Command];
|
||||||
|
{$ifdef debug}
|
||||||
|
Writeln('**SENT** ', TNames[Operation], ' ', TNames[Command]);
|
||||||
|
{$endif}
|
||||||
|
FConnection.SendMessage(TS_IAC + Operation + Command);
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
{$ifdef debug}
|
||||||
|
Writeln('**GOT** ', TNames[Operation], ' ', TNames[Command]);
|
||||||
|
{$endif}
|
||||||
|
case Operation of
|
||||||
|
TS_DO : if Command in FPossible then Accept(TS_WILL, Command)
|
||||||
|
else Refuse(TS_WONT, Command);
|
||||||
|
|
||||||
|
TS_DONT : if Command in FPossible then Refuse(TS_WONT, Command);
|
||||||
|
|
||||||
|
TS_WILL : if Command in FPossible then FActive := FActive + [Command]
|
||||||
|
else Refuse(TS_DONT, Command);
|
||||||
|
|
||||||
|
TS_WONT : if Command in FPossible then FActive := FActive - [Command];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnetClient.SendCommand(const Command: Char; const Value: Boolean);
|
||||||
|
begin
|
||||||
|
if FConnected then begin
|
||||||
|
{$ifdef debug}
|
||||||
|
Writeln('**SENT** ', TNames[Question(Command, Value)], ' ', TNames[Command]);
|
||||||
|
{$endif}
|
||||||
|
case Question(Command, Value) of
|
||||||
|
TS_WILL : FActive := FActive + [Command];
|
||||||
|
end;
|
||||||
|
FConnection.SendMessage(TS_IAC + Question(Command, Value) + Command);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLTelnetClient.Connect(const anAddress: string; const aPort: Word): Boolean;
|
||||||
|
begin
|
||||||
|
Result := FConnection.Connect(anAddress, aPort);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLTelnetClient.Connect: Boolean;
|
||||||
|
begin
|
||||||
|
Result := FConnection.Connect(FHost, FPort);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLTelnetClient.Get(var aData; const aSize: Integer; aSocket: TLSocket): Integer;
|
||||||
|
begin
|
||||||
|
Result := FOutput.Read(aData, aSize);
|
||||||
|
if FOutput.Position = FOutput.Size then
|
||||||
|
FOutput.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLTelnetClient.GetMessage(out msg: string; aSocket: TLSocket): Integer;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
msg := '';
|
||||||
|
if FOutput.Size > 0 then begin
|
||||||
|
FOutput.Position := 0;
|
||||||
|
SetLength(msg, FOutput.Size);
|
||||||
|
Result := FOutput.Read(PChar(msg)^, Length(msg));
|
||||||
|
FOutput.Clear;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLTelnetClient.Send(const aData; const aSize: Integer;
|
||||||
|
aSocket: TLSocket): Integer;
|
||||||
|
var
|
||||||
|
Tmp: string;
|
||||||
|
begin
|
||||||
|
{$ifdef debug}
|
||||||
|
Writeln('**SEND START** ');
|
||||||
|
{$endif}
|
||||||
|
Result := 0;
|
||||||
|
if aSize > 0 then begin
|
||||||
|
SetLength(Tmp, aSize);
|
||||||
|
Move(aData, PChar(Tmp)^, aSize);
|
||||||
|
DoubleIAC(Tmp);
|
||||||
|
if LocalEcho and (not OptionIsSet(TS_ECHO)) and (not OptionIsSet(TS_HYI)) then
|
||||||
|
FOutput.Write(PChar(Tmp)^, Length(Tmp));
|
||||||
|
Result := FConnection.SendMessage(Tmp);
|
||||||
|
end;
|
||||||
|
{$ifdef debug}
|
||||||
|
Writeln('**SEND END** ');
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLTelnetClient.SendMessage(const msg: string; aSocket: TLSocket
|
||||||
|
): Integer;
|
||||||
|
begin
|
||||||
|
Result := Send(PChar(msg)^, Length(msg));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLTelnetClient.CallAction;
|
||||||
|
begin
|
||||||
|
FConnection.CallAction;
|
||||||
|
end;
|
||||||
|
|
||||||
|
initialization
|
||||||
|
for zz := #0 to #255 do
|
||||||
|
TNames[zz] := IntToStr(Ord(zz));
|
||||||
|
TNames[#1] := 'TS_ECHO';
|
||||||
|
TNames[#133] := 'TS_HYI';
|
||||||
|
TNames[#251] := 'TS_WILL';
|
||||||
|
TNames[#252] := 'TS_WONT';
|
||||||
|
TNames[#253] := 'TS_DO';
|
||||||
|
TNames[#254] := 'TS_DONT';
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
1263
utils/fppkg/lnet/lwebserver.pp
Normal file
1263
utils/fppkg/lnet/lwebserver.pp
Normal file
File diff suppressed because it is too large
Load Diff
1452
utils/fppkg/lnet/openssl.pp
Normal file
1452
utils/fppkg/lnet/openssl.pp
Normal file
File diff suppressed because it is too large
Load Diff
224
utils/fppkg/lnet/sys/lepolleventer.inc
Normal file
224
utils/fppkg/lnet/sys/lepolleventer.inc
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
{% lepolleventer.inc included by levents.pas }
|
||||||
|
|
||||||
|
{$ifdef Linux}
|
||||||
|
|
||||||
|
{ TLEpollEventer }
|
||||||
|
|
||||||
|
const
|
||||||
|
BASE_SIZE = 100;
|
||||||
|
// bug in fpc 2.0.4-
|
||||||
|
EPOLL_CTL_ADD = 1;
|
||||||
|
EPOLL_CTL_DEL = 2;
|
||||||
|
EPOLL_CTL_MOD = 3;
|
||||||
|
|
||||||
|
EPOLLIN = $01; { The associated file is available for read(2) operations. }
|
||||||
|
EPOLLPRI = $02; { There is urgent data available for read(2) operations. }
|
||||||
|
EPOLLOUT = $04; { The associated file is available for write(2) operations. }
|
||||||
|
EPOLLERR = $08; { Error condition happened on the associated file descriptor. }
|
||||||
|
EPOLLHUP = $10; { Hang up happened on the associated file descriptor. }
|
||||||
|
EPOLLONESHOT = 1 shl 30;
|
||||||
|
EPOLLET = 1 shl 31; { Sets the Edge Triggered behaviour for the associated file descriptor. }
|
||||||
|
|
||||||
|
|
||||||
|
constructor TLEpollEventer.Create;
|
||||||
|
var
|
||||||
|
lEvent: TEpollEvent;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
FFreeList:=TFPObjectList.Create;
|
||||||
|
Inflate;
|
||||||
|
FTimeout:=0;
|
||||||
|
FEpollFD:=epoll_create(BASE_SIZE);
|
||||||
|
FEpollReadFD:=epoll_create(BASE_SIZE);
|
||||||
|
FEpollMasterFD:=epoll_create(2);
|
||||||
|
if (FEPollFD < 0) or (FEpollReadFD < 0) or (FEpollMasterFD < 0) then
|
||||||
|
raise Exception.Create('Unable to create epoll');
|
||||||
|
lEvent.events:=EPOLLIN or EPOLLOUT or EPOLLPRI or EPOLLERR or EPOLLHUP or EPOLLET;
|
||||||
|
lEvent.data.fd:=FEpollFD;
|
||||||
|
if epoll_ctl(FEpollMasterFD, EPOLL_CTL_ADD, FEpollFD, @lEvent) < 0 then
|
||||||
|
raise Exception.Create('Unable to add FDs to master epoll FD');
|
||||||
|
lEvent.data.fd:=FEpollReadFD;
|
||||||
|
if epoll_ctl(FEpollMasterFD, EPOLL_CTL_ADD, FEpollReadFD, @lEvent) < 0 then
|
||||||
|
raise Exception.Create('Unable to add FDs to master epoll FD');
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TLEpollEventer.Destroy;
|
||||||
|
begin
|
||||||
|
fpClose(FEpollFD);
|
||||||
|
FFreeList.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLEpollEventer.GetTimeout: DWord;
|
||||||
|
begin
|
||||||
|
Result:=DWord(FTimeout);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEpollEventer.SetTimeout(const Value: DWord);
|
||||||
|
begin
|
||||||
|
FTimeout:=cInt(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEpollEventer.HandleIgnoreRead(aHandle: TLHandle);
|
||||||
|
var
|
||||||
|
lEvent: TEpollEvent;
|
||||||
|
begin
|
||||||
|
lEvent.data.ptr:=aHandle;
|
||||||
|
lEvent.events:=EPOLLIN or EPOLLPRI or EPOLLHUP;
|
||||||
|
if not aHandle.IgnoreRead then begin
|
||||||
|
if epoll_ctl(FEpollReadFD, EPOLL_CTL_ADD, aHandle.Handle, @lEvent) < 0 then
|
||||||
|
Bail('Error modifying handle for reads', LSocketError);
|
||||||
|
end else begin
|
||||||
|
if epoll_ctl(FEpollReadFD, EPOLL_CTL_DEL, aHandle.Handle, @lEvent) < 0 then
|
||||||
|
Bail('Error modifying handle for reads', LSocketError);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLEpollEventer.Inflate;
|
||||||
|
var
|
||||||
|
OldLength: Integer;
|
||||||
|
begin
|
||||||
|
OldLength:=Length(FEvents);
|
||||||
|
if OldLength > 1 then
|
||||||
|
SetLength(FEvents, Sqr(OldLength))
|
||||||
|
else
|
||||||
|
SetLength(FEvents, BASE_SIZE);
|
||||||
|
SetLength(FEventsRead, Length(FEvents));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLEpollEventer.AddHandle(aHandle: TLHandle): Boolean;
|
||||||
|
|
||||||
|
var
|
||||||
|
lEvent: TEpollEvent;
|
||||||
|
begin
|
||||||
|
Result:=inherited AddHandle(aHandle);
|
||||||
|
if Result then begin
|
||||||
|
Result:=False;
|
||||||
|
lEvent.events:=EPOLLET or EPOLLOUT or EPOLLERR;
|
||||||
|
lEvent.data.ptr:=aHandle;
|
||||||
|
if epoll_ctl(FEpollFD, EPOLL_CTL_ADD, aHandle.FHandle, @lEvent) < 0 then
|
||||||
|
Bail('Error adding handle to epoll', LSocketError);
|
||||||
|
lEvent.events:=EPOLLIN or EPOLLPRI or EPOLLHUP;
|
||||||
|
if not aHandle.IgnoreRead then begin
|
||||||
|
if epoll_ctl(FEpollReadFD, EPOLL_CTL_ADD, aHandle.FHandle, @lEvent) < 0 then
|
||||||
|
Bail('Error adding handle to epoll', LSocketError);
|
||||||
|
end;
|
||||||
|
if FCount > High(FEvents) then
|
||||||
|
Inflate;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function Max(const a, b: Integer): Integer; inline;
|
||||||
|
begin
|
||||||
|
if a > b then
|
||||||
|
Result:=a
|
||||||
|
else
|
||||||
|
Result:=b;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLEpollEventer.CallAction: Boolean;
|
||||||
|
var
|
||||||
|
i, MasterChanges, Changes, ReadChanges: Integer;
|
||||||
|
Temp, TempRead: TLHandle;
|
||||||
|
MasterEvents: array[0..1] of TEpollEvent;
|
||||||
|
begin
|
||||||
|
Result:=False;
|
||||||
|
Changes:=0;
|
||||||
|
ReadChanges:=0;
|
||||||
|
|
||||||
|
MasterChanges:=epoll_wait(FEpollMasterFD, @MasterEvents[0], 2, FTimeout);
|
||||||
|
|
||||||
|
if MasterChanges > 0 then begin
|
||||||
|
for i:=0 to MasterChanges-1 do
|
||||||
|
if MasterEvents[i].Data.fd = FEpollFD then
|
||||||
|
Changes:=epoll_wait(FEpollFD, @FEvents[0], FCount, 0)
|
||||||
|
else
|
||||||
|
ReadChanges:=epoll_wait(FEpollReadFD, @FEventsRead[0], FCount, 0);
|
||||||
|
if (Changes < 0) or (ReadChanges < 0) then
|
||||||
|
Bail('Error on epoll: ', LSocketError)
|
||||||
|
else
|
||||||
|
Result:=Changes + ReadChanges > 0;
|
||||||
|
|
||||||
|
if Result then begin
|
||||||
|
FInLoop:=True;
|
||||||
|
for i:=0 to Max(Changes, ReadChanges)-1 do begin
|
||||||
|
Temp:=nil;
|
||||||
|
if i < Changes then begin
|
||||||
|
Temp:=TLHandle(FEvents[i].data.ptr);
|
||||||
|
|
||||||
|
if (not Temp.FDispose)
|
||||||
|
and (FEvents[i].events and EPOLLOUT = EPOLLOUT) then
|
||||||
|
if Assigned(Temp.FOnWrite) and not Temp.IgnoreWrite then
|
||||||
|
Temp.FOnWrite(Temp);
|
||||||
|
|
||||||
|
if Temp.FDispose then
|
||||||
|
AddForFree(Temp);
|
||||||
|
end; // writes
|
||||||
|
|
||||||
|
if i < ReadChanges then begin
|
||||||
|
TempRead:=TLHandle(FEventsRead[i].data.ptr);
|
||||||
|
|
||||||
|
if (not TempRead.FDispose)
|
||||||
|
and ((FEventsRead[i].events and EPOLLIN = EPOLLIN)
|
||||||
|
or (FEventsRead[i].events and EPOLLHUP = EPOLLHUP)
|
||||||
|
or (FEventsRead[i].events and EPOLLPRI = EPOLLPRI)) then
|
||||||
|
if Assigned(TempRead.FOnRead) and not TempRead.IgnoreRead then
|
||||||
|
TempRead.FOnRead(TempRead);
|
||||||
|
|
||||||
|
if TempRead.FDispose then
|
||||||
|
AddForFree(TempRead);
|
||||||
|
end; // reads
|
||||||
|
|
||||||
|
if i < Changes then begin
|
||||||
|
if not Assigned(Temp) then
|
||||||
|
Temp:=TLHandle(FEvents[i].data.ptr);
|
||||||
|
|
||||||
|
if (not Temp.FDispose)
|
||||||
|
and (FEvents[i].events and EPOLLERR = EPOLLERR) then
|
||||||
|
if Assigned(Temp.FOnError) and not Temp.IgnoreError then
|
||||||
|
Temp.FOnError(Temp, 'Handle error: ' + LStrError(LSocketError));
|
||||||
|
|
||||||
|
if Temp.FDispose then
|
||||||
|
AddForFree(Temp);
|
||||||
|
end; // errors
|
||||||
|
end;
|
||||||
|
FInLoop:=False;
|
||||||
|
if Assigned(FFreeRoot) then
|
||||||
|
FreeHandles;
|
||||||
|
end;
|
||||||
|
end else if MasterChanges < 0 then
|
||||||
|
Bail('Error on epoll: ', LSocketError);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function BestEventerClass: TLEventerClass;
|
||||||
|
|
||||||
|
function GetVersion(s: string): Integer;
|
||||||
|
const
|
||||||
|
Numbers = ['0'..'9'];
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
s:=StringReplace(s, '.', '', [rfReplaceAll]);
|
||||||
|
i:=1;
|
||||||
|
while (i <= Length(s)) and (s[i] in Numbers) do
|
||||||
|
Inc(i);
|
||||||
|
s:=Copy(s, 1, i - 1);
|
||||||
|
if Length(s) < 4 then // varies OS to OS
|
||||||
|
Insert('0', s, 3); // in linux, last part can be > 10
|
||||||
|
Result:=StrToInt(s);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$ifndef DISABLE_EPOLL}
|
||||||
|
var
|
||||||
|
u: TUTSName;
|
||||||
|
{$endif}
|
||||||
|
begin
|
||||||
|
Result:=TLSelectEventer;
|
||||||
|
{$ifndef DISABLE_EPOLL}
|
||||||
|
if fpUname(u) = 0 then // check for 2.6+
|
||||||
|
if GetVersion(u.release) >= 2600 then
|
||||||
|
Result:=TLEpollEventer;
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$endif} // Linux
|
32
utils/fppkg/lnet/sys/lepolleventerh.inc
Normal file
32
utils/fppkg/lnet/sys/lepolleventerh.inc
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{% lepolleventerh.inc included by levents.pas }
|
||||||
|
|
||||||
|
{$ifdef Linux}
|
||||||
|
|
||||||
|
PEpollEvent = ^epoll_event;
|
||||||
|
TEpollEvent = epoll_event;
|
||||||
|
PEpollData = ^epoll_data;
|
||||||
|
TEpollData = epoll_data;
|
||||||
|
|
||||||
|
{ TLEpollEventer }
|
||||||
|
|
||||||
|
TLEpollEventer = class(TLEventer)
|
||||||
|
protected
|
||||||
|
FTimeout: cInt;
|
||||||
|
FEvents: array of TEpollEvent;
|
||||||
|
FEventsRead: array of TEpollEvent;
|
||||||
|
FEpollReadFD: THandle; // this one monitors LT style for READ
|
||||||
|
FEpollFD: THandle; // this one monitors ET style for other
|
||||||
|
FEpollMasterFD: THandle; // this one monitors the first two
|
||||||
|
FFreeList: TFPObjectList;
|
||||||
|
function GetTimeout: DWord; override;
|
||||||
|
procedure SetTimeout(const Value: DWord); override;
|
||||||
|
procedure HandleIgnoreRead(aHandle: TLHandle); override;
|
||||||
|
procedure Inflate;
|
||||||
|
public
|
||||||
|
constructor Create; override;
|
||||||
|
destructor Destroy; override;
|
||||||
|
function AddHandle(aHandle: TLHandle): Boolean; override;
|
||||||
|
function CallAction: Boolean; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$endif} // linux
|
129
utils/fppkg/lnet/sys/lkqueueeventer.inc
Normal file
129
utils/fppkg/lnet/sys/lkqueueeventer.inc
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
{% lkqueueeventer.inc included by levents.pas }
|
||||||
|
|
||||||
|
{$ifdef BSD}
|
||||||
|
|
||||||
|
{ TLKQueueEventer }
|
||||||
|
|
||||||
|
constructor TLKQueueEventer.Create;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
Inflate;
|
||||||
|
FFreeSlot:=0;
|
||||||
|
FTimeout.tv_sec:=0;
|
||||||
|
FTimeout.tv_nsec:=0;
|
||||||
|
FQueue:=KQueue;
|
||||||
|
if FQueue < 0 then
|
||||||
|
raise Exception.Create('Unable to create kqueue');
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TLKQueueEventer.Destroy;
|
||||||
|
begin
|
||||||
|
fpClose(FQueue);
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLKQueueEventer.GetTimeout: DWord;
|
||||||
|
begin
|
||||||
|
Result:=FTimeout.tv_sec + FTimeout.tv_nsec * 1000 * 1000;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLKQueueEventer.SetTimeout(const Value: DWord);
|
||||||
|
begin
|
||||||
|
FTimeout.tv_sec:=Value div 1000;
|
||||||
|
FTimeout.tv_nsec:=(Value mod 1000) * 1000;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLKQueueEventer.HandleIgnoreRead(aHandle: TLHandle);
|
||||||
|
const
|
||||||
|
INBOOL: array[Boolean] of Integer = (EV_ENABLE, EV_DISABLE);
|
||||||
|
begin
|
||||||
|
EV_SET(@FChanges[FFreeSlot], aHandle.FHandle, EVFILT_READ,
|
||||||
|
INBOOL[aHandle.IgnoreRead], 0, 0, Pointer(aHandle));
|
||||||
|
|
||||||
|
Inc(FFreeSlot);
|
||||||
|
if FFreeSlot > Length(FChanges) then
|
||||||
|
Inflate;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLKQueueEventer.Inflate;
|
||||||
|
const
|
||||||
|
BASE_SIZE = 100;
|
||||||
|
var
|
||||||
|
OldLength: Integer;
|
||||||
|
begin
|
||||||
|
OldLength:=Length(FChanges);
|
||||||
|
if OldLength > 1 then begin
|
||||||
|
SetLength(FChanges, Sqr(OldLength));
|
||||||
|
SetLength(FEvents, Sqr(OldLength));
|
||||||
|
end else begin
|
||||||
|
SetLength(FChanges, BASE_SIZE);
|
||||||
|
SetLength(FEvents, BASE_SIZE);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLKQueueEventer.AddHandle(aHandle: TLHandle): Boolean;
|
||||||
|
begin
|
||||||
|
Result:=inherited AddHandle(aHandle);
|
||||||
|
|
||||||
|
if FFreeSlot > Length(FChanges) then
|
||||||
|
Inflate;
|
||||||
|
EV_SET(@FChanges[FFreeSlot], aHandle.FHandle, EVFILT_WRITE,
|
||||||
|
EV_ADD or EV_CLEAR, 0, 0, Pointer(aHandle));
|
||||||
|
Inc(FFreeSlot);
|
||||||
|
|
||||||
|
if FFreeSlot > Length(FChanges) then
|
||||||
|
Inflate;
|
||||||
|
if not aHandle.FIgnoreRead then begin
|
||||||
|
EV_SET(@FChanges[FFreeSlot], aHandle.FHandle, EVFILT_READ,
|
||||||
|
EV_ADD, 0, 0, Pointer(aHandle));
|
||||||
|
Inc(FFreeSlot);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLKQueueEventer.CallAction: Boolean;
|
||||||
|
var
|
||||||
|
i, n: Integer;
|
||||||
|
Temp: TLHandle;
|
||||||
|
begin
|
||||||
|
n:=KEvent(FQueue, @FChanges[0], FFreeSlot,
|
||||||
|
@FEvents[0], Length(FEvents), @FTimeout);
|
||||||
|
FFreeSlot:=0;
|
||||||
|
if n < 0 then
|
||||||
|
Bail('Error on kqueue: ', LSocketError);
|
||||||
|
Result:=n > 0;
|
||||||
|
if Result then begin
|
||||||
|
FInLoop:=True;
|
||||||
|
for i:=0 to n-1 do begin
|
||||||
|
Temp:=TLHandle(FEvents[i].uData);
|
||||||
|
|
||||||
|
if (not Temp.FDispose)
|
||||||
|
and (FEvents[i].Filter = EVFILT_WRITE) then
|
||||||
|
if Assigned(Temp.FOnWrite) and not Temp.IgnoreWrite then
|
||||||
|
Temp.FOnWrite(Temp);
|
||||||
|
|
||||||
|
if (not Temp.FDispose)
|
||||||
|
and (FEvents[i].Filter = EVFILT_READ) then
|
||||||
|
if Assigned(Temp.FOnRead) and not Temp.IgnoreRead then
|
||||||
|
Temp.FOnRead(Temp);
|
||||||
|
|
||||||
|
if (not Temp.FDispose)
|
||||||
|
and ((FEvents[i].Flags and EV_ERROR) > 0) then
|
||||||
|
if Assigned(Temp.FOnError) and not Temp.IgnoreError then
|
||||||
|
Temp.FOnError(Temp, 'Handle error' + LStrError(LSocketError));
|
||||||
|
|
||||||
|
if Temp.FDispose then
|
||||||
|
AddForFree(Temp);
|
||||||
|
end;
|
||||||
|
FInLoop:=False;
|
||||||
|
if Assigned(FFreeRoot) then
|
||||||
|
FreeHandles;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function BestEventerClass: TLEventerClass;
|
||||||
|
begin
|
||||||
|
Result:=TLKQueueEventer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$endif} // BSD
|
||||||
|
|
25
utils/fppkg/lnet/sys/lkqueueeventerh.inc
Normal file
25
utils/fppkg/lnet/sys/lkqueueeventerh.inc
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{% lkqueueeventerh.inc included by levents.pas }
|
||||||
|
|
||||||
|
{$ifdef BSD}
|
||||||
|
|
||||||
|
{ TLKQueueEventer }
|
||||||
|
|
||||||
|
TLKQueueEventer = class(TLEventer)
|
||||||
|
protected
|
||||||
|
FTimeout: TTimeSpec;
|
||||||
|
FEvents: array of TKEvent;
|
||||||
|
FChanges: array of TKEvent;
|
||||||
|
FFreeSlot: Integer;
|
||||||
|
FQueue: THandle;
|
||||||
|
function GetTimeout: DWord; override;
|
||||||
|
procedure SetTimeout(const Value: DWord); override;
|
||||||
|
procedure HandleIgnoreRead(aHandle: TLHandle); override;
|
||||||
|
procedure Inflate;
|
||||||
|
public
|
||||||
|
constructor Create; override;
|
||||||
|
destructor Destroy; override;
|
||||||
|
function AddHandle(aHandle: TLHandle): Boolean; override;
|
||||||
|
function CallAction: Boolean; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$endif} // bsd
|
51
utils/fppkg/lnet/sys/lspawnfcgiunix.inc
Normal file
51
utils/fppkg/lnet/sys/lspawnfcgiunix.inc
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
uses
|
||||||
|
Classes, BaseUnix;
|
||||||
|
|
||||||
|
function SpawnFCGIProcess(App, Enviro: string; const aPort: Word): Integer;
|
||||||
|
var
|
||||||
|
TheSocket: TLSocket;
|
||||||
|
i: Integer;
|
||||||
|
SL: TStringList;
|
||||||
|
aNil: Pointer = nil;
|
||||||
|
ppEnv, ppArgs: ppChar;
|
||||||
|
begin
|
||||||
|
Result:=FpFork;
|
||||||
|
|
||||||
|
if Result = 0 then begin
|
||||||
|
ppArgs:=@aNil;
|
||||||
|
|
||||||
|
for i:=3 to 10000 do
|
||||||
|
CloseSocket(i);
|
||||||
|
|
||||||
|
if CloseSocket(StdInputHandle) <> 0 then
|
||||||
|
Exit(LSocketError);
|
||||||
|
|
||||||
|
TheSocket:=TLSocket.Create;
|
||||||
|
TheSocket.Blocking:=True;
|
||||||
|
|
||||||
|
if not TheSocket.Listen(aPort) then
|
||||||
|
Exit(LSocketError);
|
||||||
|
|
||||||
|
ppEnv:=@aNil;
|
||||||
|
|
||||||
|
if Length(Enviro) > 0 then begin
|
||||||
|
SL:=TStringList.Create;
|
||||||
|
repeat
|
||||||
|
i:=Pos(':', Enviro);
|
||||||
|
if i > 0 then begin
|
||||||
|
SL.Add(Copy(Enviro, 1, i - 1));
|
||||||
|
Delete(Enviro, 1, i);
|
||||||
|
end else
|
||||||
|
SL.Add(Enviro);
|
||||||
|
until i = 0;
|
||||||
|
GetMem(ppEnv, SizeOf(pChar) * (SL.Count + 1));
|
||||||
|
for i:=0 to SL.Count-1 do
|
||||||
|
ppEnv[i]:=pChar(SL[i]);
|
||||||
|
ppEnv[SL.Count]:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FpExecve(pChar(App), ppArgs, ppEnv);
|
||||||
|
end else if Result > 0 then
|
||||||
|
Result:=0; // it went ok
|
||||||
|
end;
|
||||||
|
|
7
utils/fppkg/lnet/sys/lspawnfcgiwin.inc
Normal file
7
utils/fppkg/lnet/sys/lspawnfcgiwin.inc
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
function SpawnFCGIProcess(App, Enviro: string; const aPort: Word): Integer;
|
||||||
|
begin
|
||||||
|
Result:=0; // TODO: implement
|
||||||
|
end;
|
||||||
|
|
18
utils/fppkg/lnet/sys/osunits.inc
Normal file
18
utils/fppkg/lnet/sys/osunits.inc
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{$ifdef WINDOWS}
|
||||||
|
Winsock2,
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
{$ifdef UNIX}
|
||||||
|
BaseUnix, NetDB,
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
{$ifdef NETWARE}
|
||||||
|
WinSock,
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
{$ifdef OS2}
|
||||||
|
WinSock,
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
SysUtils, Sockets;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user