aboutsummaryrefslogtreecommitdiffstats
path: root/src/libopm
diff options
context:
space:
mode:
Diffstat (limited to 'src/libopm')
-rw-r--r--src/libopm/COPYING339
-rw-r--r--src/libopm/Makefile.am2
-rw-r--r--src/libopm/Makefile.in632
-rw-r--r--src/libopm/src/Makefile.am18
-rw-r--r--src/libopm/src/Makefile.in617
-rw-r--r--src/libopm/src/config.c249
-rw-r--r--src/libopm/src/config.h19
-rw-r--r--src/libopm/src/libopm.c1343
-rw-r--r--src/libopm/src/libopm.h63
-rw-r--r--src/libopm/src/list.c97
-rw-r--r--src/libopm/src/list.h40
-rw-r--r--src/libopm/src/memory.c73
-rw-r--r--src/libopm/src/memory.h28
-rw-r--r--src/libopm/src/opm.h70
-rw-r--r--src/libopm/src/opm_common.h21
-rw-r--r--src/libopm/src/opm_error.h26
-rw-r--r--src/libopm/src/opm_types.h49
-rw-r--r--src/libopm/src/proxy.c316
-rw-r--r--src/libopm/src/proxy.h15
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 */