]> jfr.im git - irc/blitzed-org/libopm.git/commitdiff
The opm perl module!
authordgl <redacted>
Sat, 26 Oct 2002 19:10:06 +0000 (19:10 +0000)
committerdgl <redacted>
Sat, 26 Oct 2002 19:10:06 +0000 (19:10 +0000)
OPM/.cvsignore [new file with mode: 0644]
OPM/Changes [new file with mode: 0644]
OPM/MANIFEST [new file with mode: 0644]
OPM/Makefile.PL [new file with mode: 0644]
OPM/OPM.pm [new file with mode: 0644]
OPM/OPM.xs [new file with mode: 0644]
OPM/README [new file with mode: 0644]
OPM/test.pl [new file with mode: 0644]
OPM/typemap [new file with mode: 0644]

diff --git a/OPM/.cvsignore b/OPM/.cvsignore
new file mode 100644 (file)
index 0000000..7e8b5ae
--- /dev/null
@@ -0,0 +1,24 @@
+*.sw[po]
+Makefile.old
+OPM.c
+blib
+Makefile.aperl
+perlmain.c
+tmon.out
+mon.out
+so_locations
+pm_to_blib
+*.o
+*.a
+perl.exe
+perl
+perl
+OPM.bs
+OPM.bso
+OPM.def
+libOPM.def
+OPM.exp
+OPM.x
+core
+core.*perl.*.?
+*perl.core
diff --git a/OPM/Changes b/OPM/Changes
new file mode 100644 (file)
index 0000000..23f390e
--- /dev/null
@@ -0,0 +1,6 @@
+Revision history for Perl extension OPM.
+
+0.01  Sun Sep 22 01:46:37 2002
+       - original version; created by h2xs 1.21 with options
+               -O -n OPM cvs/libopm/src/opm_types.h cvs/libopm/src/opm_error.h
+
diff --git a/OPM/MANIFEST b/OPM/MANIFEST
new file mode 100644 (file)
index 0000000..1972964
--- /dev/null
@@ -0,0 +1,7 @@
+Changes
+Makefile.PL
+MANIFEST
+OPM.pm
+OPM.xs
+README
+test.pl
diff --git a/OPM/Makefile.PL b/OPM/Makefile.PL
new file mode 100644 (file)
index 0000000..3f61bb2
--- /dev/null
@@ -0,0 +1,17 @@
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+    'NAME'             => 'OPM',
+    'VERSION_FROM'     => 'OPM.pm', # finds $VERSION
+    'PREREQ_PM'                => {}, # e.g., Module::Name => 1.1
+    ($] >= 5.005 ?    ## Add these new keywords supported since 5.005
+      (ABSTRACT_FROM => 'OPM.pm', # retrieve abstract from module
+       AUTHOR     => 'David Leadbeater <dg@blitzed.org>') : ()),
+    'LIBS'             => ['-L../src/.libs -lopm'], # e.g., '-lm'
+    'DEFINE'           => '', # e.g., '-DHAVE_SOMETHING'
+       # Insert -I. if you add *.h files later:
+    'INC'              => '', # e.g., '-I/usr/include/other'
+       # Un-comment this if you add C files to link with later:
+    # 'OBJECT'         => '$(O_FILES)', # link all the C files too
+);
diff --git a/OPM/OPM.pm b/OPM/OPM.pm
new file mode 100644 (file)
index 0000000..bd9ad46
--- /dev/null
@@ -0,0 +1,119 @@
+package OPM;
+
+use 5.005;
+use strict;
+use vars qw/@ISA $VERSION $AUTOLOAD/;
+use Carp;
+
+require Exporter;
+require DynaLoader;
+
+@ISA = qw(Exporter DynaLoader);
+
+$VERSION = '0.01';
+
+sub AUTOLOAD {
+   # This AUTOLOAD is used to 'autoload' constants from the constant()
+   # XS function.  If a constant is not found then control is passed
+   # to the AUTOLOAD in AutoLoader.
+
+   my $constname;
+   ($constname = $AUTOLOAD) =~ s/.*:://;
+   croak "& not defined" if $constname eq 'constant';
+   my $val = constant($constname, 0);
+   if ($! != 0) {
+          croak "Your vendor has not defined OPM macro $constname";
+   }
+
+   {
+      no strict 'refs';
+      # Fixed between 5.005_53 and 5.005_61
+      if ($] >= 5.00561) {
+         *$AUTOLOAD = sub () { $val };
+      }
+      else {
+         *$AUTOLOAD = sub { $val };
+      }
+   }
+   goto &$AUTOLOAD;
+}
+
+bootstrap OPM $VERSION;
+
+# Preloaded methods go here.
+
+sub new {
+   my $package = shift;
+   if(@_) {
+      return _remote_create(@_);
+   }else{
+      my $scan = _create();
+      return $scan unless ref $scan;
+      
+      # It looks bad if we segfault easily, this just means we'll sit in an
+      # infinite loop...
+      $scan->config(OPM->CONFIG_FD_LIMIT, 1024);
+      $scan->config(OPM->CONFIG_MAX_READ, 4096);
+      $scan->config(OPM->CONFIG_TIMEOUT,  10);
+
+      return $scan;
+   }
+}
+
+sub fatal_errors {
+   OPM::_fatal_errors();
+}
+
+package OPM::Scan;
+
+sub config {
+   my($scanner, $type, $var) = @_;
+   if($var =~ /^\d+$/) {
+      $scanner->_config_int($type, $var);
+   }else{
+      $scanner->_config_string($type, $var);
+   }
+}
+
+package OPM::Remote;
+
+sub addr {
+   my $remote = shift;
+   return $remote->ip . ':' . $remote->port;
+}
+
+#package OPM::Error;
+
+1;
+__END__
+
+=head1 NAME
+
+OPM - Perl interface to libopm open proxy scanning library
+
+=head1 SYNOPSIS
+
+  use OPM;
+  OPM->fatal_errors; # croak on errors
+
+  my $scan = OPM->new; # new scanner
+  my $remote = OPM->new("127.0.0.1"); # new remote IP to scan
+  $scan->scan($remote); # Scans it
+
+=head1 DESCRIPTION
+
+Docs not yet done - see test.pl for best example.
+
+=head2 EXPORT
+
+None.
+
+=head1 AUTHOR
+
+David Leadbeater, E<lt>dg@blitzed.orgE<gt>
+
+=head1 SEE ALSO
+
+L<perl>.
+
+=cut
diff --git a/OPM/OPM.xs b/OPM/OPM.xs
new file mode 100644 (file)
index 0000000..0d81682
--- /dev/null
@@ -0,0 +1,326 @@
+/* vim:set ts=8 noexpandtab: */
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include "../src/opm.h"
+#include "../src/opm_types.h"
+#include "../src/opm_error.h"
+
+static bool croak_on_error = 0;
+
+typedef struct _OPM OPM_Scan;
+typedef struct _OPM_REMOTE OPM_Remote;
+typedef int OPM_Error;
+
+/* This is used to store a define -> int mapping */
+typedef struct __defines {
+   char *text;
+   int num;
+} _defines;
+
+/* The mappings (called as OPM::xx hence the lack of OPM_ names) */
+_defines define[] = {
+   {"CALLBACK_END",         OPM_CALLBACK_END},
+   {"CALLBACK_ERROR",       OPM_CALLBACK_ERROR},
+   {"CALLBACK_NEGFAIL",     OPM_CALLBACK_NEGFAIL},
+   {"CALLBACK_OPENPROXY",   OPM_CALLBACK_OPENPROXY},
+   {"CALLBACK_TIMEOUT",     OPM_CALLBACK_TIMEOUT},
+   {"CONFIG_BIND_IP",       OPM_CONFIG_BIND_IP},
+   {"CONFIG_DNSBL_HOST",    OPM_CONFIG_DNSBL_HOST},
+   {"CONFIG_FD_LIMIT",      OPM_CONFIG_FD_LIMIT},
+   {"CONFIG_MAX_READ",      OPM_CONFIG_MAX_READ},
+   {"CONFIG_SCAN_IP",       OPM_CONFIG_SCAN_IP},
+   {"CONFIG_SCAN_PORT",     OPM_CONFIG_SCAN_PORT},
+   {"CONFIG_TARGET_STRING", OPM_CONFIG_TARGET_STRING},
+   {"CONFIG_TIMEOUT",       OPM_CONFIG_TIMEOUT},
+   {"ERR_BADADDR",          OPM_ERR_BADADDR},
+   {"ERR_NOPROTOCOLS",      OPM_ERR_NOPROTOCOLS},
+   {"ERR_BADKEY",           OPM_ERR_BADKEY},
+   {"ERR_BADPROTOCOL",      OPM_ERR_BADPROTOCOL},
+   {"ERR_BADVALUE",         OPM_ERR_BADVALUE},
+   {"ERR_BIND",             OPM_ERR_BIND},
+   {"ERR_CBNOTFOUND",       OPM_ERR_CBNOTFOUND},
+   {"ERR_MAX_READ",         OPM_ERR_MAX_READ},
+   {"ERR_NOFD",             OPM_ERR_NOFD},
+   {"STATE_CLOSED",         OPM_STATE_CLOSED},
+   {"STATE_ESTABLISHED",    OPM_STATE_ESTABLISHED},
+   {"STATE_NEGSENT",        OPM_STATE_NEGSENT},
+   {"STATE_UNESTABLISHED",  OPM_STATE_UNESTABLISHED},
+   {"SUCCESS",              OPM_SUCCESS},
+   {"TYPE_HTTP",            OPM_TYPE_HTTP},
+   {"TYPE_ROUTER",          OPM_TYPE_ROUTER},
+   {"TYPE_SOCKS4",          OPM_TYPE_SOCKS4},
+   {"TYPE_SOCKS5",          OPM_TYPE_SOCKS5},
+   {"TYPE_WINGATE",         OPM_TYPE_WINGATE},
+   {NULL, 0},
+};
+
+static int
+constant(char *name)
+{
+   int i = -1;
+
+   errno = 0;
+   while(define[++i].text != NULL)
+      if(strEQ(name, define[i].text))
+        return define[i].num;
+
+   errno = EINVAL;
+   return 0;
+}
+
+static char
+*string_error(OPM_Error error)
+{
+    switch(error)
+    {
+       case OPM_SUCCESS:
+          return "Success";
+       case OPM_ERR_BADKEY:
+          return "Unknown or bad key value";
+       case OPM_ERR_BADVALUE:
+          return "Bad value matching key";
+       case OPM_ERR_BADPROTOCOL:
+          return "Unknown protocol in config";
+       case OPM_ERR_MAX_READ:
+          return "Socket reached MAX_READ";
+       case OPM_ERR_CBNOTFOUND:
+          return "Callback is out of range";
+       case OPM_ERR_BADADDR:
+          return "IP in remote struct is bad";
+       case OPM_ERR_BIND:
+          return "Error binding to BIND_IP";
+       case OPM_ERR_NOFD:
+          return "Unable to allocate file descriptor";
+       case OPM_ERR_NOPROTOCOLS:
+          return "No protocols are configured";
+   }
+   return "Unknown error";
+}
+
+static void error_check(OPM_Error error)
+{
+   if(croak_on_error)
+      croak("%s", string_error(error));
+
+   return;
+}
+
+static void perl_callback(OPM_Scan *scanner, OPM_Remote *remote, int val,
+     void *func)
+{
+   dSP;
+
+   ENTER;
+   SAVETMPS;
+
+   PUSHMARK(SP);
+   
+   XPUSHs(sv_2mortal(sv_bless(newRV_inc(newSViv((int)scanner)),
+      gv_stashpv("OPM::Scan", 1))));
+   XPUSHs(sv_2mortal(sv_bless(newRV_inc(newSViv((int)remote)),
+      gv_stashpv("OPM::Remote", 1))));
+   XPUSHs(sv_2mortal(newSViv(val)));
+
+   PUTBACK;
+
+   perl_call_sv((SV *) func, G_DISCARD);
+
+   FREETMPS;
+   LEAVE;
+}
+
+MODULE = OPM           PACKAGE = OPM
+
+int
+constant(sv,arg)
+    PREINIT:
+       STRLEN          len;
+    INPUT:
+       SV *            sv
+       char *          s = SvPV(sv, len);
+    CODE:
+       RETVAL = constant(s);
+    OUTPUT:
+       RETVAL
+
+OPM_Scan *
+_create()
+    CODE:
+       RETVAL = opm_create();
+       //printf("Created %p\n", RETVAL);
+    OUTPUT:
+       RETVAL
+
+OPM_Remote *
+_remote_create(sv)
+    PREINIT:
+       STRLEN          len;
+    INPUT:
+       SV *            sv
+       char *          s = SvPV(sv, len);
+    CODE:
+       RETVAL = opm_remote_create(s);
+    OUTPUT:
+       RETVAL
+
+void
+_fatal_errors()
+    CODE:
+       croak_on_error = 1;
+
+MODULE = OPM           PACKAGE = OPM::Scan             PREFIX = opm_
+
+void
+opm_DESTROY(scanner)
+       OPM_Scan *scanner
+  CODE:
+       opm_free(scanner);
+
+OPM_Error
+opm_addtype(scanner, type, port)
+       OPM_Scan *scanner
+       int type
+       int port
+   CODE:
+       RETVAL = opm_addtype(scanner, type, port);
+       if(RETVAL != OPM_SUCCESS)
+          error_check(RETVAL);
+   OUTPUT:
+       RETVAL
+
+OPM_Error
+opm_addcustom(scanner, type, string, port)
+       OPM_Scan *scanner   
+       SV* type
+       SV* string
+       int port
+   PREINIT:
+       STRLEN          typelen;
+       STRLEN          stringlen;
+   INPUT:
+       char *          stype = SvPV(type, typelen);
+       char *          sstring = SvPV(string, stringlen);
+   CODE:
+       RETVAL = opm_addcustom(scanner, stype, sstring, port);
+       if(RETVAL != OPM_SUCCESS)
+          error_check(RETVAL);
+   OUTPUT: 
+       RETVAL
+
+OPM_Error
+opm_scan(scanner, remote)
+       OPM_Scan *scanner
+       OPM_Remote *remote
+   CODE:
+       RETVAL = opm_scan(scanner, remote);
+       if(RETVAL != OPM_SUCCESS)
+          error_check(RETVAL);
+   OUTPUT:
+       RETVAL
+
+OPM_Error
+opm_callback(scanner, type, func)
+       OPM_Scan *scanner
+       int type
+       SV *func
+   CODE:
+       RETVAL = opm_callback(scanner, type, &perl_callback, (void *)newSVsv(func));
+       if(RETVAL != OPM_SUCCESS)
+          error_check(RETVAL);
+   OUTPUT:
+       RETVAL
+
+void
+opm_cycle(scanner)
+       OPM_Scan *scanner
+
+OPM_Error
+opm__config_int(scanner, type, num)
+       OPM_Scan *scanner
+       int type
+       int num
+   CODE:
+       RETVAL = opm_config(scanner, type, &num);
+       if(RETVAL != OPM_SUCCESS)
+          error_check(RETVAL);
+   OUTPUT:
+       RETVAL
+
+OPM_Error
+opm__config_string(scanner, type, sv)
+       OPM_Scan *scanner
+       int type
+       SV *sv
+    PREINIT:
+       STRLEN          len;
+    INPUT:
+       char *          s = SvPV(sv, len);
+    CODE: 
+       RETVAL = opm_config(scanner, type, s);
+       if(RETVAL != OPM_SUCCESS)
+          error_check(RETVAL);
+    OUTPUT:
+       RETVAL
+
+MODULE = OPM           PACKAGE = OPM::Remote           PREFIX = opm_remote_
+
+void
+opm_remote_free(remote)
+       OPM_Remote *remote
+
+OPM_Error
+opm_remote_callback(remote, type, func)
+       OPM_Remote *remote
+       int type
+       SV *func
+    CODE:
+       RETVAL = opm_remote_callback(remote, type, &perl_callback, (void *)func);
+       if(RETVAL != OPM_SUCCESS)
+          error_check(RETVAL);
+    OUTPUT:
+       RETVAL
+
+SV *
+opm_remote_ip(remote)
+       OPM_Remote *remote
+    CODE:
+        RETVAL = newSVpv(remote->ip, 0);
+    OUTPUT:
+       RETVAL
+
+SV *
+opm_remote_port(remote)
+       OPM_Remote *remote
+    CODE:
+        RETVAL = newSViv(remote->port);
+    OUTPUT:
+       RETVAL
+
+SV *
+opm_remote_protocol(remote)
+       OPM_Remote *remote
+    CODE:
+        RETVAL = newSViv(remote->protocol);
+    OUTPUT:
+       RETVAL
+
+SV *
+opm_remote_bytes_read(remote)
+       OPM_Remote *remote
+    CODE:
+        RETVAL = newSViv(remote->bytes_read);
+    OUTPUT:
+       RETVAL
+
+MODULE = OPM           PACKAGE = OPM::Error            PREFIX = opm_error_
+
+SV *
+opm_error_string(error)
+       OPM_Error error
+    CODE:
+        RETVAL = newSVpv(string_error(error), 0);
+    OUTPUT:
+       RETVAL
+
diff --git a/OPM/README b/OPM/README
new file mode 100644 (file)
index 0000000..7d52b9b
--- /dev/null
@@ -0,0 +1,35 @@
+OPM version 0.01
+================
+
+The README is used to introduce the module and provide instructions on
+how to install the module, any machine dependencies it may have (for
+example C compilers and installed libraries) and any other information
+that should be provided before the module is installed.
+
+A README file is required for CPAN modules since CPAN extracts the
+README file from a module distribution so that people browsing the
+archive can use it get an idea of the modules uses. It is usually a
+good idea to provide version information here so that people can
+decide whether fixes for the module are worth downloading.
+
+INSTALLATION
+
+To install this module type the following:
+
+   perl Makefile.PL
+   make
+   make test
+   make install
+
+DEPENDENCIES
+
+This module requires these other modules and libraries:
+
+  blah blah blah
+
+COPYRIGHT AND LICENCE
+
+Put the correct copyright and licence information here.
+
+Copyright (C) 2002 A. U. Thor blah blah blah
+
diff --git a/OPM/test.pl b/OPM/test.pl
new file mode 100644 (file)
index 0000000..0066959
--- /dev/null
@@ -0,0 +1,93 @@
+# Before `make install' is performed this script should be runnable with
+# `make test'. After `make install' it should work as `perl test.pl'
+
+#########################
+
+# change 'tests => 1' to 'tests => last_test_to_print';
+$^W = 1;
+
+use strict;
+use Test;
+BEGIN { 
+   $ENV{LD_LIBRARY_PATH} = "../src/.libs"; # you didn't see this hack right?
+   plan tests => 9;
+};
+
+use OPM; 
+
+ok(1);
+
+OPM->fatal_errors;
+my $scan = new OPM or die "loading OPM";
+
+ok(2);
+
+$scan->addtype(OPM->TYPE_HTTP, 80);
+$scan->addtype(OPM->TYPE_HTTP, 3128);
+$scan->addtype(OPM->TYPE_HTTP, 8080);
+$scan->addtype(OPM->TYPE_SOCKS4, 1080);
+$scan->addtype(OPM->TYPE_SOCKS5, 1080);
+
+$scan->addcustom("HTTP", "CONNECT %i:%p HTTP/1.0\r\n\r\n", 80);
+
+$scan->config(OPM->CONFIG_SCAN_IP, "203.56.139.100");
+$scan->config(OPM->CONFIG_SCAN_PORT, 6667);
+$scan->config(OPM->CONFIG_TARGET_STRING, "*** Looking up your hostname...");
+
+ok(3);
+
+$scan->callback(OPM->CALLBACK_END, sub {
+      my($scan, $remote, $val) = @_;
+      print "end callback " . $remote->ip . "\n";
+      $remote->free;
+
+      ok(7);
+   } );
+$scan->callback(OPM->CALLBACK_OPENPROXY, sub {
+      my($scan, $remote, $val) = @_;
+      print "openproxy callback: " . $remote->addr . "\n";
+   } );
+$scan->callback(OPM->CALLBACK_NEGFAIL, sub {
+      my($scan, $remote, $val) = @_;
+      print "negfail callback " . $remote->addr . "\n";
+   } );
+$scan->callback(OPM->CALLBACK_TIMEOUT, sub {
+      my($scan, $remote, $val) = @_;
+      print "timeout callback " . $remote->addr . "\n";
+   } );
+$scan->callback(OPM->CALLBACK_ERROR, sub {
+      my($scan, $remote, $val) = @_;
+      print "error callback " . $remote->addr . "\n";
+   } );
+
+ok(4);
+
+unless(exists $ENV{OPEN_PROXY}) {
+   print "The rest of the tests require a valid open proxy; run\n";
+   print "OPEN_PROXY=\"127.0.0.1\" make test\n";
+   print "Where 127.0.0.1 is an open proxy\n";
+   exit;
+}
+
+my $remote1 = OPM->new($ENV{OPEN_PROXY});
+my $remote2 = OPM->new("127.0.0.1");
+
+ok(5) if ref $remote1 and ref $remote2;
+
+$scan->scan($remote1);
+$scan->scan($remote2);
+
+ok(6);
+
+print "Wait..\n";
+$scan->cycle;
+sleep 1;
+$scan->cycle;
+sleep 1;
+$scan->cycle;
+
+ok(8);
+$scan = undef;
+
+ok(9);
+
diff --git a/OPM/typemap b/OPM/typemap
new file mode 100644 (file)
index 0000000..304e493
--- /dev/null
@@ -0,0 +1,18 @@
+TYPEMAP
+OPM_Scan *     T_PTROBJ_SPECIAL
+OPM_Remote *   T_PTROBJ_SPECIAL
+OPM_Error      T_PTROBJ_SPECIAL
+
+INPUT
+T_PTROBJ_SPECIAL
+   if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/_/::/g;$ntt=~s/Ptr$//;\$ntt}\")) {
+      IV tmp = SvIV((SV*)SvRV($arg));
+      $var = ($type) tmp;
+   } else {
+      croak(\"$var is not of type ${(my $ntt=$ntype)=~s/_/::/g;$ntt=~s/Ptr$//;\$ntt}\");
+   }
+
+OUTPUT
+T_PTROBJ_SPECIAL
+   sv_setref_pv($arg, \"${(my $ntt=$ntype)=~s/_/::/g;$ntt=~s/Ptr$//;\$ntt}\", (void*)$var);
+