mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 11:29:27 +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/fprepos.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/pkghandler.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