diff options
Diffstat (limited to 'src/libopm')
| -rw-r--r-- | src/libopm/COPYING | 339 | ||||
| -rw-r--r-- | src/libopm/Makefile.am | 2 | ||||
| -rw-r--r-- | src/libopm/Makefile.in | 632 | ||||
| -rw-r--r-- | src/libopm/src/Makefile.am | 18 | ||||
| -rw-r--r-- | src/libopm/src/Makefile.in | 617 | ||||
| -rw-r--r-- | src/libopm/src/config.c | 249 | ||||
| -rw-r--r-- | src/libopm/src/config.h | 19 | ||||
| -rw-r--r-- | src/libopm/src/libopm.c | 1343 | ||||
| -rw-r--r-- | src/libopm/src/libopm.h | 63 | ||||
| -rw-r--r-- | src/libopm/src/list.c | 97 | ||||
| -rw-r--r-- | src/libopm/src/list.h | 40 | ||||
| -rw-r--r-- | src/libopm/src/memory.c | 73 | ||||
| -rw-r--r-- | src/libopm/src/memory.h | 28 | ||||
| -rw-r--r-- | src/libopm/src/opm.h | 70 | ||||
| -rw-r--r-- | src/libopm/src/opm_common.h | 21 | ||||
| -rw-r--r-- | src/libopm/src/opm_error.h | 26 | ||||
| -rw-r--r-- | src/libopm/src/opm_types.h | 49 | ||||
| -rw-r--r-- | src/libopm/src/proxy.c | 316 | ||||
| -rw-r--r-- | src/libopm/src/proxy.h | 15 |
19 files changed, 4017 insertions, 0 deletions
diff --git a/src/libopm/COPYING b/src/libopm/COPYING new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/src/libopm/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/src/libopm/Makefile.am b/src/libopm/Makefile.am new file mode 100644 index 0000000..dfa49b2 --- /dev/null +++ b/src/libopm/Makefile.am @@ -0,0 +1,2 @@ +AUTOMAKE_OPTIONS = foreign +SUBDIRS = src diff --git a/src/libopm/Makefile.in b/src/libopm/Makefile.in new file mode 100644 index 0000000..2cf5060 --- /dev/null +++ b/src/libopm/Makefile.in @@ -0,0 +1,632 @@ +# Makefile.in generated by automake 1.15.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2017 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libopm +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_arg_enable_assert.m4 \ + $(top_srcdir)/m4/ax_arg_enable_efence.m4 \ + $(top_srcdir)/m4/ax_arg_enable_warnings.m4 \ + $(top_srcdir)/m4/ax_arg_openssl.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_gcc_stack_protect.m4 \ + $(top_srcdir)/m4/ax_library_net.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/setup.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs \ + COPYING +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +SUBDIRS = src +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/libopm/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/libopm/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libopm/src/Makefile.am b/src/libopm/src/Makefile.am new file mode 100644 index 0000000..7726c07 --- /dev/null +++ b/src/libopm/src/Makefile.am @@ -0,0 +1,18 @@ +noinst_LTLIBRARIES = libopm.la + +libopm_la_SOURCES = config.c \ + config.h \ + libopm.c \ + libopm.h \ + list.c \ + list.h \ + memory.c \ + memory.h \ + opm_common.h \ + opm_error.h \ + opm.h \ + opm_types.h \ + proxy.c \ + proxy.h + +libopm_la_LIBADD = @LTLIBOBJS@ diff --git a/src/libopm/src/Makefile.in b/src/libopm/src/Makefile.in new file mode 100644 index 0000000..15db3dd --- /dev/null +++ b/src/libopm/src/Makefile.in @@ -0,0 +1,617 @@ +# Makefile.in generated by automake 1.15.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2017 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libopm/src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_arg_enable_assert.m4 \ + $(top_srcdir)/m4/ax_arg_enable_efence.m4 \ + $(top_srcdir)/m4/ax_arg_enable_warnings.m4 \ + $(top_srcdir)/m4/ax_arg_openssl.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_gcc_stack_protect.m4 \ + $(top_srcdir)/m4/ax_library_net.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/src/setup.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libopm_la_DEPENDENCIES = @LTLIBOBJS@ +am_libopm_la_OBJECTS = config.lo libopm.lo list.lo memory.lo proxy.lo +libopm_la_OBJECTS = $(am_libopm_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libopm_la_SOURCES) +DIST_SOURCES = $(libopm_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ + $(top_srcdir)/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = libopm.la +libopm_la_SOURCES = config.c \ + config.h \ + libopm.c \ + libopm.h \ + list.c \ + list.h \ + memory.c \ + memory.h \ + opm_common.h \ + opm_error.h \ + opm.h \ + opm_types.h \ + proxy.c \ + proxy.h + +libopm_la_LIBADD = @LTLIBOBJS@ +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libopm/src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libopm/src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libopm.la: $(libopm_la_OBJECTS) $(libopm_la_DEPENDENCIES) $(EXTRA_libopm_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libopm_la_OBJECTS) $(libopm_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libopm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memory.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proxy.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libopm/src/config.c b/src/libopm/src/config.c new file mode 100644 index 0000000..dfc4c48 --- /dev/null +++ b/src/libopm/src/config.c @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2002 Erik Fears + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to + * + * The Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307, USA. + * + * + */ + +#include "setup.h" + +#include <stdlib.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "memory.h" +#include "config.h" +#include "opm_error.h" +#include "opm_types.h" +#include "opm_common.h" +#include "list.h" + + +static const OPM_CONFIG_HASH_T HASH[] = +{ + { OPM_CONFIG_FD_LIMIT, OPM_TYPE_INT }, + { OPM_CONFIG_BIND_IP , OPM_TYPE_ADDRESS }, + { OPM_CONFIG_DNSBL_HOST, OPM_TYPE_STRING }, + { OPM_CONFIG_TARGET_STRING, OPM_TYPE_STRINGLIST }, + { OPM_CONFIG_SCAN_IP, OPM_TYPE_STRING }, + { OPM_CONFIG_SCAN_PORT, OPM_TYPE_INT }, + { OPM_CONFIG_MAX_READ, OPM_TYPE_INT }, + { OPM_CONFIG_TIMEOUT, OPM_TYPE_INT } +}; + +/* config_create + * + * Create an OPM_CONFIG_T struct, set default values and return it + * + * Parameters: + * None; + * + * Return: + * Pointer to allocated OPM_CONFIG_T struct + */ +OPM_CONFIG_T * +libopm_config_create(void) +{ + const unsigned int num = sizeof(HASH) / sizeof(OPM_CONFIG_HASH_T); + OPM_CONFIG_T *ret; + + ret = libopm_calloc(sizeof(OPM_CONFIG_T)); + ret->vars = libopm_calloc(sizeof(void *) * num); + + + /* + * Set default config items. This in the future would be much better + * if it could set realistic defaults for each individual config item. + * + * OPM_TYPE_INT = 0 + * OPM_TYPE_STRING = "" + * OPM_TYPE_ADDRESS = 0.0.0.0 + * OPM_TYPE_STRINGLIST = empty list + */ + for (unsigned int i = 0; i < num; ++i) + { + switch (libopm_config_gettype(i)) + { + case OPM_TYPE_INT: + ret->vars[i] = libopm_calloc(sizeof(int)); + break; + + case OPM_TYPE_STRING: + ret->vars[i] = libopm_strdup(""); + break; + + case OPM_TYPE_ADDRESS: + ret->vars[i] = libopm_calloc(sizeof(struct sockaddr_in)); + break; + + case OPM_TYPE_STRINGLIST: + ret->vars[i] = libopm_calloc(sizeof(OPM_LIST_T)); + break; + + default: + ret->vars[i] = NULL; + } + } + + return ret; +} + +/* config_free + * + * Free config structure and clean up + * + * Parameters: + * config: Structure to free/cleanup + * + * Return: + * None + */ +void +libopm_config_free(OPM_CONFIG_T *config) +{ + const unsigned int num = sizeof(HASH) / sizeof(OPM_CONFIG_HASH_T); + OPM_NODE_T *p, *next; + OPM_LIST_T *list; + + for (unsigned int i = 0; i < num; ++i) + { + if (config->vars[i] == NULL) + continue; + + switch (libopm_config_gettype(i)) + { + case OPM_TYPE_STRINGLIST: + list = config->vars[i]; + + LIST_FOREACH_SAFE(p, next, list->head) + { + libopm_free(p->data); + libopm_free(p); + } + + break; + + default: + libopm_free(config->vars[i]); + break; + } + } + + libopm_free(config->vars); + libopm_free(config); +} + +/* config_set + * + * Set configuration options on config struct. + * + * Parameters: + * config: Config struct to set parameters on + * key: Variable within the struct to set + * value: Address of value to set + * + * Return: + * 1: Variable was set + * 0: Some error occured + */ + +OPM_ERR_T +libopm_config_set(OPM_CONFIG_T *config, unsigned int key, const void *value) +{ + const unsigned int num = sizeof(HASH) / sizeof(OPM_CONFIG_HASH_T); + OPM_NODE_T *node; + + if (key >= num) + return OPM_ERR_BADKEY; /* Return appropriate error code eventually */ + + switch (libopm_config_gettype(key)) + { + case OPM_TYPE_STRING: + if (config->vars[key]) + libopm_free(config->vars[key]); + + config->vars[key] = libopm_strdup(value); + break; + + case OPM_TYPE_INT: + *(int *)config->vars[key] = *(const int *)value; + break; + + case OPM_TYPE_ADDRESS: + if (inet_pton(AF_INET, value, &(((struct sockaddr_in *)config->vars[key])->sin_addr)) <= 0) + return OPM_ERR_BADVALUE; /* Return appropriate err code */ + + break; + + case OPM_TYPE_STRINGLIST: + node = libopm_node_create(libopm_strdup(value)); + libopm_list_add(config->vars[key], node); + break; + + default: + return OPM_ERR_BADKEY; /* return appropriate err code */ + } + + return OPM_SUCCESS; +} + +/* config_gettype + * + * Get type of key. + * + * Parameters: + * key: Key to get type of. + * + * Return: + * TYPE_? of key + */ +int +libopm_config_gettype(int key) +{ + const unsigned int num = sizeof(HASH) / sizeof(OPM_CONFIG_HASH_T); + + for (unsigned int i = 0; i < num; ++i) + if (HASH[i].key == key) + return HASH[i].type; + + return 0; +} + +/* config + * + * Retrieve a specific config variable from + * an OPM_CONFIG_T struct. This is basically a + * wrapper to extracting the variable from the + * array. + * + * Parameters: + * config: Config struct to extract from + * key: Value to extract + * + * Return: + * -ADDRESS- to extracted value in array. This address + * will have to be cast on the return end to be any use. + */ +void * +libopm_config(OPM_CONFIG_T *config, unsigned int key) +{ + return config->vars[key]; +} diff --git a/src/libopm/src/config.h b/src/libopm/src/config.h new file mode 100644 index 0000000..7bfc80d --- /dev/null +++ b/src/libopm/src/config.h @@ -0,0 +1,19 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#include "libopm.h" + +typedef struct _opm_config_hash OPM_CONFIG_HASH_T; + +struct _opm_config_hash +{ + int key; + int type; +}; + +extern void libopm_config_free(OPM_CONFIG_T *); +extern void *libopm_config(OPM_CONFIG_T *, unsigned int); +extern int libopm_config_gettype(int); +extern OPM_CONFIG_T *libopm_config_create(void); +extern OPM_ERR_T libopm_config_set(OPM_CONFIG_T *, unsigned int , const void *); +#endif /* CONFIG_H */ diff --git a/src/libopm/src/libopm.c b/src/libopm/src/libopm.c new file mode 100644 index 0000000..89b376f --- /dev/null +++ b/src/libopm/src/libopm.c @@ -0,0 +1,1343 @@ +/* + * Copyright (C) 2002-2003 Erik Fears + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to + * + * The Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307, USA. + * + * + */ + +#include "setup.h" + +#include <errno.h> +#include <time.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> +#include <poll.h> +#ifdef HAVE_LIBCRYPTO +#include <openssl/ssl.h> +#endif + +#include "config.h" +#include "libopm.h" +#include "memory.h" +#include "opm_error.h" +#include "opm_types.h" +#include "opm_common.h" +#include "list.h" +#include "proxy.h" + + +static OPM_PROTOCOL_CONFIG_T *libopm_protocol_config_create(void); +static void libopm_protocol_config_free(OPM_PROTOCOL_CONFIG_T *); + +static OPM_SCAN_T *libopm_scan_create(OPM_T *, OPM_REMOTE_T *); +static void libopm_scan_free(OPM_SCAN_T *); + +static OPM_CONNECTION_T *libopm_connection_create(void); +static void libopm_connection_free(OPM_CONNECTION_T *); + +static void libopm_check_establish(OPM_T *); +static void libopm_check_poll(OPM_T *); +static void libopm_check_closed(OPM_T *); +static void libopm_check_queue(OPM_T *); + +static void libopm_do_connect(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +static void libopm_do_readready(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +static int libopm_do_readready_tls(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +static void libopm_do_writeready(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +static void libopm_do_hup(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +static void libopm_do_read(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +static void libopm_do_openproxy(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +static void libopm_do_callback(OPM_T *, OPM_REMOTE_T *, int, int); + +static OPM_REMOTE_T *libopm_setup_remote(OPM_REMOTE_T *, OPM_CONNECTION_T *); + + +/* OPM_PROTOCOLS hash + * + * OPM_PPROTOCOLS hashes the protocol types (int) to functions + * which handle the protocol (sending/receiving protocol specific + * data). + * + */ +static OPM_PROTOCOL_T OPM_PROTOCOLS[] = +{ + { OPM_TYPE_HTTP, libopm_proxy_http_write, NULL, 0 }, + { OPM_TYPE_SOCKS4, libopm_proxy_socks4_write, NULL, 0 }, + { OPM_TYPE_SOCKS5, libopm_proxy_socks5_write, NULL, 0 }, + { OPM_TYPE_ROUTER, libopm_proxy_router_write, NULL, 0 }, + { OPM_TYPE_WINGATE, libopm_proxy_wingate_write, NULL, 0 }, + { OPM_TYPE_HTTPPOST, libopm_proxy_httppost_write, NULL, 0 }, + { OPM_TYPE_DREAMBOX, libopm_proxy_dreambox_write, NULL, 0 }, + { OPM_TYPE_HTTPS, libopm_proxy_https_write, libopm_do_readready_tls, 1 }, + { OPM_TYPE_HTTPSPOST, libopm_proxy_httpspost_write, libopm_do_readready_tls, 1 }, + { OPM_TYPE_SSH, NULL, NULL, 0 } +}; + +/* opm_create + * + * Initialize a new scanner and return a pointer to it. + * + * Parameters: + * None + * + * Return + * Pointer to new OPM_T (scanner) + */ +OPM_T * +opm_create(void) +{ + OPM_T *ret; + + ret = libopm_calloc(sizeof(*ret)); + ret->config = libopm_config_create(); + + /* Setup callbacks */ + ret->callbacks = libopm_calloc(sizeof(OPM_CALLBACK_T) * CBLEN); + + return ret; +} + +/* opm_remote_create + * + * Create OPM_REMOTE_T struct, fill it with neccessary + * default values and return it to the client. + * + * Parameters: + * ip: IP of remote host + * + * Return: + * Address of OPM_REMOTE_T created + * + */ +OPM_REMOTE_T * +opm_remote_create(const char *ip) +{ + OPM_REMOTE_T *ret; + + ret = libopm_calloc(sizeof(*ret)); + ret->ip = libopm_strdup(ip); + + return ret; +} + +/* opm_remote_free + * + * Free OPM_REMOTE_T struct and cleanup + * + * Parameters: + * remote: Struct to free + * + * Return: + * None + */ +void +opm_remote_free(OPM_REMOTE_T *remote) +{ + OPM_NODE_T *p, *next; + OPM_PROTOCOL_CONFIG_T *ppc; + + libopm_free(remote->ip); + + LIST_FOREACH_SAFE(p, next, remote->protocols.head) + { + ppc = p->data; + + libopm_protocol_config_free(ppc); + libopm_list_remove(&remote->protocols, p); + libopm_node_free(p); + } + + libopm_free(remote); +} + +/* opm_callback + * Register scanner level callback + * + * Parameters + * scanner: scanner struct + * type: callback type + * Return: + * Error code + */ + +OPM_ERR_T +opm_callback(OPM_T *scanner, int type, OPM_CALLBACK_FUNC *function, void *data) +{ + if (type < 0 || type >= CBLEN) + return OPM_ERR_CBNOTFOUND; + + scanner->callbacks[type].func = function; + scanner->callbacks[type].data = data; + + return OPM_SUCCESS; +} + +/* opm_free + * + * Free OPM_T (scanner) and cleanup + * + * Parameters: + * scanner: Address of OPM_T to cleanup + * + * Return: + * None + */ +void +opm_free(OPM_T *scanner) +{ + OPM_NODE_T *p, *next; + OPM_PROTOCOL_CONFIG_T *ppc; + OPM_SCAN_T *scan; + + libopm_config_free(scanner->config); + + LIST_FOREACH_SAFE(p, next, scanner->protocols.head) + { + ppc = p->data; + + libopm_protocol_config_free(ppc); + libopm_list_remove(&scanner->protocols, p); + libopm_node_free(p); + } + + LIST_FOREACH_SAFE(p, next, scanner->scans.head) + { + scan = p->data; + + libopm_scan_free(scan); + libopm_list_remove(&scanner->scans, p); + libopm_node_free(p); + } + + LIST_FOREACH_SAFE(p, next, scanner->queue.head) + { + scan = p->data; + + libopm_scan_free(scan); + libopm_list_remove(&scanner->queue, p); + libopm_node_free(p); + } + + libopm_free(scanner->callbacks); + libopm_free(scanner); +} + +/* opm_config + * + * Wrapper to config_set. Set configuration variables + * on the config struct. + * + * Parameters: + * scanner: OPM_T struct the config struct resides in + * key: Variable within the config struct to set + * value: Address of value to set variable (key) to + * + * Return: + * OPM_ERR_T containing error code + */ +OPM_ERR_T +opm_config(OPM_T *scanner, int key, const void *value) +{ + return libopm_config_set(scanner->config, key, value); +} + +/* opm_addtype + * + * Add a proxy type and port to the list of protocols + * a scanner will use. + * + * Parameters: + * scanner: pointer to scanner struct + * type: type of proxy to scan (used in hashing to the functions) + * port: port this specific type/protocol will scan on + * Return: + * OPM_SUCCESS: Successful protocol add + * OPM_ERR_BADPROTOCOL: Protocol is unknown + */ +OPM_ERR_T +opm_addtype(OPM_T *scanner, int type, unsigned short int port) +{ + OPM_NODE_T *node; + OPM_PROTOCOL_CONFIG_T *protocol_config; + + for (unsigned int i = 0; i < sizeof(OPM_PROTOCOLS) / sizeof(OPM_PROTOCOL_T); ++i) + { + if (type == OPM_PROTOCOLS[i].type) + { +#ifndef HAVE_LIBCRYPTO + if (OPM_PROTOCOLS[i].use_tls) + return OPM_ERR_BADPROTOCOL; +#endif + protocol_config = libopm_protocol_config_create(); + protocol_config->type = &OPM_PROTOCOLS[i]; + protocol_config->port = port; + + node = libopm_node_create(protocol_config); + libopm_list_add(&scanner->protocols, node); + + return OPM_SUCCESS; + } + } + + return OPM_ERR_BADPROTOCOL; +} + +/* opm_remote_addtype + * + * Add a proxy type and port to the list of protocols + * a scanner will use. + * + * Parameters: + * remote: pointer to scanner struct + * type: type of proxy to scan (used in hashing to the functions) + * port: port this specific type/protocol will scan on + * Return: + * OPM_SUCCESS: Successful protocol add + * OPM_ERR_BADPROTOCOL: Protocol is unknown + */ +OPM_ERR_T opm_remote_addtype(OPM_REMOTE_T *remote, int type, unsigned short int port) +{ + OPM_NODE_T *node; + OPM_PROTOCOL_CONFIG_T *protocol_config; + + for (unsigned int i = 0; i < sizeof(OPM_PROTOCOLS) / sizeof(OPM_PROTOCOL_T); ++i) + { + if (type == OPM_PROTOCOLS[i].type) + { +#ifndef HAVE_LIBCRYPTO + if (OPM_PROTOCOLS[i].use_tls) + return OPM_ERR_BADPROTOCOL; +#endif + protocol_config = libopm_protocol_config_create(); + protocol_config->type = &OPM_PROTOCOLS[i]; + protocol_config->port = port; + + node = libopm_node_create(protocol_config); + libopm_list_add(&remote->protocols, node); + + return OPM_SUCCESS; + } + } + + return OPM_ERR_BADPROTOCOL; +} + +/* libopm_protocol_config_create + * + * Allocate and return address of a new OPM_PROTOCOL_CONFIG_T + * + * Parameters: + * None + * + * Return: + * Address of new OPM_PROTOCOL_CONFIG_T + */ +static OPM_PROTOCOL_CONFIG_T * +libopm_protocol_config_create(void) +{ + OPM_PROTOCOL_CONFIG_T *ret; + + ret = libopm_calloc(sizeof(*ret)); + + return ret; +} + +/* protocol_config_free + * + * Free OPM_PROTOCOL_CONFIG_T struct + * + * Parameters: + * protocol: struct to free + * + * Return: + * None + */ +static void +libopm_protocol_config_free(OPM_PROTOCOL_CONFIG_T *protocol) +{ + libopm_free(protocol); +} + +/* opm_scan + * + * Scan remote host. The opm_scan function takes an OPM_REMOTE_T + * struct, calculates the in_addr of the remote host, and creates + * a scan list based on protocols defined in the scanner. + * + * Parameters: + * scanner: Scanner to scan host on + * remote: OPM_REMOTE_T defining remote host + * + * Return: + * (to be written) + */ +OPM_ERR_T +opm_scan(OPM_T *scanner, OPM_REMOTE_T *remote) +{ + OPM_SCAN_T *scan; /* New scan for OPM_T */ + OPM_NODE_T *node; /* Node we'll add scan to when we link it to scans */ + struct in_addr in; + + if (LIST_SIZE(&scanner->protocols) == 0 && + LIST_SIZE(&remote->protocols) == 0) + return OPM_ERR_NOPROTOCOLS; + + /* + * XXX: libopm ideally shouldn't see an IP address in string representation. + * Could have been stuffed into the _OPM_REMOTE struct by the caller that + * already does getaddrinfo() anyway. + */ + if (inet_pton(AF_INET, remote->ip, &in) <= 0) + return OPM_ERR_BADADDR; + + scan = libopm_scan_create(scanner, remote); + memcpy(&scan->addr.sin_addr, &in, sizeof(scan->addr.sin_addr)); + + node = libopm_node_create(scan); + libopm_list_add(&scanner->queue, node); + + return OPM_SUCCESS; +} + +/* opm_end + * + * End a scan prematurely. + * + * Parameters: + * scanner: Scanner to end scan on + * remote: Pointer to remote struct to search for and end + * + * Return: + * No return. OPM_CALLBACK_END will still be called as normal. + */ +void +opm_end(OPM_T *scanner, OPM_REMOTE_T *remote) +{ + OPM_NODE_T *node1, *node2, *next1, *next2; + OPM_SCAN_T *scan; + OPM_CONNECTION_T *conn; + + /* End active scans */ + opm_endscan(scanner, remote); + + /* + * Secondly remove all traces of it in the queue. Once removed we have to call + * OPM_CALLBACK_END + */ + LIST_FOREACH_SAFE(node1, next1, scanner->queue.head) + { + scan = node1->data; + + if (scan->remote == remote) + { + /* Free all connections */ + LIST_FOREACH_SAFE(node2, next2, scan->connections.head) + { + conn = node2->data; + + libopm_list_remove(&scan->connections, node2); + libopm_connection_free(conn); + libopm_node_free(node2); + continue; + } + + /* OPM_CALLBACK_END because check_closed normally handles this */ + libopm_do_callback(scanner, scan->remote, OPM_CALLBACK_END, 0); + + /* Free up the scan */ + libopm_list_remove(&scanner->queue, node1); + libopm_scan_free(scan); + libopm_node_free(node1); + } + } +} + +/* opm_endscan + * + * End a scan prematurely. Only end non-queued scans. This is useful + * because it only checks the active scan list (saving time), where + * opm_end checks both the scan and the possibly large queue. + * + * Parameters: + * scanner: Scanner to end scan on + * remote: Pointer to remote struct to search for and end + * + * Return: + * No return. OPM_CALLBACK_END will still be called as normal. + */ +void +opm_endscan(OPM_T *scanner, OPM_REMOTE_T *remote) +{ + OPM_NODE_T *node1, *node2; + OPM_SCAN_T *scan; + OPM_CONNECTION_T *conn; + + /* + * First check to see if it's in the queue, if it is set all connections closed + * Next cycle of libopm_check_closed will take care of the garbage and handle + * OPM_CALLBACK_END + */ + LIST_FOREACH(node1, scanner->scans.head) + { + scan = node1->data; + + if (scan->remote == remote) + { + LIST_FOREACH(node2, scan->connections.head) + { + conn = node2->data; + conn->state = OPM_STATE_CLOSED; + } + } + } +} + +/* opm_active + + Return number of scans in a scanner left. + + Parameters: + scanner: Scanner to return active scans on + + Return: + Number of active scans, both queued and active. +*/ +size_t +opm_active(OPM_T *scanner) +{ + return LIST_SIZE(&scanner->queue) + LIST_SIZE(&scanner->scans); +} + +/* scan_create + * + * Create new OPM_SCAN_T struct + * + * Parameters: + * scanner: Scanner the scan is being created for. This + * is needed to get information on currently set + * protocols/config. + * + * remote: Remote host this scan will be scanning + * + * Return + * Address of new struct + */ +static OPM_SCAN_T * +libopm_scan_create(OPM_T *scanner, OPM_REMOTE_T *remote) +{ + OPM_SCAN_T *ret; + OPM_CONNECTION_T *conn; + OPM_NODE_T *node, *p; +#ifdef HAVE_LIBCRYPTO + static int tls_init = 0; + static SSL_CTX *ctx_client; + + if (!tls_init) + { + tls_init = 1; + SSLeay_add_ssl_algorithms(); + + ctx_client = SSL_CTX_new(SSLv23_client_method()); + if (!ctx_client) + exit(EXIT_FAILURE); + } +#endif + + ret = libopm_calloc(sizeof(*ret)); + ret->remote = remote; + + /* Setup list of connections, one for each protocol */ + LIST_FOREACH(p, scanner->protocols.head) + { + conn = libopm_connection_create(); + + conn->protocol = ((OPM_PROTOCOL_CONFIG_T *)p->data)->type; + conn->port = ((OPM_PROTOCOL_CONFIG_T *)p->data)->port; + +#ifdef HAVE_LIBCRYPTO + if (conn->protocol->use_tls) + /* SSL_new does only fail if OOM in which case HOPM exits anyway */ + conn->tls_handle = SSL_new(ctx_client); +#endif + + node = libopm_node_create(conn); + libopm_list_add(&ret->connections, node); + } + + /* + * Do the same for any specific protocols the remote struct might be configured with + */ + LIST_FOREACH(p, remote->protocols.head) + { + conn = libopm_connection_create(); + + conn->protocol = ((OPM_PROTOCOL_CONFIG_T *)p->data)->type; + conn->port = ((OPM_PROTOCOL_CONFIG_T *)p->data)->port; + +#ifdef HAVE_LIBCRYPTO + if (conn->protocol->use_tls) + /* SSL_new does only fail if OOM in which case HOPM exits anyway */ + conn->tls_handle = SSL_new(ctx_client); +#endif + + node = libopm_node_create(conn); + libopm_list_add(&ret->connections, node); + } + + return ret; +} + +/* scan_free + * + * Free and cleanup OPM_SCAN_T struct + * + * Parametsr: + * scan: Scan struct to free + * + * Return: + * None + */ +static void +libopm_scan_free(OPM_SCAN_T *scan) +{ + OPM_NODE_T *p, *next; + OPM_CONNECTION_T *conn; + + LIST_FOREACH_SAFE(p, next, scan->connections.head) + { + conn = p->data; + + libopm_connection_free(conn); + libopm_list_remove(&scan->connections, p); + libopm_node_free(p); + } + + libopm_free(scan); +} + +/* connection_create + * + * Allocate new OPM_CONNECTION_T + * + * Parameters: + * None + * + * Return: + * Address of new OPM_CONNECTION_T + */ +static OPM_CONNECTION_T * +libopm_connection_create(void) +{ + OPM_CONNECTION_T *ret; + + ret = libopm_calloc(sizeof(*ret)); + ret->state = OPM_STATE_UNESTABLISHED; + + return ret; +} + +/* connection_free + * + * Free OPM_CONNECTION_T struct + * + * Parameters: + * conn: Address of struct to free + * + * Return: + * None + */ +static void +libopm_connection_free(OPM_CONNECTION_T *conn) +{ + libopm_free(conn); +} + +/* opm_cycle + * + * Perform tasks (called by client's loop) + * + * Parameters: + * None + * Return: + * None + */ +void +opm_cycle(OPM_T *scanner) +{ + libopm_check_queue(scanner); /* Move scans from the queue to the live scan list */ + libopm_check_establish(scanner); /* Make new connections if possible */ + libopm_check_poll(scanner); /* Poll connections for IO and proxy test */ + libopm_check_closed(scanner); /* Check for closed or timed out connections */ +} + +/* check_queue + * + * Move scans from the queue to the live scan list as long as there is + * room. + * + * Parameters: + * scanner: Scanner to check queue on + * + * Return: + * None + */ +static void +libopm_check_queue(OPM_T *scanner) +{ + OPM_NODE_T *node; + OPM_SCAN_T *scan; + unsigned int protocols, projected, fd_limit; + + if (LIST_SIZE(&scanner->queue) == 0) + return; + + fd_limit = *(int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT); + projected = scanner->fd_use; + + /* + * We want to keep the live scan list as small as possible, so only move + * queued scans to the live list if they will not push above fd_limit + */ + while (LIST_SIZE(&scanner->queue) > 0) + { + /* Grab the top scan */ + scan = scanner->queue.head->data; + protocols = LIST_SIZE(&scan->connections); + + /* Check if it will fit in the live scan list */ + if ((protocols + projected) > fd_limit) + break; + + /* + * Scans on the top of the queue were added first, swap the head off the + * top of the queue and add it to the tail of the live scan list + */ + node = libopm_list_remove(&scanner->queue, scanner->queue.head); + libopm_list_add(&scanner->scans, node); + projected += protocols; + } +} + +/* check_establish + * + * Make new connections if there are free file descriptors and connections + * to be made. + * + * Parameters: + * scanner: Scanner to check for establish on + * Return: + * None + */ +static void +libopm_check_establish(OPM_T *scanner) +{ + OPM_NODE_T *node1, *node2; + OPM_SCAN_T *scan; + OPM_CONNECTION_T *conn; + unsigned int fd_limit; + + if (LIST_SIZE(&scanner->scans) == 0) + return; + + fd_limit = *(int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT); + + if (scanner->fd_use >= fd_limit) + return; + + LIST_FOREACH(node1, scanner->scans.head) + { + scan = node1->data; + + LIST_FOREACH(node2, scan->connections.head) + { + /* Only scan if we have free file descriptors */ + if (scanner->fd_use >= fd_limit) + return; + + conn = node2->data; + + if (conn->state == OPM_STATE_UNESTABLISHED) + libopm_do_connect(scanner, scan, conn); + } + } +} + +/* check_closed + * + * Check for connections which have timed out or are + * closed. Connections timed out still need to be closed. + * + * Remove the connection from the list of connections, free + * the connection struct and free the list node. Then if this is + * the last connection of the scan, consider the scan completed and + * free the scan aswell (and callback that the scan ended). + * + * Parameters: + * scanner: Scanner to check on + * Return: + * None + */ +static void +libopm_check_closed(OPM_T *scanner) +{ + time_t present; + int timeout; + OPM_NODE_T *node1, *node2, *next1, *next2; + OPM_SCAN_T *scan; + OPM_CONNECTION_T *conn; + + if (LIST_SIZE(&scanner->scans) == 0) + return; + + time(&present); + timeout = *(int *)libopm_config(scanner->config, OPM_CONFIG_TIMEOUT); + + LIST_FOREACH_SAFE(node1, next1, scanner->scans.head) + { + scan = node1->data; + + LIST_FOREACH_SAFE(node2, next2, scan->connections.head) + { + conn = node2->data; + + if (conn->state == OPM_STATE_CLOSED) + { +#ifdef HAVE_LIBCRYPTO + if (conn->protocol->use_tls) + { + SSL_set_shutdown(conn->tls_handle, SSL_RECEIVED_SHUTDOWN); + if (!SSL_shutdown(conn->tls_handle)) + SSL_shutdown(conn->tls_handle); + SSL_free(conn->tls_handle); + } +#endif + if (conn->fd > -1) + close(conn->fd); + + scanner->fd_use--; + + libopm_list_remove(&scan->connections, node2); + libopm_connection_free(conn); + libopm_node_free(node2); + continue; + } + + if (((present - conn->creation) >= timeout) && conn->state != OPM_STATE_UNESTABLISHED) + { +#ifdef HAVE_LIBCRYPTO + if (conn->protocol->use_tls) + { + SSL_set_shutdown(conn->tls_handle, SSL_RECEIVED_SHUTDOWN); + if (!SSL_shutdown(conn->tls_handle)) + SSL_shutdown(conn->tls_handle); + SSL_free(conn->tls_handle); + } +#endif + if (conn->fd > -1) + close(conn->fd); + + scanner->fd_use--; + + libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_TIMEOUT, 0); + libopm_list_remove(&scan->connections, node2); + libopm_connection_free(conn); + libopm_node_free(node2); + continue; + } + } + + /* + * No more connections left in this scan, let the client know the scan has + * ended, then remove the scan from the scanner, and free it up. + */ + if (LIST_SIZE(&scan->connections) == 0) + { + libopm_do_callback(scanner, scan->remote, OPM_CALLBACK_END, 0); + libopm_list_remove(&scanner->scans, node1); + libopm_scan_free(scan); + libopm_node_free(node1); + } + } +} + +/* do_connect + * + * Call socket() and connect() to start a scan. + * + * Parametsr: + * scan: Scan struct containing the connection + * conn: Connection to establish + * Return: + * None + */ +static void +libopm_do_connect(OPM_T * scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ + struct sockaddr_in *bind_ip; + struct sockaddr_in *addr; /* Outgoing host */ + struct sockaddr_in local_addr; /* For binding */ + + addr = &scan->addr; /* Already have the IP in byte format from opm_scan */ + addr->sin_family = AF_INET; + addr->sin_port = htons(conn->port); + + bind_ip = (struct sockaddr_in *)libopm_config(scanner->config, OPM_CONFIG_BIND_IP); + + conn->fd = socket(AF_INET, SOCK_STREAM, 0); + scanner->fd_use++; /* Increase file descriptor use */ + + if (conn->fd == -1) + { + libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_NOFD); + conn->state = OPM_STATE_CLOSED; + return; + } + + if (bind_ip) + { + memset(&local_addr, 0, sizeof(local_addr)); + + local_addr.sin_addr.s_addr = bind_ip->sin_addr.s_addr; + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(0); + + if (bind(conn->fd, (struct sockaddr *)&local_addr, sizeof(local_addr)) == -1) + { + libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_BIND); + conn->state = OPM_STATE_CLOSED; + return; + } + } + + /* Set socket non blocking */ + fcntl(conn->fd, F_SETFL, O_NONBLOCK); + + connect(conn->fd, (struct sockaddr *)addr, sizeof(*addr)); + +#ifdef HAVE_LIBCRYPTO + if (conn->protocol->use_tls) + SSL_set_fd(conn->tls_handle, conn->fd); +#endif + + conn->state = OPM_STATE_ESTABLISHED; + time(&conn->creation); /* Stamp creation time, for timeout */ +} + +/* check_poll + * + * Check sockets for ready read/write + * + * Parameters: + * scanner: Scanner to isolate check on + * Return: + * None + */ +static void +libopm_check_poll(OPM_T *scanner) +{ + OPM_NODE_T *node1, *node2; + OPM_SCAN_T *scan; + OPM_CONNECTION_T *conn; + unsigned int size = 0; + static unsigned int ufds_size; + static struct pollfd *ufds = NULL; + + /* Grow pollfd array (ufds) as needed */ + if (ufds_size < (*(unsigned int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT))) + { + libopm_free(ufds); + + ufds = libopm_calloc((sizeof *ufds) * (*(unsigned int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT))); + ufds_size = (*(unsigned int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT)); + } + + if (LIST_SIZE(&scanner->scans) == 0) + return; + + LIST_FOREACH(node1, scanner->scans.head) + { + scan = node1->data; + + LIST_FOREACH(node2, scan->connections.head) + { + if (size >= ufds_size) + break; + + conn = node2->data; + + if (conn->state < OPM_STATE_ESTABLISHED || + conn->state == OPM_STATE_CLOSED) + continue; + + ufds[size].events = 0; + ufds[size].revents = 0; + ufds[size].fd = conn->fd; + + /* Check for HUNG UP. */ + ufds[size].events |= POLLHUP; + /* Check for INVALID FD */ + ufds[size].events |= POLLNVAL; + + switch (conn->state) + { + case OPM_STATE_ESTABLISHED: + ufds[size].events |= POLLOUT; + break; + case OPM_STATE_NEGSENT: + ufds[size].events |= POLLIN; + break; + } + + size++; + } + } + + switch (poll(ufds, size, 0)) + { + case -1: + /* error in select/poll */ + return; + case 0: + /* Nothing to do */ + return; + + /* Pass pointer to connection to handler. */ + } + + LIST_FOREACH(node1, scanner->scans.head) + { + scan = node1->data; + + LIST_FOREACH(node2, scan->connections.head) + { + conn = node2->data; + + for (unsigned int i = 0; i < size; ++i) + { + if ((ufds[i].fd == conn->fd) && (conn->state != OPM_STATE_CLOSED)) + { + if (ufds[i].revents & POLLIN) + libopm_do_readready(scanner, scan, conn); + if (ufds[i].revents & POLLOUT) + libopm_do_writeready(scanner, scan, conn); + if (ufds[i].revents & POLLHUP) + libopm_do_hup(scanner, scan, conn); + } + } + } + } +} + +static int +libopm_do_readready_tls(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ +#ifdef HAVE_LIBCRYPTO + int max_read, length; + char readbuf[LIBOPM_TLS_RECORD_SIZE]; + + if (!SSL_is_init_finished(conn->tls_handle)) + return 0; + + if ((length = SSL_read(conn->tls_handle, readbuf, sizeof(readbuf))) <= 0) + { + switch (SSL_get_error(conn->tls_handle, length)) + { + /* TBD: possibly could recover here from some errors */ + default: + libopm_do_hup(scanner, scan, conn); + return 0; + } + } + + max_read = *(int *)libopm_config(scanner->config, OPM_CONFIG_MAX_READ); + + for (const char *p = readbuf, *end = readbuf + length; p < end; ++p) + { + conn->bytes_read++; + + if (conn->bytes_read >= max_read) + { + libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_MAX_READ); + conn->state = OPM_STATE_CLOSED; + return 0; + } + + if (*p == '\0' || *p == '\r') + continue; + + if (*p == '\n') + { + conn->readbuf[conn->readlen] = '\0'; + conn->readlen = 0; + + libopm_do_read(scanner, scan, conn); + + if (conn->state == OPM_STATE_CLOSED) + return 0; + + continue; + } + + if (conn->readlen < READBUFLEN) + conn->readbuf[++(conn->readlen) - 1] = *p; /* -1 to pad for null term */ + } +#endif + return 0; +} + +/* do_readready + * + * Remote connection is read ready, read the data into a buffer and check it against + * the target_string if neccessary + * + * Parameters: + * scanner: Scanner doing the scan + * scan: Specific scan + * conn: Specific connection in the scan + * + * Return: + * None + */ +static void +libopm_do_readready(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ + int max_read; + char c; + + /* + * If protocol has a specific read function, call that instead of + * reading data from here. + */ + if (conn->protocol->read_function) + { + conn->protocol->read_function(scanner, scan, conn); + return; + } + + max_read = *(int *)libopm_config(scanner->config, OPM_CONFIG_MAX_READ); + + while (1) + { + switch (read(conn->fd, &c, 1)) + { + case 0: + libopm_do_hup(scanner, scan, conn); + return; + + case -1: + if (errno != EAGAIN) + libopm_do_hup(scanner, scan, conn); + return; + + default: + conn->bytes_read++; + + if (conn->bytes_read >= max_read) + { + libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_MAX_READ); + conn->state = OPM_STATE_CLOSED; + return; + } + + if (c == '\0' || c == '\r') + continue; + + if (c == '\n') + { + conn->readbuf[conn->readlen] = '\0'; + conn->readlen = 0; + + libopm_do_read(scanner, scan, conn); + + if (conn->state == OPM_STATE_CLOSED) + return; + + continue; + } + + if (conn->readlen < READBUFLEN) + conn->readbuf[++(conn->readlen) - 1] = c; /* -1 to pad for null term */ + } + } +} + +/* do_read + * + * A line of data has been read from the socket, check it against + * target string. + * + * + * + * Parameters: + * scanner: Scanner doing the scan + * scan: Specific scan + * conn: Specific connection in the scan + * + * Return: + * None + */ +static void +libopm_do_read(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ + OPM_LIST_T *list; + OPM_NODE_T *node; + + /* Check readbuf against target strings */ + list = (OPM_LIST_T *)libopm_config(scanner->config, OPM_CONFIG_TARGET_STRING); + + LIST_FOREACH(node, list->head) + { + const char *target_string = node->data; + + if (strstr(conn->readbuf, target_string)) + { + libopm_do_openproxy(scanner, scan, conn); + break; + } + } +} + +/* do_openproxy + * + * An open proxy was found on connection conn. Cleanup the connection and + * call the appropriate callback to let the client know the proxy was found. + * + * Parameters: + * scanner: Scanner doing the scan + * scan: Specific scan + * conn: Specific connection in the scan + * + * Return: + * None + */ +static void +libopm_do_openproxy(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ + /* Mark the connection for close */ + conn->state = OPM_STATE_CLOSED; + + /* Call client's open proxy callback */ + libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_OPENPROXY, 0); +} + +/* do_writeready + * + * Remote connection is write ready, call the specific protocol + * function for writing to this socket. + * + * Parameters: + * scanner: Scanner doing the scan + * scan: Specific scan + * conn: Specific connection in the scan + * + * Return: + * None + */ +static void +libopm_do_writeready(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ + OPM_PROTOCOL_T *protocol; + +#ifdef HAVE_LIBCRYPTO + if (conn->protocol->use_tls) + { + if (!SSL_is_init_finished(conn->tls_handle)) + { + SSL_connect(conn->tls_handle); + return; + } + } +#endif + + protocol = conn->protocol; + + /* Call write function for specific protocol */ + if (protocol->write_function) + protocol->write_function(scanner, scan, conn); + + /* Flag as NEGSENT so we don't have to send data again*/ + conn->state = OPM_STATE_NEGSENT; +} + +/* do_hup + * + * Connection ended prematurely + * + * Parameters: + * scanner: Scanner doing the scan + * scan: Specific scan + * conn: Specific connection in the scan + * error: OPM_ERR_T containing the error type + * Return: + * None + */ +static void +libopm_do_hup(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ + /* Mark the connection for close */ + conn->state = OPM_STATE_CLOSED; + + libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_NEGFAIL, 0); +} + +/* do_callback + * + * Call callback + * + * Parameters: + * scanner: scanner remote is on + * remote: remote callback is for + * type: callback type + * var: optional var passed back (error codes, etc ) + * Return: + * None + */ +static void +libopm_do_callback(OPM_T *scanner, OPM_REMOTE_T *remote, int type, int var) +{ + /* Callback is out of range */ + if (type < 0 || type >= CBLEN) + return; + + if (scanner->callbacks[type].func) + (scanner->callbacks[type].func)(scanner, remote, var, scanner->callbacks[type].data); +} + +/* setup_remote + * + * Setup an OPM_REMOTE_T with information from an OPM_CONNECTION_T + * for callback + * + * Parameters: + * remote, conn + * + * Return: + * remote + */ +static OPM_REMOTE_T * +libopm_setup_remote(OPM_REMOTE_T *remote, OPM_CONNECTION_T *conn) +{ + remote->port = conn->port; + remote->bytes_read = conn->bytes_read; + remote->protocol = conn->protocol->type; + + return remote; +} diff --git a/src/libopm/src/libopm.h b/src/libopm/src/libopm.h new file mode 100644 index 0000000..ca03512 --- /dev/null +++ b/src/libopm/src/libopm.h @@ -0,0 +1,63 @@ +#ifndef LIBOPM_H +#define LIBOPM_H + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "config.h" +#include "opm_common.h" +#include "opm.h" + +#define CBLEN 5 /* Number of callback functions */ +#define READBUFLEN 128 /* Size of conn->readbuf */ +#define SENDBUFLEN 512 /* Size of sendbuffer in proxy.c */ +#define LIBOPM_TLS_RECORD_SIZE 16384 + +typedef struct _OPM_SCAN OPM_SCAN_T; +typedef struct _OPM_CONNECTION OPM_CONNECTION_T; +typedef struct _OPM_PROTOCOL_CONFIG OPM_PROTOCOL_CONFIG_T; +typedef struct _OPM_PROTOCOL OPM_PROTOCOL_T; + +/* + * Types of hard coded proxy READ/WRITE functions which are + * setup in a table in libopm.c + */ +typedef int OPM_PROXYWRITE_T (OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +typedef int OPM_PROXYREAD_T (OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); + +struct _OPM_SCAN +{ + struct sockaddr_in addr; /* Address in byte order of remote client */ + OPM_REMOTE_T *remote; /* Pointed to the OPM_REMOTE_T for this scan, passed by client */ + OPM_LIST_T connections; /* List of individual connections of this scan (1 for each protocol) */ +}; + +struct _OPM_CONNECTION +{ + OPM_PROTOCOL_T *protocol; /* Pointer to specific protocol this connection handles */ + unsigned short int port; /* Some protocols have multiple ports, eg. HTTP */ + int fd; /* Allocated file descriptor, 0 if not yet allocated */ + unsigned short int bytes_read; /* Bytes read so far in this connection */ + char readbuf[READBUFLEN + 1]; /* 128 byte read buffer, anything over 128 is probably not of use */ + unsigned short int readlen; /* Length of readbuf */ + unsigned short int state; /* State of connection */ + time_t creation; /* When this connection was established */ + void *tls_handle; /* SSL structure created by SSL_new() */ +}; + +struct _OPM_PROTOCOL_CONFIG +{ + OPM_PROTOCOL_T *type; /* Protocol type */ + unsigned short int port; /* Port to connect on */ +}; + +struct _OPM_PROTOCOL +{ + int type; /* Protocol type */ + OPM_PROXYWRITE_T *write_function; /* Write function handler for this protocol */ + OPM_PROXYREAD_T *read_function; /* Read function handler for this protocol */ + int use_tls; /* TLS/SSL-enabled protocol such as HTTPS */ +}; +#endif /* LIBOPM_H */ diff --git a/src/libopm/src/list.c b/src/libopm/src/list.c new file mode 100644 index 0000000..b730b73 --- /dev/null +++ b/src/libopm/src/list.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2002-2003 Erik Fears + * Copyright (c) 2014-2018 ircd-hybrid development team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +/*! \file list.c + * \brief Maintains doubly-linked lists. + * \version $Id$ + */ + +#include "setup.h" + +#include <stdlib.h> +#include <assert.h> + +#include "opm_common.h" +#include "list.h" +#include "memory.h" + + +OPM_NODE_T * +libopm_node_create(void *data) +{ + OPM_NODE_T *node = libopm_calloc(sizeof *node); + + node->data = data; + + return node; +} + +OPM_NODE_T * +libopm_list_add(OPM_LIST_T *list, OPM_NODE_T *node) +{ + node->prev = NULL; + node->next = list->head; + + /* Assumption: If list->tail != NULL, list->head != NULL */ + if (list->head) + list->head->prev = node; + else if (list->tail == NULL) + list->tail = node; + + list->head = node; + list->elements++; + + return node; +} + +OPM_NODE_T * +libopm_list_remove(OPM_LIST_T *list, OPM_NODE_T *node) +{ + /* Assumption: If node->next == NULL, then list->tail == node + * and: If node->prev == NULL, then list->head == node + */ + if (node->next) + node->next->prev = node->prev; + else + { + assert(list->tail == node); + list->tail = node->prev; + } + + if (node->prev) + node->prev->next = node->next; + else + { + assert(list->head == node); + list->head = node->next; + } + + /* Set this to NULL does matter */ + node->next = node->prev = NULL; + list->elements--; + + return node; +} + +void +libopm_node_free(OPM_NODE_T *node) +{ + libopm_free(node); +} diff --git a/src/libopm/src/list.h b/src/libopm/src/list.h new file mode 100644 index 0000000..c18f099 --- /dev/null +++ b/src/libopm/src/list.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2002-2003 Erik Fears + * Copyright (c) 2014-2018 ircd-hybrid development team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +/*! \file list.h + * \brief A header for the list manipulation routines. + * \version $Id$ + */ + +#ifndef LIST_H +#define LIST_H + +#define LIST_FOREACH(pos, head) for (pos = (head); pos != NULL; pos = pos->next) +#define LIST_FOREACH_SAFE(pos, n, head) for (pos = (head), n = pos ? pos->next : NULL; pos != NULL; pos = n, n = pos ? pos->next : NULL) +#define LIST_FOREACH_PREV(pos, head) for (pos = (head); pos != NULL; pos = pos->prev) +#define LIST_SIZE(list) (list)->elements + +extern OPM_NODE_T *libopm_node_create(void *); + +extern OPM_NODE_T *libopm_list_add(OPM_LIST_T *, OPM_NODE_T *); +extern OPM_NODE_T *libopm_list_remove(OPM_LIST_T *, OPM_NODE_T *); + +extern void libopm_node_free(OPM_NODE_T *); +#endif /* LIST_H */ diff --git a/src/libopm/src/memory.c b/src/libopm/src/memory.c new file mode 100644 index 0000000..ec54c6c --- /dev/null +++ b/src/libopm/src/memory.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2002 Erik Fears + * Copyright (c) 2014-2018 ircd-hybrid development team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#include <stdlib.h> +#include <assert.h> +#include <string.h> + +#include "memory.h" + + +/* libopm_calloc + * + * A wrapper function for malloc(), for catching memory issues + * and error handling. + * + * Parameters + * bytes: amount in bytes to allocate + * + * Return: + * Pointer to allocated memory + */ +void * +libopm_calloc(size_t bytes) +{ + void *ret = calloc(1, bytes); + assert(ret); + + return ret; +} + +/* libopm_free + * + * Free memory allocated with xcalloc + * + * Parameters: + * var: pointer to memory to free + * + * Return: + * None + */ +void +libopm_free(void *ptr) +{ + free(ptr); +} + +void * +libopm_strdup(const char *s) +{ + void *ret = malloc(strlen(s) + 1); + + assert(ret); + strcpy(ret, s); + + return ret; +} diff --git a/src/libopm/src/memory.h b/src/libopm/src/memory.h new file mode 100644 index 0000000..24ef445 --- /dev/null +++ b/src/libopm/src/memory.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2002 Erik Fears + * Copyright (c) 2014-2018 ircd-hybrid development team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef MALLOC_H +#define MALLOC_H + +extern void *libopm_calloc(size_t); +extern void libopm_free(void *); +extern void *libopm_strdup(const char *); + +#endif /* MALLOC_H */ diff --git a/src/libopm/src/opm.h b/src/libopm/src/opm.h new file mode 100644 index 0000000..3d98634 --- /dev/null +++ b/src/libopm/src/opm.h @@ -0,0 +1,70 @@ +/** \file opm.h + * \brief Main header for libopm. + * \author Erik Fears + * \version $Id$ + */ + +#ifndef OPM_H +#define OPM_H + +#include "opm_common.h" + +typedef struct _OPM_CONFIG OPM_CONFIG_T; +typedef struct _OPM OPM_T; +typedef struct _OPM_REMOTE OPM_REMOTE_T; +typedef struct _OPM_CALLBACK OPM_CALLBACK_T; + +typedef int OPM_ERR_T; + +typedef void OPM_CALLBACK_FUNC (OPM_T *, OPM_REMOTE_T *, int, void *); + +struct _OPM_CALLBACK +{ + OPM_CALLBACK_FUNC *func; + void *data; +}; + +struct _OPM_CONFIG +{ + void **vars; +}; + +struct _OPM +{ + OPM_CONFIG_T *config; /* Individual scanner configuration */ + OPM_LIST_T queue; /* List of scans in the queue (not yet established) */ + OPM_LIST_T scans; /* List of scans (each scan containing a list of connections) */ + OPM_LIST_T protocols; /* List of protocols this scanner handles */ + unsigned int fd_use; /* Number of file descriptors in use */ + OPM_CALLBACK_T *callbacks; /* Scanner wide callbacks */ +}; + +struct _OPM_REMOTE +{ + char *ip; /* Readable IP address */ + unsigned short int port; /* Port passed back on certain callbacks */ + unsigned short int protocol; /* Protocol passed back on certain callbacks */ + unsigned short int bytes_read; /* Bytes read passed back on certain callbacks */ + OPM_LIST_T protocols; /* Remote specific protocols */ + void *data; /* Arbitrary data that the client can point to for any purpose*/ +}; + +extern OPM_T *opm_create(void); +extern void opm_free(OPM_T *); + +extern OPM_REMOTE_T *opm_remote_create(const char *); +extern void opm_remote_free(OPM_REMOTE_T *); + +extern OPM_ERR_T opm_config(OPM_T *, int, const void *); +extern OPM_ERR_T opm_scan(OPM_T *, OPM_REMOTE_T *); +extern void opm_end(OPM_T *, OPM_REMOTE_T *); +extern void opm_endscan(OPM_T *, OPM_REMOTE_T *); + +extern OPM_ERR_T opm_addtype(OPM_T *, int, unsigned short int); +extern OPM_ERR_T opm_remote_addtype(OPM_REMOTE_T *, int, unsigned short int); +extern OPM_ERR_T opm_callback(OPM_T *, int, OPM_CALLBACK_FUNC *, void *); + +extern void opm_cycle(OPM_T *); + +extern size_t opm_active(OPM_T *); +#endif /* OPM_H */ diff --git a/src/libopm/src/opm_common.h b/src/libopm/src/opm_common.h new file mode 100644 index 0000000..8472331 --- /dev/null +++ b/src/libopm/src/opm_common.h @@ -0,0 +1,21 @@ +#ifndef OPM_COMMON_H +#define OPM_COMMON_H + +typedef struct _libopm_node OPM_NODE_T; +typedef struct _libopm_list OPM_LIST_T; + + +struct _libopm_list +{ + struct _libopm_node *head; + struct _libopm_node *tail; + unsigned int elements; +}; + +struct _libopm_node +{ + struct _libopm_node *next; + struct _libopm_node *prev; + void *data; +}; +#endif /* OPM_COMMON_H */ diff --git a/src/libopm/src/opm_error.h b/src/libopm/src/opm_error.h new file mode 100644 index 0000000..ec55793 --- /dev/null +++ b/src/libopm/src/opm_error.h @@ -0,0 +1,26 @@ +#ifndef LIBOPM_ERROR_H +#define LIBOPM_ERROR_H + +/* Success */ +#define OPM_SUCCESS 1 + +/* Configuration Errors */ +#define OPM_ERR_BADKEY 2 /* Unknown or bad key value */ +#define OPM_ERR_BADVALUE 3 /* Bad value matching key */ +#define OPM_ERR_BADPROTOCOL 4 /* Unknown protocol in config */ + +/* Read Errors */ +#define OPM_ERR_MAX_READ 5 /* Socket reached MAX_READ */ + +/* Callback Registration Errors */ +#define OPM_ERR_CBNOTFOUND 6 /* Callback is out of range */ + +/* opm_scan errors */ +#define OPM_ERR_BADADDR 7 /* IP in remote struct is bad */ +#define OPM_ERR_NOPROTOCOLS 8 /* No protocols to scan! */ + +/* bind/connect errors */ +#define OPM_ERR_BIND 9 /* Error binding to BIND_IP */ +#define OPM_ERR_NOFD 10 /* Unable to allocate file descriptor */ + +#endif /* LIBOPM_ERROR_H */ diff --git a/src/libopm/src/opm_types.h b/src/libopm/src/opm_types.h new file mode 100644 index 0000000..d00994b --- /dev/null +++ b/src/libopm/src/opm_types.h @@ -0,0 +1,49 @@ +#ifndef OPM_TYPES_H +#define OPM_TYPES_H + +/* Configuration Directives */ +#define OPM_CONFIG_FD_LIMIT 0 +#define OPM_CONFIG_BIND_IP 1 +#define OPM_CONFIG_DNSBL_HOST 2 +#define OPM_CONFIG_TARGET_STRING 3 +#define OPM_CONFIG_SCAN_IP 4 +#define OPM_CONFIG_SCAN_PORT 5 +#define OPM_CONFIG_MAX_READ 6 +#define OPM_CONFIG_TIMEOUT 7 + +/* Configuration Variable Types */ +#define OPM_TYPE_INT 1 +#define OPM_TYPE_STRING 2 +#define OPM_TYPE_ADDRESS 3 +#define OPM_TYPE_STRINGLIST 4 + +/* Protocols */ +#define OPM_TYPE_HTTP 1 +#define OPM_TYPE_SOCKS4 2 +#define OPM_TYPE_SOCKS5 3 +#define OPM_TYPE_WINGATE 4 +#define OPM_TYPE_ROUTER 5 +#define OPM_TYPE_HTTPPOST 6 +#define OPM_TYPE_DREAMBOX 7 +#define OPM_TYPE_HTTPS 8 +#define OPM_TYPE_HTTPSPOST 9 +#define OPM_TYPE_SSH 10 + +/* States */ +#define OPM_STATE_UNESTABLISHED 1 +#define OPM_STATE_ESTABLISHED 2 +#define OPM_STATE_NEGSENT 3 +#define OPM_STATE_CLOSED 4 + + +/* + * Callbacks -- If more callback types are added, CBLEN will + * need to be changed in libopm.h accordingly + */ +#define OPM_CALLBACK_OPENPROXY 0 /* An open proxy has been found REMOTE/SCANNER */ +#define OPM_CALLBACK_NEGFAIL 1 /* Negotiation to a proxy has failed REMOTE/SCANNER */ +#define OPM_CALLBACK_END 2 /* A scan has ended REMOTE/SCANNER */ +#define OPM_CALLBACK_ERROR 3 /* An unrecoverable error has occured */ +#define OPM_CALLBACK_TIMEOUT 4 /* Specific scan (protocol) on host has timed out */ + +#endif /* OPM_TYPES_H */ diff --git a/src/libopm/src/proxy.c b/src/libopm/src/proxy.c new file mode 100644 index 0000000..84baadf --- /dev/null +++ b/src/libopm/src/proxy.c @@ -0,0 +1,316 @@ +/* Copyright (C) 2002 Erik Fears + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to + * + * The Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307, USA. + * + * + */ + +#include "setup.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef HAVE_LIBCRYPTO +#include <openssl/ssl.h> +#endif + +#include "config.h" +#include "proxy.h" +#include "opm_common.h" +#include "opm_types.h" +#include "opm_error.h" +#include "libopm.h" + + +static char SENDBUF[SENDBUFLEN + 1]; + +int +libopm_proxy_http_write(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ + size_t len = snprintf(SENDBUF, SENDBUFLEN, "CONNECT %s:%d HTTP/1.0\r\n\r\n", + (char *)libopm_config(scanner->config, OPM_CONFIG_SCAN_IP), + *(int *)libopm_config(scanner->config, OPM_CONFIG_SCAN_PORT)); + + if (send(conn->fd, SENDBUF, len, 0) == -1) + return 0; /* Return error code ? */ + + /* extra linefeed required for MikroTik HttpProxy, must be separate send() */ + send(conn->fd, "\r\n", 2, 0); + + return OPM_SUCCESS; +} + +/* + * CONNECT request byte order for socks4 + * + * +----+----+----+----+----+----+----+----+----+----+....+----+ + * | VN | CD | DSTPORT | DSTIP | USERID |NULL| + * +----+----+----+----+----+----+----+----+----+----+....+----+ + * # of bytes: 1 1 2 4 variable 1 + * + * VN = Version, CD = Command Code (1 is connect request) + */ +int +libopm_proxy_socks4_write(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ + size_t len; + struct in_addr addr; + unsigned long laddr; + int scan_port; + char *scan_ip; + + scan_ip = (char *)libopm_config(scanner->config, OPM_CONFIG_SCAN_IP); + scan_port = *(int *)libopm_config(scanner->config, OPM_CONFIG_SCAN_PORT); + + if (inet_pton(AF_INET, scan_ip, &addr) <= 0) + ; /* handle error */ + + laddr = htonl(addr.s_addr); + + len = snprintf(SENDBUF, SENDBUFLEN, "%c%c%c%c%c%c%c%c%c", 4, 1, + (((unsigned short)scan_port) >> 8) & 0xFF, + (((unsigned short)scan_port) & 0xFF), + (char)(laddr >> 24) & 0xFF, (char)(laddr >> 16) & 0xFF, + (char)(laddr >> 8) & 0xFF, (char)laddr & 0xFF, 0); + + send(conn->fd, SENDBUF, len, 0); + + return OPM_SUCCESS; +} + +/* + * Send version authentication selection message to socks5 + * + * +----+----------+----------+ + * |VER | NMETHODS | METHODS | + * +----+----------+----------+ + * | 1 | 1 | 1 to 255 | + * +----+----------+----------+ + * + * VER always contains 5, for socks version 5 + * Method 0 is 'No authentication required' + * + * + * + * The SOCKS request is formed as follows: + * + * +----+-----+-------+------+----------+----------+ + * |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | + * +----+-----+-------+------+----------+----------+ + * | 1 | 1 | X'00' | 1 | Variable | 2 | + * +----+-----+-------+------+----------+----------+ + * + * + * o VER protocol version: X'05' + * o CMD + * o CONNECT X'01' + * o BIND X'02' + * o UDP ASSOCIATE X'03' + * o RSV RESERVED + * o ATYP address type of following address + * o IP V4 address: X'01' + * o DOMAINNAME: X'03' + * o IP V6 address: X'04' + * o DST.ADDR desired destination address + * o DST.PORT desired destination port in network octet + * order + * + * + */ +int +libopm_proxy_socks5_write(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ + size_t len; + struct in_addr addr; + unsigned long laddr; + int scan_port; + char *scan_ip; + + scan_ip = (char *)libopm_config(scanner->config, OPM_CONFIG_SCAN_IP); + scan_port = *(int *)libopm_config(scanner->config, OPM_CONFIG_SCAN_PORT); + + if (inet_pton(AF_INET, scan_ip, &addr) <= 0) + ; /* handle error */ + + laddr = htonl(addr.s_addr); + + /* Form authentication string */ + /* Version 5, 1 number of methods, 0 method (no auth). */ + len = snprintf(SENDBUF, SENDBUFLEN, "%c%c%c", 5, 1, 0); + send(conn->fd, SENDBUF, len, 0); + + /* Form request string */ + + /* + * Will need to write ipv6 support here in future + * as socks5 is ipv6 compatible + */ + len = snprintf(SENDBUF, SENDBUFLEN, "%c%c%c%c%c%c%c%c%c%c", 5, 1, 0, 1, + (char) (laddr >> 24) & 0xFF, (char) (laddr >> 16) & 0xFF, + (char) (laddr >> 8) & 0xFF, (char) laddr & 0xFF, + (((unsigned short) scan_port) >> 8) & 0xFF, + (((unsigned short) scan_port) & 0xFF)); + + send(conn->fd, SENDBUF, len, 0); + + return OPM_SUCCESS; +} + +/* + * Open wingates require no authentication, they will send a prompt when + * connect. + */ +int +libopm_proxy_wingate_write(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ + size_t len; + int scan_port; + char *scan_ip; + + scan_ip = (char *)libopm_config(scanner->config, OPM_CONFIG_SCAN_IP); + scan_port = *(int *)libopm_config(scanner->config, OPM_CONFIG_SCAN_PORT); + + len = snprintf(SENDBUF, SENDBUFLEN, "%s:%d\r\n", scan_ip, scan_port); + send(conn->fd, SENDBUF, len, 0); + + return OPM_SUCCESS; +} + +/* + * Cisco scanning + * + * Some cisco routers have 'cisco' set as password which allow open telnet + * relay. Attempt to connect using cisco as a password, then give command for + * telnet to the scanip/scanport + */ +int +libopm_proxy_router_write(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ + size_t len; + int scan_port; + char *scan_ip; + + scan_ip = (char *)libopm_config(scanner->config, OPM_CONFIG_SCAN_IP); + scan_port = *(int *)libopm_config(scanner->config, OPM_CONFIG_SCAN_PORT); + + len = snprintf(SENDBUF, SENDBUFLEN, "cisco\r\n"); + send(conn->fd, SENDBUF, len, 0); + + len = snprintf(SENDBUF, SENDBUFLEN, "telnet %s %d\r\n", scan_ip, scan_port); + send(conn->fd, SENDBUF, len, 0); + + return OPM_SUCCESS; +} + +/* + * HTTP POST Scanning + * + */ +int +libopm_proxy_httppost_write(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ + size_t len; + int scan_port; + char *scan_ip; + + scan_ip = (char *)libopm_config(scanner->config, OPM_CONFIG_SCAN_IP); + scan_port = *(int *)libopm_config(scanner->config, OPM_CONFIG_SCAN_PORT); + + len = snprintf(SENDBUF, SENDBUFLEN, + "POST http://%s:%d/ HTTP/1.0\r\n" + "Content-type: text/plain\r\n" + "Content-length: 5\r\n\r\n" + "quit\r\n\r\n", scan_ip, scan_port); + + send(conn->fd, SENDBUF, len, 0); + + return OPM_SUCCESS; +} + +/* + * Dreambox scanning + * + * Some dreambox machines have 'dreambox' as the password, and would allow + * full root access to telnet or install bouncers. + */ +int +libopm_proxy_dreambox_write(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ + size_t len; + int scan_port; + char *scan_ip; + + scan_ip = (char *)libopm_config(scanner->config, OPM_CONFIG_SCAN_IP); + scan_port = *(int *)libopm_config(scanner->config, OPM_CONFIG_SCAN_PORT); + + len = snprintf(SENDBUF, SENDBUFLEN, "root\r\n"); + send(conn->fd, SENDBUF, len, 0); + + len = snprintf(SENDBUF, SENDBUFLEN, "dreambox\r\n"); + send(conn->fd, SENDBUF, len, 0); + + len = snprintf(SENDBUF, SENDBUFLEN, "telnet %s %d\r\n", scan_ip, scan_port); + send(conn->fd, SENDBUF, len, 0); + + len = snprintf(SENDBUF, SENDBUFLEN, "nc %s %d\r\n", scan_ip, scan_port); + send(conn->fd, SENDBUF, len, 0); + + return OPM_SUCCESS; +} + +int +libopm_proxy_https_write(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ +#ifdef HAVE_LIBCRYPTO + size_t len = snprintf(SENDBUF, SENDBUFLEN, "CONNECT %s:%d HTTP/1.0\r\n\r\n", + (char *)libopm_config(scanner->config, OPM_CONFIG_SCAN_IP), + *(int *)libopm_config(scanner->config, OPM_CONFIG_SCAN_PORT)); + + SSL_write(conn->tls_handle, SENDBUF, len); + + /* extra linefeed required for MikroTik HttpProxy, must be separate send() */ + SSL_write(conn->tls_handle, "\r\n", 2); +#endif + return OPM_SUCCESS; +} + +/* + * HTTPS POST Scanning + * + */ +int +libopm_proxy_httpspost_write(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn) +{ +#ifdef HAVE_LIBCRYPTO + size_t len; + int scan_port; + char *scan_ip; + + scan_ip = (char *)libopm_config(scanner->config, OPM_CONFIG_SCAN_IP); + scan_port = *(int *)libopm_config(scanner->config, OPM_CONFIG_SCAN_PORT); + + len = snprintf(SENDBUF, SENDBUFLEN, + "POST http://%s:%d/ HTTP/1.0\r\n" + "Content-type: text/plain\r\n" + "Content-length: 5\r\n\r\n" + "quit\r\n\r\n", scan_ip, scan_port); + + SSL_write(conn->tls_handle, SENDBUF, len); +#endif + return OPM_SUCCESS; +} diff --git a/src/libopm/src/proxy.h b/src/libopm/src/proxy.h new file mode 100644 index 0000000..c006203 --- /dev/null +++ b/src/libopm/src/proxy.h @@ -0,0 +1,15 @@ +#ifndef PROXY_H +#define PROXY_H + +#include "libopm.h" + +extern int libopm_proxy_http_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +extern int libopm_proxy_socks4_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +extern int libopm_proxy_socks5_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +extern int libopm_proxy_wingate_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +extern int libopm_proxy_router_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +extern int libopm_proxy_httppost_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +extern int libopm_proxy_dreambox_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +extern int libopm_proxy_https_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +extern int libopm_proxy_httpspost_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *); +#endif /* PROXY_H */ |
