]> source.dussan.org Git - rspamd.git/commitdiff
* Perl fixes:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 16 Nov 2009 15:43:30 +0000 (18:43 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 16 Nov 2009 15:43:30 +0000 (18:43 +0300)
 - remove XS API, it seems that I would never support it
 - use sys(write|read) for IO in Mail::Rspamd::Client
 - add proper installation process for Mail::Rspamd::Client
 - remove some other legacy

--HG--
rename : perl/Client.pm => perl/lib/Mail/Rspamd/Client.pm

17 files changed:
CMakeLists.txt
perl/Client.pm [deleted file]
perl/MANIFEST [new file with mode: 0644]
perl/Makefile.PL.in
perl/Rspamd.pod [deleted file]
perl/Rspamd.xs [deleted file]
perl/Rspamd/Config.xs [deleted file]
perl/Rspamd/ContentType.xs [deleted file]
perl/Rspamd/Hash.xs [deleted file]
perl/Rspamd/InternetAddress.xs [deleted file]
perl/Rspamd/Message.xs [deleted file]
perl/Rspamd/Object.xs [deleted file]
perl/Rspamd/Part.xs [deleted file]
perl/Rspamd/Task.xs [deleted file]
perl/Rspamd/TextPart.xs [deleted file]
perl/lib/Mail/Rspamd/Client.pm [new file with mode: 0644]
perl/typemap [deleted file]

index 8c58586d0f532bb216f73aaf7e8cd120824bd511..0803b0ad9b5aeb6b4ffee80189cfb503a7a6b0fb 100644 (file)
@@ -37,11 +37,10 @@ INCLUDE(CheckCSourceCompiles)
 INCLUDE(CheckLibraryExists)
 INCLUDE(FindPkgConfig)
 INCLUDE(CheckCCompilerFlag)
+INCLUDE(FindPerl)
 
 IF(ENABLE_PERL MATCHES "ON")
 
-       INCLUDE(FindPerl)
-
        IF(NOT PERL_EXECUTABLE)
                MESSAGE(FATAL_ERROR "Error: Perl is not found but is required")
        ENDIF(NOT PERL_EXECUTABLE)
@@ -449,16 +448,18 @@ ADD_CUSTOM_COMMAND(OUTPUT src/modules.c
                                        COMMAND ../utils/gen-modules.sh ${PLUGINSSRC}
                                        WORKING_DIRECTORY src)
 
-IF(ENABLE_PERL MATCHES "ON")
+IF(PERL_EXECUTABLE)
        ADD_CUSTOM_COMMAND(OUTPUT perl/Makefile 
                                                COMMAND ${PERL_EXECUTABLE} ./Makefile.PL
                                                WORKING_DIRECTORY perl)
+       CONFIGURE_FILE(perl/Makefile.PL.in perl/Makefile.PL)
+ENDIF(PERL_EXECUTABLE)
+IF(ENABLE_PERL MATCHES "ON")
        ADD_CUSTOM_TARGET(perlxs
                                                COMMAND make
                                                DEPENDS perl/Makefile
                                                WORKING_DIRECTORY perl
                                                VERBATIM)
-       CONFIGURE_FILE(perl/Makefile.PL.in perl/Makefile.PL)
 ENDIF(ENABLE_PERL MATCHES "ON")
 
 CONFIGURE_FILE(config.h.in src/config.h)
@@ -535,7 +536,9 @@ TARGET_LINK_LIBRARIES(utils/expression-parser ${GMIME2_LIBRARIES})
 
 # Binaries
 INSTALL(PROGRAMS rspamd-${RSPAMD_VERSION} DESTINATION bin RENAME rspamd)
-INSTALL(PROGRAMS rspamc.pl DESTINATION bin RENAME rspamc)
+IF(PERL_EXECUTABLE)
+       INSTALL(PROGRAMS rspamc.pl DESTINATION bin RENAME rspamc)
+ENDIF(PERL_EXECUTABLE)
 
 
 # Configs
@@ -580,14 +583,16 @@ IF(ENABLE_LUA MATCHES "ON")
 ENDIF(ENABLE_LUA MATCHES "ON")
 
 # Perl lib
-IF(ENABLE_PERL MATCHES "ON")
+IF(PERL_EXECUTABLE)
+       INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${PERL_EXECUTABLE} ./Makefile.PL WORKING_DIRECTORY perl)")
+       INSTALL(CODE "EXECUTE_PROCESS(COMMAND make WORKING_DIRECTORY perl)")
        INSTALL(CODE "EXECUTE_PROCESS(COMMAND make install WORKING_DIRECTORY perl)")
-ENDIF(ENABLE_PERL MATCHES "ON")
+ENDIF(PERL_EXECUTABLE)
 
 # Redirector
-IF(ENABLE_REDIRECTOR MATCHES "ON")
+IF(ENABLE_REDIRECTOR MATCHES "ON" AND PERL_EXECUTABLE)
        INSTALL(PROGRAMS utils/redirector.pl DESTINATION bin RENAME rspamd-redirector)
-ENDIF(ENABLE_REDIRECTOR MATCHES "ON")
+ENDIF(ENABLE_REDIRECTOR MATCHES "ON" AND PERL_EXECUTABLE)
 
 # Start scripts
 IF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
diff --git a/perl/Client.pm b/perl/Client.pm
deleted file mode 100644 (file)
index c0585e2..0000000
+++ /dev/null
@@ -1,467 +0,0 @@
-
-=head1 NAME
-
-Mail::Rspamd::Client - Client for rspamd Protocol
-
-
-=head1 SYNOPSIS
-
-  my $client = new Mail::Rspamd::Client({port => 11333,
-                                               host => 'localhost',
-                                               ip => '127.0.0.1'});
-
-  if ($client->ping()) {
-    print "Ping is ok\n";
-  }
-
-  my $result = $client->check($testmsg);
-
-  if ($result->{'default'}->{isspam} eq 'True') {
-    do something with spam message here
-  }
-
-=head1 DESCRIPTION
-
-Mail::Rspamd::Client is a module that provides a perl implementation for
-the spamd protocol.
-
-=cut
-
-package Mail::Rspamd::Client;
-
-use IO::Socket;
-use IO::Select;
-
-my $EOL = "\015\012";
-my $BLANK = $EOL x 2;
-my $PROTOVERSION = 'RSPAMC/1.0';
-
-=head1 PUBLIC METHODS
-
-=head2 new
-
-public class (Mail::Rspamd::Client) new (\% $args)
-
-Description:
-This method creates a new Mail::Rspamd::Client object.
-
-=cut
-
-sub new {
-  my ($class, $args) = @_;
-
-  $class = ref($class) || $class;
-
-  my $self = {};
-
-  # with a sockets_path set then it makes no sense to set host and port
-  if ($args->{socketpath}) {
-    $self->{socketpath} = $args->{socketpath};
-  }
-  else {
-    $self->{hosts} = $args->{hosts};
-    $self->{alive_hosts} = $self->{hosts};
-  }
-
-  if ($args->{username}) {
-    $self->{username} = $args->{username};
-  }
-  if ($args->{ip}) {
-    $self->{ip} = $args->{ip};
-  }
-  if ($args->{from}) {
-    $self->{from} = $args->{from};
-  }
-  if ($args->{subject}) {
-    $self->{subject} = $args->{subject};
-  }
-  if ($args->{rcpt}) {
-    $self->{rcpt} = $args->{rcpt};
-  }
-  if ($args->{timeout}) {
-    $self->{timeout} = $args->{timeout};
-  }
-  else {
-    $self->{timeout} = 5;
-  }
-  if ($args->{password}) {
-    $self->{password} = $args->{password};
-  }
-
-  bless($self, $class);
-
-  $self;
-}
-
-=head2 check
-
-public instance (\%) check (String $msg)
-
-Description:
-This method makes a call to the spamd server and depending on the value of
-C<$is_check_p> either calls PROCESS or CHECK.
-
-The return value is a hash reference containing metrics indexed by name. Each metric
-is hash that contains data:
-
-isspam
-
-score
-
-threshold
-
-symbols - array of symbols
-
-=cut
-
-sub check {
-  my ($self, $msg) = @_;
-
-  my %metrics;
-
-  my $command = 'SYMBOLS';
-
-  $self->_clear_errors();
-
-  my $remote = $self->_create_connection();
-
-  return 0 unless ($remote);
-
-  my $msgsize = length($msg.$EOL);
-
-  local $SIG{PIPE} = 'IGNORE';
-
-  if (!(print $remote "$command $PROTOVERSION$EOL")) {
-    $self->_mark_dead($remote);
-    return 0;
-  }
-  print $remote "Content-length: $msgsize$EOL";
-  print $remote "User: $self->{username}$EOL" if ($self->{username});
-  print $remote "From: $self->{from}$EOL" if ($self->{from});
-  print $remote "IP: $self->{ip}$EOL" if ($self->{ip});
-  print $remote "Subject: $self->{subject}$EOL" if ($self->{subject});
-  if (ref $self->{rcpt} eq "ARRAY") {
-    foreach ($self->{rcpt}) {
-      print $remote "Rcpt: $_ $EOL";
-    }
-  }
-  print $remote "$EOL";
-  print $remote $msg;
-  print $remote "$EOL";
-  
-  return undef unless $self->_get_io_readiness($remote, 0);
-
-  my $line = <$remote>;
-  return undef unless (defined $line);
-
-  my ($version, $resp_code, $resp_msg) = $self->_parse_response_line($line);
-
-  $self->{resp_code} = $resp_code;
-  $self->{resp_msg} = $resp_msg;
-
-  return undef unless ($resp_code == 0);
-
-  my $cur_metric;
-
-  while ($self->_get_io_readiness($remote, 0) && ($line = <$remote>)) {
-    if ($line =~ m!Metric: (\S+); (\S+); (\S+) / (\S+)!) {
-      $metrics{$1} = {
-        isspam => $2,
-        score => $3 + 0,
-        threshold => $4 + 0,
-        symbols => [],
-      };
-      $cur_metric = $1;
-    }
-    elsif ($line =~ /^Symbol: (\S+)/ && $cur_metric) {
-      my $symref = $metrics{$cur_metric}->{'symbols'};
-      push(@$symref, $1);
-    }
-    elsif ($line =~ /^${EOL}$/) {
-      last;
-    }
-  }
-
-  close $remote;
-
-  return \%metrics;
-}
-
-sub _auth {
-  my ($self, $sock) = @_;
-
-  local $SIG{PIPE} = 'IGNORE';
-
-  if (!(print $sock "PASSWORD $self->{password}$EOL")) {
-    $self->_mark_dead($remote);
-    return 0;
-  }
-
-  return 0 unless $self->_get_io_readiness($sock, 0);
-
-  if (defined (my $reply = <$sock>)) {
-    my $end = <$sock>;
-    if ($reply =~ /^password accepted/) {
-      return 1;
-    }
-  }
-
-  return 0;
-  
-}
-
-=head2 learn
-
-public instance (\%) check (String $msg, String $statfile, Boolean in_class)
-
-Description:
-This method makes a call to the spamd learning a statfile with message.
-
-=cut
-
-sub learn {
-  my ($self, $msg, $statfile, $in_class) = @_;
-
-  my %metrics;
-
-  my $command = 'LEARN';
-
-  $self->_clear_errors();
-
-  my $remote = $self->_create_connection();
-
-  return 0 unless ($remote);
-
-  return 0 unless $self->_auth($remote);
-
-  my $msgsize = length($msg.$EOL);
-
-  local $SIG{PIPE} = 'IGNORE';
-
-  if (!(print $remote "$command $statfile $msgsize$EOL")) {
-    $self->_mark_dead($remote);
-    return 0;
-  }
-
-  print $remote $msg;
-  print $remote "$EOL";
-  
-  return undef unless $self->_get_io_readiness($remote, 0);
-  if (defined (my $reply = <$sock>)) {
-    if ($reply =~ /^learn ok/) {
-      close $remote;
-      return 1;
-    }
-  }
-
-  close $remote;
-  return 0;
-}
-
-=head2 ping
-
-public instance (Boolean) ping ()
-
-Description:
-This method performs a server ping and returns 0 or 1 depending on
-if the server responded correctly.
-
-=cut
-
-sub ping {
-  my ($self) = @_;
-
-  my $remote = $self->_create_connection();
-
-  return 0 unless ($remote);
-  local $SIG{PIPE} = 'IGNORE';
-
-  if (!(print $remote "PING $PROTOVERSION$EOL")) {
-    $self->_mark_dead($remote);
-    return 0;
-  }
-  print $remote "$EOL";
-
-  return undef unless $self->_get_io_readiness($remote, 0);
-  my $line = <$remote>;
-  close $remote;
-  return undef unless (defined $line);
-
-  my ($version, $resp_code, $resp_msg) = $self->_parse_response_line($line);
-  return 0 unless ($resp_msg eq 'PONG');
-
-  return 1;
-}
-
-=head1 PRIVATE METHODS
-
-=head2 _create_connection
-
-private instance (IO::Socket) _create_connection ()
-
-Description:
-This method sets up a proper IO::Socket connection based on the arguments
-used when greating the client object.
-
-On failure, it sets an internal error code and returns undef.
-
-=cut
-
-sub _create_connection {
-  my ($self) = @_;
-
-  my $remote;
-  my $tries = 0;
-
-  if ($self->{socketpath}) {
-    $remote = IO::Socket::UNIX->new( Peer => $self->{socketpath},
-                                    Type => SOCK_STREAM,
-             Blocking  => 0,
-                                  );
-    # Get write readiness
-    if ($self->_get_io_readiness($remote, 1) == 0) {
-      print "Connection timed out: $!\n";
-      return undef;
-    }
-  }
-  else {
-    my $server;
-
-    do {
-      $server = $self->_select_server();
-      $tries ++;
-
-      $remote = IO::Socket::INET->new( Proto     => "tcp",
-                PeerAddr  => $server->{host},
-                PeerPort  => $server->{port},
-                Blocking  => 0,
-              );
-      # Get write readiness
-      if ($self->_get_io_readiness($remote, 1) != 0) {
-        return $remote;
-      }
-      else {
-        next;
-      }
-    } while ($tries < 5);
-
-    return undef unless $server;
-  }
-  unless ($remote) {
-    print "Failed to create connection to spamd daemon: $!\n";
-    return undef;
-  }
-  $remote;
-}
-
-sub _revive_dead {
-  my ($self) = @_;
-
-  my $now = time();
-  foreach my $s ($self->{dead_hosts}) {
-    # revive after minute of downtime
-    if (defined($s->{dead}) && $s->{dead} == 1 && $now - $s->{t} > 60) {
-      $s->{dead} = 0;
-      push(@{$self->{alive_hosts}}, $s->{host});
-    }
-  }
-
-  1;
-}
-
-sub _select_server {
-  my($self) = @_;
-    
-  $self->_revive_dead();
-  my $alive_num = scalar(@{$self->{alive_hosts}});
-  if (!$alive_num) {
-    $self->{alive_hosts} = $self->{hosts};
-    $self->{dead_hosts} = ();
-    $alive_num = scalar($self->{alive_hosts});
-  }
-  
-  my $selected = $self->{alive_hosts}[int(rand($alive_num))];
-  if ($selected =~ /^(\S+):(\d+)$/) {
-    my $server = {
-        host => $1,
-        port => $2,
-    };
-    return $server;
-  }
-
-  undef;
-}
-
-
-sub _mark_dead {
-  my ($self, $server) = @_;
-  
-  my $now = time();
-  $self->{dead_hosts}->{$server} = {
-    host => $server,
-    dead => 1,
-    t => $now,
-  };
-  for (my $i = 0; $i < scalar (@{$self->{alive_hosts}}); $i ++) {
-    if ($self->{alive_hosts} == $server) {
-      splice(@{$self->{alive_hosts}}, $i, 1);
-      last;
-    }
-  }
-}
-
-sub _get_io_readiness {
-  my ($self, $sock, $is_write) = @_;
-  my $s = IO::Select->new();
-  $s->add($sock);
-
-  if ($is_write) {
-    @ready = $s->can_write($self->{timeout});
-  }
-  else {
-    @ready = $s->can_read($self->{timeout});
-  }
-  
-
-  scalar(@ready);
-}
-
-=head2 _parse_response_line
-
-private instance (@) _parse_response_line (String $line)
-
-Description:
-This method parses the initial response line/header from the server
-and returns its parts.
-
-We have this as a seperate method in case we ever decide to get fancy
-with the response line.
-
-=cut
-
-sub _parse_response_line {
-  my ($self, $line) = @_;
-
-  $line =~ s/\r?\n$//;
-  return split(/\s+/, $line, 3);
-}
-
-=head2 _clear_errors
-
-private instance () _clear_errors ()
-
-Description:
-This method clears out any current errors.
-
-=cut
-
-sub _clear_errors {
-  my ($self) = @_;
-
-  $self->{resp_code} = undef;
-  $self->{resp_msg} = undef;
-}
-
-1;
-
-
diff --git a/perl/MANIFEST b/perl/MANIFEST
new file mode 100644 (file)
index 0000000..49ff809
--- /dev/null
@@ -0,0 +1,3 @@
+Makefile.PL
+MANIFEST
+lib/Mail/Rspamd/Client.pm
index 10ca63e1663e07805996e50f19544ff35e811fc4..31aca8f856a69a63f29dee4bc6a7ca26d6c9a885 100644 (file)
@@ -1,22 +1,6 @@
 use ExtUtils::MakeMaker;
 WriteMakefile(
-    NAME         => 'Mail::Rspamd',
     AUTHOR       => 'Vsevolod Stakhov <vsevolod@highsecure.ru>',
-    XS           => { 'Rspamd.xs'  => 'Rspamd.c' },
-    VERSION_FROM => 'Rspamd.pm', # finds $VERSION
-    LIBS         => ['${GLIB_LDFLAGS} ${GMIME_LDFLAGS} -levent'],   # e.g., '-lm'
-    DEFINE       => '',
-    INC          => '${GLIB_CFLAGS} ${GMIME_CFLAGS}',
-    PM              => { 'Rspamd.pod' => '$(INST_LIBDIR)/Rspamd.pod',
-                     'Rspamd.pm' => '$(INST_LIBDIR)/Rspamd.pm'},
-    depend       => {
-           'Rspamd.so'  => 'Rspamd.o',
-           'Rspamd.o'   => 'Rspamd.c',
-           'Rspamd.c'   => qw{
-Rspamd/ContentType.xs            Rspamd/Part.xs                   Rspamd/Hash.xs
-Rspamd/InternetAddress.xs        Rspamd/Message.xs                Rspamd/Object.xs
-Rspamd/TextPart.xs
-},
-       },
+    VERSION_FROM => 'lib/Mail/Rspamd/Client.pm', # finds $VERSION
 );
 
diff --git a/perl/Rspamd.pod b/perl/Rspamd.pod
deleted file mode 100644 (file)
index 2af9b49..0000000
+++ /dev/null
@@ -1,600 +0,0 @@
-=head1 NAME
-
-Mail::Rspamd - Interface for accessing rspamd internals
-
-=head1 SYNOPSIS
-
-  use Mail::Rspamd;
-    
-  sub mime_filter {
-      my ($task) = @_;
-      my $msg = $task->get_message();
-      $msg->set_subject ( 'Re: ' . $msg->get_subject () );
-      if ($msg->get_mime_part->get_content_type->to_string =~ /text/) {
-          # Do something
-      }
-      my %header;
-      tie %header, 'Mail::Rspamd::Hash::Header', $msg;
-      
-      $header{'From'} = 'John Doe <john@domain>';
-      $header{'X-Info'} = 'Normal one arbitrary header';
-      $header{'X-Info'} = ['This is','Multiline X-Info header'];
-      
-      my $old_header = $header{'X-Info'};
-      $header{'X-Info'} = [ 'First header', @{$old_header}, 'Last header'];
-  }
-
-
-=head1 DESCRIPTION
-
-Mail::Rspamd is a perl module for accessing internal structures of rspamd, such as
-task, message, config, logger e.t.c. Module is based on ideas from MIME::Fast.
-
-=head1 INHERITANCE
-
-This is a reformatted snipped from the official GMime documentation:
-
-  Not a real objects:
-
-  Mail::Rspamd::ContentType
-  Mail::Rspamd::Disposition
-  Mail::Rspamd::Header
-  Mail::Rspamd::Param
-  Mail::Rspamd::Hash::Header    (only in perl module)
-
-  Glib objects:
-
-  Mail::Rspamd::Object
-    Mail::Rspamd::Message
-    Mail::Rspamd::Part
-  InternetAddress
-
-=head1 PUBLIC CLASSES
-
-=head2 Mail::Rspamd::Message
-
-=over 4
-
-=item I<new>()
-
-=item I<new>(pretty_headers)
-
-Class method. Create a new Mail::Rspamd::Message object.
-Such object have no headers or any mime parts.
-If you need to parse any message data use construct_message()
-method from the Mail::Rspamd::Parser submodule.
-Optional parameter I<pretty_headers> (default 0) if set to 1,
-initializes friendly order of the header items.
-The object is destroyed during the perl garbage collection.
-E.g.:
-
-    my $msg = new Mail::Rspamd::Message;
-
-=item I<set_sender>(address)
-
-=item I<get_sender>()
-
-Set and get the sender's name and address on the Mail::Rspamd::Message object.
-E.g.
-
-    $msg->set_sender("\"Joe Sixpack\" <joe\@sixpack.org>");
-    $sender = $msg->get_sender;
-
-=item I<set_reply_to>(address)
-
-=item I<get_reply_to>(address)
-
-Set and get the sender's Reply-To address of the MIME message.
-
-=item I<add_recipient>(type, name, email)
-
-Add a recipient of a chosen type to the MIME Message.
-Available recipient types include: GMIME_RECIPIENT_TYPE_TO,
-GMIME_RECIPIENT_TYPE_CC and GMIME_RECIPIENT_TYPE_BCC.
-
-=item I<add_recipients_from_string>(type, string)
-
-Add recipients of a chosen type to the MIME Message.
-E.g.:
-
-    $msg->add_recipients_from_string(GMIME_RECIPIENT_TYPE_TO,
-        "\"Mickey Mouse\" <mickey\@example>," .
-        "\"John Doe\" <john\@home>");
-
-=item I<get_recipients>(type)
-
-Returns a list of recipients of a chosen type from the MIME Message.
-The I<type> parameter is the same as in the add_recipient() method.
-
-=item I<set_subject>(subject)
-
-=item I<get_subject>()
-
-Set and get the subject of the MIME message.
-
-=item I<set_date>(date, gmt_offset)
-
-=item I<set_date_from_string>(str)
-
-Set the sent-date on the MIME message. You can give a date string
-or the numbers (time in seconds and offset in hours and minutes).
-E.g.
-
-    $msg->set_date(991697409, '+0100');
-    $msg->set_date("Wed, 7 Mar 2001 03:00:01 +0100 (CET)");
-
-=item I<get_date>()
-
-Get the sent-date of the MIME message. In scalar
-context returns date as a string value,
-otherwise two element array - time in seconds and gmt_offset.
-
-=item I<set_message_id>(message_id)
-
-=item I<get_message_id>()
-
-Set and get the Message-Id of the message.
-
-=item I<set_header>(field, value)
-
-Set a message header to the MIME Message. This can be
-such headers as X-Mailer, X-Priority, or In-Reply-To
-as well as From etc. If you want to delete
-any header - use remove_header() method.
-
-=item I<add_header>(field, value)
-
-Add a header to the message header.
-
-=item I<remove_header>(field)
-
-Removes the given field from the message header.
-
-=item I<get_header>(field)
-
-Get the header from the MIME message. This is the only (besides the
-tied header hash) way you can retrieve any arbitrary header
-(as X-Mailer etc.). Other headers can be accessed also with e.g.
-get_sender (From header), get_content_type (Mail::Rspamd::Part method), etc.
-
-=item I<set_mime_part>(mime_part)
-
-=item I<get_mime_part>()
-
-Set and get the root-level MIME part of the message.
-Parameter mime_part should be valid Mail::Rspamd::Object object.
-
-B<NOTE>: get_mime_part() does not exists in C gmime library.
-
-=item I<get_body>(want_plain = 1, is_html = 0)
-
-Returns the body of the message. Parameters are optional.
-If want_plain is 1 (default)  plain text is returned.
-If HTML is in the return string, is_html is set to 1.
-Binary parts are omitted.
-
-=item I<get_headers>()
-
-Returns an allocated string containing the raw message headers.
-
-=item I<foreach_part>(function, data)
-
-Calls callback on each of the mime parts in the mime message.
-Parameters: function is the reference to the callback function,
-and data is a scalar (or any reference) that would be passed
-to each callback function call.
-E.g.:
-
-    $msg->foreach_part(\&parse,$data);
-
-=back
-
-=head2 Mail::Rspamd::Header
-
-=over 4
-
-=item *
-
-Mail::Rspamd::Header is a private structure. This structure contains
-all the headers except special ones (Content-* MIME-Version).
-Look for Header tied hash for easy maintaining for header.
-Use also the Mail::Rspamd::Message::get_header() and set_header() methods.
-
-=back
-
-=head2 Mail::Rspamd::Part
-
-=over 4
-
-=item I<new> ()
-
-=item I<new> (type = "text", subtype = "plain")
-
-Class method. Create a new Mail::Rspamd::Part object (MIME part).
-It supports a few special headers (Content-* and MIME-Version),
-and has contents of specified type.
-If you do not issue any parameter to the new function,
-"text/plain" would be the default type for the new Mail::Rspamd::Part object.
-
-
-=item I<set_content_header> ($header)
-
-=item I<get_content_header> ()
-
-Sets or gets an arbitrary MIME content header.
-
-=item I<set_content_description> (description)
-
-=item I<get_content_description> ()
-
-Set and get content description (Content-Description) on the MIME part.
-
-=item I<set_content_md5> (content_md5)
-
-=item I<verify_content_md5> ()
-
-=item I<get_content_md5> ()
-
-Set, get and verify content MD5 hash (Content-MD5) on the MIME part contents.
-
-=item I<set_content_location> (location)
-
-=item I<get_content_location> ()
-
-Set and get content location (Content-Location) on the MIME part.
-
-=item I<set_encoding> (encoding)
-
-=item I<encoding_from_string> (encoding_string)
-
-=item I<get_encoding> ()
-
-=item I<encoding_to_string> ()
-
-Set and get encoding on the MIME part. Encoding could be one of these
-constants (or strings):
-
-    GMIME_PART_ENCODING_DEFAULT # string '8 bit'
-    GMIME_PART_ENCODING_7BIT # string '7 bit'
-    GMIME_PART_ENCODING_8BIT # '8 bit'
-    GMIME_PART_ENCODING_BASE64 # 'base64'
-    GMIME_PART_ENCODING_QUOTEDPRINTABLE # 'quoted-printable'
-
-E.g.
-    Mail::Rspamd::Part::encoding_to_string("GMIME_PART_ENCODING_BASE64");
-
-=item I<set_content_disposition> (disposition)
-
-=item I<set_content_disposition_object> (Mail::Rspamd::Disposition)
-
-=item I<get_content_disposition> ()
-
-=item I<get_content_disposition> ()
-
-Set and get content disposition (Content-Disposition) on the MIME part.
-As the parameter one can issue usualy 'inline' or 'attachment'.
-Function get_content_disposition() returns only the main part of this
-header (no parameters).
-
-=item I<add_content_disposition_parameter> (name, value)
-
-=item I<get_content_disposition_parameter> (name)
-
-Add and get content disposition parameter.
-
-=item I<set_filename> (filename)
-
-Add the 'filename' content disposition parameter to the Content-Disposition
-header, and 'name' parameter to the Content-Type header.
-
-=item I<get_filename> ()
-
-Get filename suggested by the MIME part headers (either from the
-Content-Disposition or Content-Type header).
-
-=item I<set_content> (content_object)
-
-Set content of the MIME part based on the supplied argument (text
-Mail::Rspamd::Stream object, Mail::Rspamd::DataWrapper object
-or FILEHANDLE).
-
-=item I<get_content> ()
-
-Get text content of the MIME part (readonly).
-
-=item I<get_content_object> ()
-
-Get Mail::Rspamd::DataWrapper object of the MIME part.
-
-=item I<set_pre_encoded_content> (content, encoding)
-
-Set pre-encoded content on the MIME part. The 'encoding'
-parameter can have values described in encoding_to_string() function above.
-These function are used by the parser. You can write your own.
-
-=back
-
-=head2 Mail::Rspamd::Object
-
-This is the base class for Mail::Rspamd objects (messages,
-parts, multiparts, filters, streams etc.). 
-
-=over 4
-
-=item I<set_content_type> ($type)
-
-=item I<get_content_type> ()
-
-Set and get content type on the Mail::Rspamd::Object. The 'type' parameter
-should be a Mail::Rspamd::ContentType object.
-E.g.
-
-    $type = $part->get_content_type;
-    print "Type of $part is " . $type->to_string;
-
-=item I<set_content_type_parameter> ($name, $value)
-
-=item I<get_content_type_parameter> ($name)
-
-Sets or gets the value of the content-type param $name set on the MIME part object.
-
-=item I<set_content_id> (content_id)
-
-=item I<get_content_id> ()
-
-Set and get content id (Content-Id) on the MIME part object.
-
-=item I<set_header>(field, value)
-
-Set a message header to the MIME object.
-
-=item I<add_header>(field, value)
-
-Add a header field to the MIME object header.
-
-=item I<remove_header>(field)
-
-Removes the given field from the header.
-
-=item I<get_header>(field)
-
-Gets the value of the requested header.
-
-=item I<get_content_length> ()
-
-Get content length of the MIME object.
-
-B<NOTE>: This methoid does not exists in the C gmime.
-
-B<NOTE>: Encoded content length is only prediction, not the exact number of bytes
-you would get after final encoding. Predicted encoded length is 
-greater or equal to size of the encoded parts, though. The length
-of the part/message headers is not counted.
-
-=item I<is_multipart> ()
-
-Returns 1 if the MIME object is of type multipart, 0 otherwise.
-
-B<NOTE>: This methoid does not exists in the C gmime.
-
-=item I<effective_type> ()
-
-Returns content type of the given object as a lowercase text string.
-
-B<NOTE>: This methoid does not exists in the C gmime.
-
-=item I<to_string>()
-
-Returns the contents of the MIME object as a string.
-
-=back
-
-=head2 Mail::Rspamd::ContentType
-
-=over 4
-
-=item I<new> (type, subtype)
-
-=item I<new> (str)
-
-Create new Mail::Rspamd::ContentType object with type of 'type/subtype'
-or type read from the string 'str'.
-
-=item I<type> ()
-
-Get the 'type' part (string) of the Mail::Rspamd::ContentType object.
-B<NOTE>: this method is not in gmime C library.
-
-=item I<subtype> ()
-
-Get the 'subtype' part (string) of the Mail::Rspamd::ContentType object.
-B<NOTE>: this method is not in gmime C library.
-
-=item I<to_string> ()
-
-Get the string representation for the Mail::Rspamd::ContentType object.
-
-=item I<is_type> (type, subtype)
-
-Returns 1 if content type match the given type and subtype, 0 otherwise.
-You can use '*' in place of type or subtype as a wildcard.
-This function is case insensitive.
-E.g.
-
-    $is_multipart = $content_type->is_type('multipart','*');
-    $is_text = $content_type->is_type('text','*');
-
-=item I<add_parameter> (attribute, value)
-
-=item I<get_parameter> ()
-
-Add and get parameter to/of the content type header.
-E.g.
-
-    $content_type->add_parameter('name', 'test.gif');
-
-=back
-
-=head2 Mail::Rspamd::Task
-
-This is the base class for Mail::Rspamd objects (messages,
-parts, multiparts, filters, streams etc.). 
-
-=over 4
-
-=item I<get_message> ()
-
-=item I<set_message> (message)
-
-Get and set Mail::Rspamd::Message object from task.
-
-=item I<ip> ()
-
-Get ip address of client.
-
-=item I<from> ()
-
-Get MAIL FROM address.
-
-=item I<save_point> ()
-
-Set save point to task for delayed filter's processing.
-
-=item I<recall_filter> ()
-
-Restore filter's processing
-
-=item I<insert_result> (metric, symbol, flag)
-
-Insert to task result to metric <metric>, that have symbol <symbol> and value <flag>.
-
-=item I<get_conf> ()
-
-Return Mail::Rspamd::Config object.
-
-=item I<get_urls> ()
-
-Return message's urls as array of strings.
-
-=item I<get_text_parts> ()
-
-Return message's text parts as array of Mail::Rspamd::TextPart objects.
-
-=back
-
-=head2 Mail::Rspamd::Config
-
-Object that allows access to rspamd config (read and write).
-
-=over 4
-
-=item I<get_scalar> (scalar)
-
-=item I<set_scalar> (scalar, value)
-
-Gets and sets specified parameter in config.
-
-=item I<get_metric> (metric)
-
-Returns hash of parameters of specified metric:
-
-=begin text
-
-{
-'name'             => name of metric
-'func_name'        => consolidation function
-'required_score'   => score for metric
-}
-
-=end text
-
-=item I<get_statfile> (statfile)
-
-Returns parameters of specified statfile:
-
-=begin text
-
-{
-'alias'         => alias of statfile
-'pattern'       => fs pattern
-'metric'        => metric of statfile
-'weight'        => weigth of statfile
-'size'          => size of statfile
-}
-
-=end text
-
-=item I<get_module_param> (modulename, paramname)
-
-Return parameter's value for specified module.
-
-=back
-
-=head2 Mail::Rspamd::TextPart
-
-Object that represent a single text part of message.
-
-=over 4
-
-=item I<get_content> ()
-
-Returns content of part.
-
-=item I<get_fuzzy> ()
-
-Returns fuzzy hash of part as string.
-
-=item I<compare_distance> (other)
-
-Calculate distance between two parts using their fuzzy hashes. Return value from 0 (identical) to 100 (totally different).
-
-=item I<is_html> ()
-
-Return 0 if part is plain text and not 0 otherwise.
-
-=back
-
-=head1 CONSTANT VARIABLES
-
-    GMIME_LENGTH_ENCODED
-    GMIME_LENGTH_CUMULATIVE
-
-    GMIME_PART_ENCODING_DEFAULT
-    GMIME_PART_ENCODING_7BIT
-    GMIME_PART_ENCODING_8BIT
-    GMIME_PART_ENCODING_BASE64
-    GMIME_PART_ENCODING_QUOTEDPRINTABLE
-    GMIME_PART_NUM_ENCODINGS
-
-    GMIME_RECIPIENT_TYPE_TO
-    GMIME_RECIPIENT_TYPE_CC
-    GMIME_RECIPIENT_TYPE_BCC
-
-    INTERNET_ADDRESS_NONE
-    INTERNET_ADDRESS_NAME
-    INTERNET_ADDRESS_GROUP
-
-=head1 REQUIREMENTS
-
-This module Mail::Rspamd requires perl 5.8.x and gmime 2.0.9 or higher.
-
-
-=head1 BUGS
-
-Quoted-printable binary parts could be wrongly decoded (when
-the new line is "\n" instead of "\r\n", and there is no equal sign
-at the end of line. RFC says that binary parts should be encoded with
-BASE64 not Q-P (it is also best compression for such parts).
-Then there is no harm.
-
-=head1 AUTHOR
-
-Piotr Klaban, post@klaban.torun.pl (original author of MIME::Fast)
-Vsevolod Stakhov, vsevolod@highsecure.ru
-
-=head1 SEE ALSO
-
-perl(1).
-
-The homepage of gmime C library at http://spruce.sourceforge.net/gmime/
-The homepage of MIME::Fast perl module is available at http://search.cpan.org/dist/MIME-Fast/
diff --git a/perl/Rspamd.xs b/perl/Rspamd.xs
deleted file mode 100644 (file)
index ecfe0b9..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Perl XS module for interacting with rspamd
- *
- * vi:ts=4 
- */
-
-#include "../src/config.h"
-#include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
-
-#include "../src/main.h"
-#include "../src/message.h"
-#include "../src/cfg_file.h"
-#include "../src/perl.h"
-#include "../src/mem_pool.h"
-#include "../src/fuzzy.h"
-
-#define XSINTERFACE_FUNC_RSPAMD_MESSAGE_SET(cv,f)      \
-       CvXSUBANY(cv).any_dptr = (void (*) (pTHX_ void*))(CAT2( g_mime_message_,f ))
-#define XSINTERFACE_FUNC_RSPAMD_PART_SET(cv,f)      \
-       CvXSUBANY(cv).any_dptr = (void (*) (pTHX_ void*))(CAT2( g_mime_part_,f ))
-#define XSINTERFACE_FUNC_RSPAMD_IA_SET(cv,f)      \
-       CvXSUBANY(cv).any_dptr = (void (*) (pTHX_ void*))(CAT2( internet_address_,f ))
-
-struct raw_header {
-    struct raw_header *next;
-    char *name;
-    char *value;
-};                     
-
-typedef struct _GMimeHeader {
-       GHashTable *hash;
-       GHashTable *writers;
-       struct raw_header *headers;
-} local_GMimeHeader;
-
-/* enums */
-#ifdef GMIME24
-typedef GMimeContentEncoding Mail__Rspamd__PartEncodingType;
-typedef int    Mail__Rspamd__InternetAddressType;
-#else
-typedef InternetAddressType    Mail__Rspamd__InternetAddressType;
-typedef GMimePartEncodingType  Mail__Rspamd__PartEncodingType;
-#endif
-
-/* C types */
-typedef GMimeObject *          Mail__Rspamd__Object;
-typedef GMimeParam *           Mail__Rspamd__Param;
-typedef GMimePart *            Mail__Rspamd__Part;
-typedef struct mime_text_part * Mail__Rspamd__TextPart;
-typedef GMimeParser *          Mail__Rspamd__Parser;
-typedef GMimeMultipart *       Mail__Rspamd__MultiPart;
-typedef GMimeMessage *         Mail__Rspamd__Message;
-typedef GMimeMessagePart *     Mail__Rspamd__MessagePart;
-typedef GMimeMessagePartial *  Mail__Rspamd__MessagePartial;
-typedef InternetAddress *      Mail__Rspamd__InternetAddress;
-#ifdef GMIME24
-typedef GMimeContentDisposition *      Mail__Rspamd__Disposition;
-#else
-typedef GMimeDisposition *     Mail__Rspamd__Disposition;
-#endif
-typedef GMimeContentType *     Mail__Rspamd__ContentType;
-typedef GMimeCharset *         Mail__Rspamd__Charset;
-
-/*
- * Declarations for message header hash array
- */
-
-static gboolean
-recipients_destroy (gpointer key, gpointer value, gpointer user_data)
-{
-       InternetAddressList *recipients = value;
-       internet_address_list_destroy (recipients);
-
-       return TRUE;
-}
-
-typedef struct {
-        int                            keyindex;       /* key index for firstkey */
-        char                   *fetchvalue;    /* value for each() method fetched with FETCH */
-        Mail__Rspamd__Message  objptr;         /* any object pointer */
-} hash_header;
-
-typedef hash_header *Mail__Rspamd__Hash__Header;
-
-
-/*
- * Double linked list of perl allocated pointers (for DESTROY xsubs)
- */
-static GList *plist = NULL;
-
-/*
- * Calling callback function for each mime part
- */
-struct _user_data_sv {
-       SV *  svfunc;
-       SV *  svuser_data;
-       SV *  svfunc_complete;
-       SV *  svfunc_sizeout;
-};
-
-static void
-call_sub_foreach(GMimeObject *mime_object, gpointer data)
-{
-       SV * svpart;
-       SV * rvpart;
-
-       dSP ;
-       struct _user_data_sv *svdata;
-
-       svdata = (struct _user_data_sv *) data;
-       svpart = sv_newmortal ();
-
-       if (GMIME_IS_PART(mime_object)) {
-               rvpart = sv_setref_pv(svpart, "Mail::Rspamd::Part", (Mail__Rspamd__Part)mime_object);
-       } else {
-               rvpart = sv_setref_pv(svpart, "Mail::Rspamd::Object", mime_object);
-       }
-               
-       PUSHMARK (sp);
-       XPUSHs (rvpart);
-       XPUSHs (sv_mortalcopy (svdata->svuser_data));
-       PUTBACK ;
-       if (svdata->svfunc) {
-               perl_call_sv (svdata->svfunc, G_DISCARD);
-       }
-}
-
-
-
-
-MODULE = Mail::Rspamd   PACKAGE = Mail::Rspamd::Log PREFIX = rspamd_log_
-PROTOTYPES: DISABLE
-
-void
-rspamd_log_log (level, str)
-       int level
-       const char *str
-    CODE:
-       g_log (G_LOG_DOMAIN, level, "%s", str);
-
-
-MODULE = Mail::Rspamd   PACKAGE = Mail::Rspamd
-
-INCLUDE: Rspamd/Object.xs
-INCLUDE: Rspamd/ContentType.xs
-INCLUDE: Rspamd/Part.xs
-INCLUDE: Rspamd/Message.xs
-
-INCLUDE: Rspamd/InternetAddress.xs
-INCLUDE: Rspamd/Hash.xs
-INCLUDE: Rspamd/TextPart.xs
-
-
diff --git a/perl/Rspamd/Config.xs b/perl/Rspamd/Config.xs
deleted file mode 100644 (file)
index 49b26db..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-MODULE = Mail::Rspamd   PACKAGE = Mail::Rspamd::Config PREFIX = rspamd_config_
-PROTOTYPES: DISABLE
-
-SV *
-rspamd_config_get_scalar (cfg, param)
-               Mail::Rspamd::Config cfg
-               const char *param
-       CODE:
-               struct config_scalar *sc;
-               int val;
-
-               sc = g_hash_table_lookup (cfg->cfg_params, param);
-               if (sc == NULL) {
-                       XSRETURN_UNDEF;
-               }
-               else {
-                       switch (sc->type) {
-                               case SCALAR_TYPE_SIZE:
-                                       RETVAL = newSViv ((int)(*(size_t *)sc->pointer));
-                                       break;
-                               case SCALAR_TYPE_INT:
-                               case SCALAR_TYPE_UINT:
-                                       RETVAL = newSViv (*(int *)sc->pointer);
-                                       break;
-                               case SCALAR_TYPE_STR:
-                                       RETVAL = newSVpv ((char *)sc->pointer, 0);
-                                       break;
-                       }
-               }
-
-
-void
-rspamd_config_set_scalar (cfg, param, value)
-               Mail::Rspamd::Config cfg
-               const char *param
-               SV* value
-       CODE:
-               char *param, *charval;
-               int intval;
-
-               sc = g_hash_table_lookup (cfg->cfg_params, param);
-               if (sc == NULL) {
-                       XSRETURN_UNDEF;
-               }
-               else {
-                       switch (sc->type) {
-                               case SCALAR_TYPE_SIZE:
-                                       intval = (int)SvIV (value);
-                                       *((size_t *)sc->pointer) = intval;
-                                       break;
-                               case SCALAR_TYPE_INT:
-                               case SCALAR_TYPE_UINT:
-                                       intval = (int)SvIV (value);
-                                       *((int *)sc->pointer) = intval;
-                                       break;
-                               case SCALAR_TYPE_STR:
-                                       charval = (char *)SvPVX (value);
-                                       *((char **)sc->pointer) = charval;
-                                       break;
-                       }
-               }
-
-HV *
-rspamd_config_get_metric (r, name)
-               Mail::Rspamd::Config cfg
-               const char *name
-       CODE:
-               struct metric *val;
-               
-               val = g_hash_table_lookup (r->metrics, name);
-               if (val == NULL) {
-                       XSRETURN_UNDEF;
-               }
-               else {
-                       RETVAL = newHV();
-
-                       (void)hv_store_ent (RETVAL, 
-                                       newSVpv ("name", sizeof ("name") - 1), 
-                                       newSVpv (val->name, strlen (val->name)), 0);
-                       (void)hv_store_ent (RETVAL, 
-                                       newSVpv ("func_name", sizeof ("func_name") - 1), 
-                                       newSVpv (val->func_name, strlen (val->func_name)), 0);
-                       (void)hv_store_ent (RETVAL, 
-                                       newSVpv ("required_score", sizeof ("required_score") - 1), 
-                                       newSVnv (val->required_score), 0);
-                       sv_2mortal((SV*)RETVAL);
-               }
-       OUTPUT:
-               RETVAL
-
-HV *
-rspamd_config_get_statfile (r, name)
-               Mail::Rspamd::Config cfg
-               const char *name
-       CODE:
-               struct statfile *val;
-               char *name;
-               
-               val = g_hash_table_lookup (r->statfiles, name);
-               if (val == NULL) {
-                       XSRETURN_UNDEF;
-               }
-               else {
-                       RETVAL = newHV();
-
-                       (void)hv_store_ent (RETVAL, 
-                                       newSVpv ("alias", sizeof ("alias") - 1), 
-                                       newSVpv (val->alias, strlen (val->alias)), 0);
-                       (void)hv_store_ent (RETVAL, 
-                                       newSVpv ("pattern", sizeof ("pattern") - 1), 
-                                       newSVpv (val->pattern, strlen (val->pattern)), 0);
-                       (void)hv_store_ent (RETVAL, 
-                                       newSVpv ("metric", sizeof ("metric") - 1), 
-                                       newSVpv (val->metric, strlen (val->metric)), 0);
-                       (void)hv_store_ent (RETVAL, 
-                                       newSVpv ("weight", sizeof ("weight") - 1), 
-                                       newSVnv (val->weight), 0);
-                       (void)hv_store_ent (RETVAL, 
-                                       newSVpv ("size", sizeof ("size") - 1), 
-                                       newSViv (val->size), 0);
-                       sv_2mortal((SV*)RETVAL);
-               }
-       OUTPUT:
-               RETVAL
-
-SV*
-rspamd_config_get_module_param (r, modulename, paramname)
-               Mail::Rspamd::Config cfg
-               const char *modulename
-               const char *paramname
-       CODE:
-               char *value;
-
-               value = get_module_opt (r, modulename, paramname);
-               if (value == NULL) {
-                       XSRETURN_UNDEF;
-               }
-               RETVAL = newSVpv (value, 0);
-       OUTPUT:
-               RETVAL
-
diff --git a/perl/Rspamd/ContentType.xs b/perl/Rspamd/ContentType.xs
deleted file mode 100644 (file)
index dae8a35..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-MODULE = Mail::Rspamd PACKAGE = Mail::Rspamd::ContentType PREFIX = rspamd_content_type_
-
-Mail::Rspamd::ContentType
-rspamd_content_type_new (Class = "Mail::Rspamd::ContentType", name = 0, subname = 0)
-       CASE: items == 2
-               char *          Class;
-               const char *    name;
-       CODE:
-               RETVAL = g_mime_content_type_new_from_string (name);
-               plist = g_list_prepend (plist, RETVAL);
-       OUTPUT:
-               RETVAL
-       CASE: items == 3
-               char *          Class;
-               const char *    name;
-               const char *    subname;
-       CODE:
-               RETVAL = g_mime_content_type_new (name, subname);
-               plist = g_list_prepend (plist, RETVAL);
-       OUTPUT:
-               RETVAL
-
-void
-DESTROY (mime_type)
-               Mail::Rspamd::ContentType               mime_type
-       CODE:
-               if (g_list_find(plist,mime_type)) {
-                       g_mime_content_type_destroy(mime_type);
-                       plist = g_list_remove(plist, mime_type);
-               }
-
-SV *
-rspamd_content_type_to_string (mime_type)
-               Mail::Rspamd::ContentType               mime_type
-       PREINIT:
-               char *  type;
-       CODE:
-               type = g_mime_content_type_to_string (mime_type);
-               if (!type)
-                       XSRETURN_UNDEF;
-               RETVAL = newSVpv(type, 0);
-               g_free (type);
-       OUTPUT:
-               RETVAL
-
-gboolean
-rspamd_content_type_is_type (mime_type, type, subtype)
-               Mail::Rspamd::ContentType               mime_type
-               const char *                    type
-               const char *                    subtype
-       CODE:
-               RETVAL = g_mime_content_type_is_type (mime_type, type, subtype);
-       OUTPUT:
-               RETVAL
-
-void
-rspamd_content_type_set_parameter (mime_type, attribute, value)
-               Mail::Rspamd::ContentType               mime_type
-               const char *                    attribute
-               const char *                    value
-       CODE:
-               g_mime_content_type_set_parameter (mime_type, attribute, value);
-
-const char *
-rspamd_content_type_get_parameter (mime_type, attribute)
-               Mail::Rspamd::ContentType               mime_type
-               const char *                    attribute
-       CODE:
-               RETVAL = g_mime_content_type_get_parameter (mime_type, attribute);
-       OUTPUT:
-               RETVAL
-
-char *
-rspamd_content_type_type (ctype)
-               Mail::Rspamd::ContentType       ctype
-       CODE:
-               RETVAL = ctype->type;
-       OUTPUT:
-               RETVAL
-               
-char *
-rspamd_content_type_subtype (ctype)
-               Mail::Rspamd::ContentType       ctype
-       CODE:
-               RETVAL = ctype->subtype;
-       OUTPUT:
-               RETVAL
diff --git a/perl/Rspamd/Hash.xs b/perl/Rspamd/Hash.xs
deleted file mode 100644 (file)
index abf75ce..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-MODULE = Mail::Rspamd PACKAGE = Mail::Rspamd::Hash::Header PREFIX=hash_
-
-Mail::Rspamd::Hash::Header
-hash_TIEHASH (Class, objptr)
-               char *                  Class
-               Mail::Rspamd::Message           objptr
-       PREINIT:
-               hash_header *           hash;
-       CODE:
-               hash = g_malloc (sizeof (hash_header));
-               hash->keyindex = 0;
-               hash->objptr = objptr;
-               hash->fetchvalue = NULL;
-               RETVAL = hash;
-       OUTPUT:
-               RETVAL
-
-void
-hash_DESTROY (obj)
-               Mail::Rspamd::Hash::Header      obj
-       CODE:
-               obj->objptr = NULL;
-               g_free (obj);
-
-void
-hash_FETCH (obj, key)
-               Mail::Rspamd::Hash::Header      obj
-               const char *            key
-       PREINIT:
-               Mail__Rspamd__Message           msg;
-               GList                   *gret = NULL, *item;
-               AV *                    retav;
-               I32                     gimme = GIMME_V;
-       PPCODE:
-               msg = obj->objptr;
-
-               /* THE HACK - FETCH method would get value indirectly from NEXTKEY */
-               if (obj->keyindex != -1 && obj->fetchvalue != NULL) {
-                       XPUSHs (sv_2mortal (newSVpv (obj->fetchvalue, 0)));
-                       obj->fetchvalue == NULL;
-                       XSRETURN(1);
-               }
-
-               obj->fetchvalue = NULL;
-               
-               gret = message_get_header (NULL, msg, key);
-
-               if (!gret || gret->data == NULL) {
-                       if (gret) {
-                               g_list_free(gret);
-                       }
-                 
-                       XSRETURN(0);
-               } else {
-                       if (gret->next == NULL) { // one value
-                               XPUSHs (sv_2mortal (newSVpv ((char *)(gret->data), 0)));
-                       } else {
-                               if (gimme == G_ARRAY) {
-                                       item = gret;
-                                       while (item && item->data) {
-                                               XPUSHs (sv_2mortal (newSVpv ((char *)(item->data), 0)));
-                                               item = item->next;
-                                       }
-                               } else if (gimme == G_SCALAR) {
-                                       retav = newAV();
-                                       item = gret;
-                                       while (item && item->data) {
-                                               av_push (retav, newSVpv ((char *)g_strdup ((item->data)), 0));
-                                               item = item->next;
-                                       }
-                                       XPUSHs (newRV_noinc ((SV *)retav));
-                               }
-                       }
-               }
-               if (gret) {
-                       item = gret;
-                       while (item) {
-                               if (item->data) {
-                                       g_free((char *)(item->data));
-                               }
-                               item = item->next;
-                       }
-                       g_list_free(gret);
-               }
-
-void
-hash_STORE (obj, key, svmixed)
-               Mail::Rspamd::Hash::Header      obj
-               const char *            key
-               SV *                    svmixed
-       PREINIT:
-               Mail__Rspamd__Message           msg;
-               char *                  value;
-               SV *                    svvalue;
-               svtype                  svvaltype;
-               STRLEN                  vallen;
-       CODE:
-               /* only one value can be stored - no arrays allowed by perl */
-               msg = obj->objptr;
-
-               svvalue = svmixed;
-               if (SvROK (svmixed)) {
-                       svvalue = SvRV(svmixed);
-               }
-               svvaltype = SvTYPE (svvalue);
-
-               if (SvGMAGICAL(svvalue)) {
-                       mg_get(svvalue);
-               }
-               
-               /* delete header for the first array item */
-               g_mime_object_remove_header (GMIME_OBJECT(msg), key);
-
-               if (svvaltype == SVt_PVAV) {
-                       AV *    avvalue;
-                       I32             i, avlen;
-                       SV *    svtmp;
-
-                       /* set header */
-                       avvalue = (AV *)svvalue;
-                       avlen = av_len(avvalue);
-                       for (i=avlen; i>=0; --i) {
-                               svtmp = (SV *)(*(av_fetch (avvalue, i, 0)));
-
-                               if (SvGMAGICAL(svtmp)) {
-                                       mg_get(svtmp);
-                               }
-                       
-                               if (svtmp && SvPOKp(svtmp)) {
-                                       value = (char *)SvPV(svtmp, vallen);
-                                       message_set_header (msg, key, value);
-                               }
-                       }
-               } else if (SvPOK(svvalue) || SvIOK(svvalue) || SvNOK(svvalue)) {
-                       value = (char *)SvPV (svvalue, vallen);
-                       message_set_header (msg, key, value);
-               } else { /* assume scalar value */
-                       /* undefined value -> remove header */
-                       if (!(SvOK(svvalue))) {
-                               g_mime_object_remove_header (GMIME_OBJECT(msg), key);
-                       }
-               }
-
-gboolean
-hash_EXISTS (obj, key)
-               Mail::Rspamd::Hash::Header      obj
-               const char *            key
-       PREINIT:
-               Mail__Rspamd__Message           msg;
-               GList                   *gret, *item;
-       CODE:
-               msg = obj->objptr;
-               gret = message_get_header (NULL, msg, key);
-               RETVAL = (gret != NULL && gret->data != NULL);
-               if (gret) {
-                       item = gret;
-                       while (item) {
-                               if (item->data) {
-                                       g_free((char *)(item->data));
-                               }
-                               item = item->next;
-                       }
-                       g_list_free(gret);
-               }
-       OUTPUT:
-               RETVAL
-
-void
-hash_DELETE(obj, key)
-               Mail::Rspamd::Hash::Header      obj
-               const char *            key
-       CODE:
-               g_mime_object_remove_header (GMIME_OBJECT(obj->objptr), key);
-
-void
-hash_NEXTKEY(obj, lastkey = NULL)
-               Mail::Rspamd::Hash::Header      obj
-               const char *            lastkey
-       ALIAS:
-               Mail::Rspamd::Hash::Header::FIRSTKEY = 1
-       PREINIT:
-               const char *                    key = NULL;
-               const char *                    value = NULL;
-               Mail__Rspamd__Message           msg;
-               I32                     gimme = GIMME_V;
-               gint                    i, j, found;
-#ifdef GMIME24
-               GMimeHeaderList *hl;
-               GMimeHeaderIter *iter;
-#else
-               local_GMimeHeader *             header;
-#endif
-               struct raw_header       *h;
-       INIT:
-               if (ix == 1) {
-                       obj->keyindex = -1;
-               }
-       PPCODE:
-               msg = obj->objptr;
-               ++obj->keyindex;
-               i = obj->keyindex;
-#ifdef GMIME24
-               hl = g_mime_object_get_header_list (GMIME_OBJECT (msg));
-               j = 0;
-               found = 0;
-               if (g_mime_header_list_get_iter (hl, iter)) {
-                       while (g_mime_header_iter_is_valid (iter)) {
-                               if (j >= i) {
-                                       key = g_mime_header_iter_get_name (iter);
-                                       value = g_mime_header_iter_get_value (iter);
-                                       found = 1;
-                                       break;
-                               }       
-                               if (!g_mime_header_iter_next (iter)) {
-                                       break;
-                               }
-                       }
-               }
-#else
-               header = GMIME_OBJECT(msg)->headers;
-
-               h = header->headers;
-               j = 0;
-               found = 0;
-               while (h) {
-                       if (j >= i) {
-                               key = h->name;
-                               value = h->value;
-                               found = 1;
-                               break;
-                       }
-                       j++;
-                       h = h->next;
-               }
-#endif
-               
-               if (!found && key == NULL) {
-                       obj->keyindex = -1;
-               }
-
-               /* THE HACK - FETCH method would get value indirectly */
-               obj->fetchvalue = NULL;
-
-               if (key) {
-                       XPUSHs (sv_2mortal (newSVpv (key, 0)));
-                       if (gimme != G_SCALAR && value) {
-                               XPUSHs (sv_2mortal (newSVpv (value, 0)));
-                       }
-                       /* THE HACK - FETCH method would get value indirectly */
-                       obj->fetchvalue = (char *)value;
-               }
-
-#ifndef GMIME24
-
-void
-hash_CLEAR(obj)
-               Mail::Rspamd::Hash::Header      obj
-       PREINIT:
-               Mail__Rspamd__Message           message;
-               local_GMimeHeader               *header;
-       CODE:
-               message = obj->objptr;
-               
-               g_free (message->from);
-               message->from = NULL;
-
-               g_free (message->reply_to);
-               message->reply_to = NULL;
-               
-               /* destroy all recipients */
-               g_hash_table_foreach_remove (message->recipients, recipients_destroy, NULL);
-               
-               g_free (message->subject);
-               message->subject = NULL;
-               
-               g_free (message->message_id);
-               message->message_id = NULL;
-
-               /* free all the headers */
-               header = GMIME_OBJECT(message)->headers;
-               g_mime_header_destroy (header);
-               GMIME_OBJECT(message)->headers = g_mime_header_new ();
-
-#endif
diff --git a/perl/Rspamd/InternetAddress.xs b/perl/Rspamd/InternetAddress.xs
deleted file mode 100644 (file)
index 6ccf30c..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-MODULE = Mail::Rspamd PACKAGE = Mail::Rspamd::InternetAddress PREFIX = rspamd_internet_address_
-
-Mail::Rspamd::InternetAddress
-rspamd_internet_address_new (Class, name, address)
-       CASE: items <= 1
-               char *          Class
-       CODE:
-#ifdef GMIME24
-               XSRETURN_UNDEF;
-#else
-               RETVAL = internet_address_new ();
-               plist = g_list_prepend (plist, RETVAL);
-#endif
-       OUTPUT:
-               RETVAL
-       CASE: items == 2
-               char *          Class
-               char *          name
-       CODE:
-#ifdef GMIME24
-               RETVAL = internet_address_group_new (name);
-#else
-               RETVAL = internet_address_new_group (name);
-#endif
-               plist = g_list_prepend (plist, RETVAL);
-       OUTPUT:
-               RETVAL
-       CASE: items == 3
-               char *          Class
-               char *          name
-               char *          address
-       CODE:
-#ifdef GMIME24
-               RETVAL = internet_address_mailbox_new (name, address);
-#else
-               RETVAL = internet_address_new_name (name, address);
-#endif
-               plist = g_list_prepend (plist, RETVAL);
-       OUTPUT:
-               RETVAL
-
-void
-DESTROY(ia)
-               Mail::Rspamd::InternetAddress   ia
-       CODE:
-               if (g_list_find (plist,ia)) {
-                       internet_address_unref (ia);
-                       plist = g_list_remove (plist, ia);
-               }
-
-AV *
-rspamd_internet_address_parse_string (str)
-               const char *            str
-       PREINIT:
-               InternetAddressList *           addrlist;
-               AV *            retav;
-               int i;
-       CODE:
-#ifdef GMIME24
-               addrlist = internet_address_list_parse_string (str);
-#else
-               addrlist = internet_address_parse_string (str);
-#endif
-               retav = newAV ();
-#ifdef GMIME24
-               i = internet_address_list_length (addrlist);
-               while (i > 0) {
-                       SV * address = newSViv(0);
-                       sv_setref_pv (address, "Mail::Rspamd::InternetAddress", (Mail__Rspamd__InternetAddress)internet_address_list_get_address (addrlist, i));
-                       av_push (retav, address);
-                       -- i;
-               }
-#else
-               while (addrlist) {
-                 SV * address = newSViv (0);
-                 sv_setref_pv (address, "Mail::Rspamd::InternetAddress", (Mail__Rspamd__InternetAddress)(addrlist->address));
-                 av_push (retav, address);
-                 addrlist = addrlist->next;
-               }
-#endif
-               RETVAL = retav;
-       OUTPUT:
-               RETVAL
-
-#ifdef GMIME24
-
-void
-interface_ia_set (ia, value)
-               Mail::Rspamd::InternetAddress   ia
-       char *                          value
-       INTERFACE_MACRO:
-       XSINTERFACE_FUNC
-       XSINTERFACE_FUNC_RSPAMD_IA_SET
-       INTERFACE:
-       set_name
-
-#else
-
-void
-interface_ia_set (ia, value)
-               Mail::Rspamd::InternetAddress   ia
-       char *                          value
-       INTERFACE_MACRO:
-       XSINTERFACE_FUNC
-       XSINTERFACE_FUNC_RSPAMD_IA_SET
-       INTERFACE:
-       set_name
-       set_addr
-
-#endif
-
-SV *
-rspamd_internet_address_to_string (ia, encode = TRUE)
-               Mail::Rspamd::InternetAddress   ia
-               gboolean                encode
-       PREINIT:
-               char *          textdata;
-       CODE:
-               textdata = internet_address_to_string (ia, encode);
-               if (textdata == NULL) {
-                       XSRETURN_UNDEF;
-               }
-               RETVAL = newSVpv (textdata, 0);
-       OUTPUT:
-               RETVAL
-
-void
-rspamd_internet_address_set_group (ia, ...)
-               Mail::Rspamd::InternetAddress   ia
-       PREINIT:
-               Mail__Rspamd__InternetAddress   addr;
-               InternetAddressList *           addrlist = NULL;
-               int                     i;
-       CODE:
-               if (items < 2) {
-                       XSRETURN_UNDEF;
-               }
-               for (i = items - 1; i > 0; --i) {
-                       /* retrieve each address from the perl array */
-                       if (sv_derived_from (ST (items - i), "Mail::Rspamd::InternetAddress")) {
-                               IV tmp = SvIV ((SV*)SvRV (ST (items - i)));
-                               addr = INT2PTR (Mail__Rspamd__InternetAddress, tmp);
-                       }
-                       if (addr) {
-#ifdef GMIME24
-                               internet_address_list_add (addrlist, addr);
-#else
-                               internet_address_list_append (addrlist, addr);
-#endif
-                       }
-               }
-               if (addrlist) {
-                       internet_address_set_group (ia, addrlist);
-               }
-
-void
-rspamd_internet_address_add_member (ia, member)
-               Mail::Rspamd::InternetAddress   ia
-               Mail::Rspamd::InternetAddress   member
-       CODE:
-               internet_address_add_memeber (ia, member);
-
-Mail::Rspamd::InternetAddressType
-rspamd_internet_address_type (ia)
-               Mail::Rspamd::InternetAddress   ia
-       CODE:
-#ifndef GMIME24
-               RETVAL = ia->type;
-#else
-               XSRETURN_UNDEF;
-#endif
-       OUTPUT:
-               RETVAL
-
diff --git a/perl/Rspamd/Message.xs b/perl/Rspamd/Message.xs
deleted file mode 100644 (file)
index c9a2188..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-MODULE = Mail::Rspamd PACKAGE = Mail::Rspamd::Message PREFIX = rspamd_message_
-
-Mail::Rspamd::Message
-rspamd_message_new(Class, pretty_headers = FALSE)
-               char *          Class
-               gboolean        pretty_headers
-       CODE:
-               RETVAL = g_mime_message_new (pretty_headers);
-               plist = g_list_prepend(plist, RETVAL);
-       OUTPUT:
-               RETVAL
-
-void
-DESTROY(message)
-               Mail::Rspamd::Message   message
-       CODE:
-               if (g_list_find(plist,message)) {
-                       g_mime_object_unref (GMIME_OBJECT (message));
-                       plist = g_list_remove(plist, message);
-               }
-
-void
-rspamd_message_add_recipient(message, type, name, address)
-               Mail::Rspamd::Message   message
-               char *          type
-               const char *    name
-               const char *    address
-       CODE:
-#ifndef GMIME24
-               g_mime_message_add_recipient (message, type, name, address);
-#else
-               if (!g_strcasecmp (type, "to")) {
-                       g_mime_message_add_recipient (message, GMIME_RECIPIENT_TYPE_TO, name, address);
-               }
-               else if (!g_strcasecmp (type, "cc")) {
-                       g_mime_message_add_recipient (message, GMIME_RECIPIENT_TYPE_CC, name, address);
-               }
-               else if (!g_strcasecmp (type, "bcc")) {
-                       g_mime_message_add_recipient (message, GMIME_RECIPIENT_TYPE_BCC, name, address);
-               }
-#endif
-
-void
-rspamd_message_add_recipients_from_string(message, type, recipients)
-       Mail::Rspamd::Message   message
-               char *          type
-               const char *    recipients
-       CODE:
-#ifndef GMIME24
-               g_mime_message_add_recipients_from_string (message, type, recipients);
-#else
-               /* XXX: add code here */
-               XSRETURN_UNDEF;
-#endif
-
-
-AV *
-rspamd_message_get_recipients(message, type)
-               Mail::Rspamd::Message   message
-               const char *    type
-       PREINIT:
-               InternetAddressList *           rcpt;
-               AV *            retav;
-               int i;
-       CODE:
-               retav = newAV();
-#ifndef GMIME24
-               rcpt = (InternetAddressList *)g_mime_message_get_recipients (message, type);
-               while (rcpt) {
-                 SV * address = newSViv(0);
-                 sv_setref_pv(address, "Mail::Rspamd::InternetAddress", (Mail__Rspamd__InternetAddress)(rcpt->address));
-                 av_push(retav, address);
-                 rcpt = rcpt->next;
-               }
-#else
-               if (!g_strcasecmp (type, "to")) {
-                       rcpt = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_TO);
-               }
-               else if (!g_strcasecmp (type, "cc")) {
-                       rcpt = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_CC);
-               }
-               else if (!g_strcasecmp (type, "bcc")) {
-                       rcpt = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_BCC);
-               }
-               i = internet_address_list_length (rcpt);
-               while (i > 0) {
-                       SV * address = newSViv(0);
-                       sv_setref_pv(address, "Mail::Rspamd::InternetAddress", (Mail__Rspamd__InternetAddress)internet_address_list_get_address(rcpt, i));
-                       av_push(retav, address);
-                       -- i;
-               }
-#endif
-               RETVAL = retav;
-       OUTPUT:
-               RETVAL
-
-
-void
-interface_m_set (message, value)
-               Mail::Rspamd::Message   message
-       char *                  value
-       INTERFACE_MACRO:
-       XSINTERFACE_FUNC
-       XSINTERFACE_FUNC_RSPAMD_MESSAGE_SET
-       INTERFACE:
-       set_subject
-       set_message_id
-       set_reply_to
-       set_sender
-
-const char *
-interface_m_get (message)
-               Mail::Rspamd::Message   message
-       INTERFACE_MACRO:
-       XSINTERFACE_FUNC
-       XSINTERFACE_FUNC_RSPAMD_MESSAGE_SET
-       INTERFACE:
-       get_subject
-       get_message_id
-       get_reply_to
-       get_sender
-               
- # date
-void
-rspamd_message_set_date (message, date, gmt_offset)
-               Mail::Rspamd::Message   message
-               time_t          date
-               int             gmt_offset
-       CODE:
-               g_mime_message_set_date (message, date, gmt_offset);
-
-void
-rspamd_message_set_date_from_string (message, str)
-               Mail::Rspamd::Message   message
-               const char *    str
-       PREINIT:
-               time_t          date;
-               int             offset = 0;
-       CODE:
-               date = g_mime_utils_header_decode_date (str, &offset);
-               g_mime_message_set_date (message, date, offset);
-
-
-void
-rspamd_message_get_date (message)
-               Mail::Rspamd::Message   message
-       PREINIT:
-               time_t          date;
-               int             gmt_offset;
-               I32             gimme = GIMME_V;
-               char *          str;
-       PPCODE:
-               if (gimme == G_SCALAR) {
-#ifdef GMIME24
-                       str = g_mime_message_get_date_as_string (message);
-#else
-                       str = g_mime_message_get_date_string (message);
-#endif
-                       if (str) {
-                               XPUSHs (sv_2mortal (newSVpv (str,0)));
-                               g_free (str);
-                       }
-               } else if (gimme == G_ARRAY) {
-                       g_mime_message_get_date (message, &date, &gmt_offset);
-                       XPUSHs (sv_2mortal (newSVnv (date)));
-                       XPUSHs (sv_2mortal (newSViv (gmt_offset)));
-               }
-
-void
-rspamd_message_set_header (message, field, value)
-               Mail::Rspamd::Message   message
-               const char *    field
-               const char *    value
-       CODE:
-#ifdef GMIME24
-               g_mime_object_set_header (GMIME_OBJECT (message), field, value);
-#else
-               g_mime_message_set_header (message, field, value);
-#endif
-               
-void
-rspamd_message_remove_header (message, field)
-               Mail::Rspamd::Message   message
-               const char *    field
-       CODE:
-#ifdef GMIME24
-               g_mime_object_remove_header (GMIME_OBJECT (message), field);
-#else
-               g_mime_message_remove_header (message, field);
-#endif
-       
-
-void
-rspamd_message_add_header (message, field, value)
-               Mail::Rspamd::Message   message
-               const char *    field
-               const char *    value
-       CODE:
-#ifdef GMIME24
-               g_mime_object_set_header (GMIME_OBJECT (message), field, value);
-#else
-               g_mime_message_set_header (message, field, value);
-#endif
-
-const char *
-rspamd_message_get_header (message, field)
-               Mail::Rspamd::Message   message
-               const char *    field
-       CODE:
-#ifdef GMIME24
-               RETVAL = g_mime_object_get_header (GMIME_OBJECT (message), field);
-#else
-               RETVAL = g_mime_message_get_header (message, field);
-#endif
-       OUTPUT:
-               RETVAL
-
-void
-rspamd_message_set_mime_part (message, mime_part)
-               Mail::Rspamd::Message   message
-               Mail::Rspamd::Object    mime_part
-       CODE:
-               g_mime_message_set_mime_part (message, GMIME_OBJECT (mime_part));
-               plist = g_list_remove (plist, mime_part);
-
-#if !defined(GMIME24)
-SV *
-rspamd_message_get_body (message, want_plain = 1, is_html = 0)
-       CASE: items == 1
-               Mail::Rspamd::Message   message
-       PREINIT:
-               gboolean        want_plain = 1;
-               gboolean        is_html;
-       char *          textdata;
-       CODE:
-               textdata = g_mime_message_get_body (message, want_plain, &is_html);
-       if (textdata == NULL)
-         XSRETURN_UNDEF;
-               RETVAL = newSVpv (textdata, 0);
-       g_free (textdata);
-       OUTPUT:
-               RETVAL
-       CASE: items == 2
-               Mail::Rspamd::Message   message
-               gboolean        want_plain
-       PREINIT:
-               gboolean        is_html;
-       char *          textdata;
-       CODE:
-               textdata = g_mime_message_get_body (message, want_plain, &is_html);
-       if (textdata == NULL)
-         XSRETURN_UNDEF;
-               RETVAL = newSVpv (textdata, 0);
-       g_free (textdata);
-       OUTPUT:
-               RETVAL
-       CASE: items == 3
-               Mail::Rspamd::Message   message
-               gboolean        want_plain
-               gboolean        &is_html
-       PREINIT:
-       char *          textdata;
-       CODE:
-               textdata = g_mime_message_get_body (message, want_plain, &is_html);
-               if (textdata == NULL) {
-                       RETVAL = &PL_sv_undef;
-               }
-               RETVAL = newSVpv (textdata, 0);
-               g_free (textdata);
-       OUTPUT:
-               is_html
-               RETVAL
-
-#endif
-               
-SV *
-rspamd_message_get_headers(message)
-               Mail::Rspamd::Message   message
-       PREINIT:
-               char *          textdata;
-       CODE:
-#ifdef GMIME24
-               textdata = g_mime_object_get_headers (GMIME_OBJECT (message));
-#else
-               textdata = g_mime_message_get_headers (message);
-#endif
-               if (textdata == NULL) {
-                       RETVAL = &PL_sv_undef;
-               }
-               RETVAL = newSVpv (textdata, 0);
-               g_free (textdata);
-       OUTPUT:
-               RETVAL
-
-void
-rspamd_message_foreach_part (message, callback, svdata)
-               Mail::Rspamd::Message   message
-               SV *                    callback
-               SV *                    svdata
-       PREINIT:
-               struct _user_data_sv    *data;
-
-       CODE:
-               data = g_new0 (struct _user_data_sv, 1);
-               data->svuser_data = newSVsv (svdata);
-               data->svfunc = newSVsv (callback);
-               g_mime_message_foreach_part (message, call_sub_foreach, data);
-               g_free (data);
-
-SV *
-get_mime_part(message)
-               Mail::Rspamd::Message   message
-       PREINIT:
-               GMimeObject *   mime_object;
-       CODE:
-               if (message->mime_part != NULL) {
-                       RETVAL = newSViv(4);
-                       mime_object = GMIME_OBJECT (message->mime_part);
-                       if (GMIME_IS_PART(mime_object)) {
-                               sv_setref_pv(RETVAL, "Mail::Rspamd::Part", (Mail__Rspamd__Part)mime_object);
-                       } else {
-                               plist = g_list_prepend(plist, RETVAL);
-                       }
-                       g_mime_object_ref( mime_object );
-               } else {
-                       RETVAL = &PL_sv_undef;
-               }
-       OUTPUT:
-               RETVAL
-
diff --git a/perl/Rspamd/Object.xs b/perl/Rspamd/Object.xs
deleted file mode 100644 (file)
index 2f56fb9..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-MODULE = Mail::Rspamd PACKAGE = Mail::Rspamd::Object PREFIX = rspamd_object_
-
-void
-rspamd_object_set_content_type (mime_object, content_type)
-               Mail::Rspamd::Object    mime_object
-               Mail::Rspamd::ContentType       content_type
-       CODE:
-               g_mime_object_set_content_type (mime_object, content_type);
-               plist = g_list_remove (plist, content_type);
-
-Mail::Rspamd::ContentType
-rspamd_object_get_content_type (mime_object)
-               Mail::Rspamd::Object    mime_object
-       PREINIT:
-               char *                  textdata;
-               GMimeContentType        *ct;
-       CODE:
-               ct = (GMimeContentType *)g_mime_object_get_content_type (mime_object);
-               textdata = g_mime_content_type_to_string (ct);
-               RETVAL = g_mime_content_type_new_from_string (textdata);
-               plist = g_list_prepend (plist, RETVAL);
-               g_free (textdata);
-       OUTPUT:
-               RETVAL
-
-void
-rspamd_object_set_content_type_parameter (mime_object, name, value)
-               Mail::Rspamd::Object    mime_object
-               const char *            name
-               const char *            value
-       CODE:
-               gmime_object_set_content_type_parameter (mime_object, name, value);
-
-const char *
-rspamd_object_get_content_type_parameter (mime_object, name)
-               Mail::Rspamd::Object    mime_object
-               const char *            name
-       CODE:
-               RETVAL = g_mime_object_get_content_type_parameter (mime_object, name);
-       OUTPUT:
-               RETVAL
-
-void
-rspamd_object_set_content_id (mime_object, content_id)
-               Mail::Rspamd::Object    mime_object
-               const char *            content_id
-       CODE:
-               g_mime_object_set_content_id (mime_object, content_id);
-
-const char *
-rspamd_object_get_content_id(mime_object)
-               Mail::Rspamd::Object    mime_object
-       CODE:
-               RETVAL = g_mime_object_get_content_id (mime_object);
-       OUTPUT:
-               RETVAL
-
-
-void
-rspamd_object_add_header (mime_object, field, value)
-               Mail::Rspamd::Object    mime_object
-               const char *    field
-               const char *    value
-       CODE:
-               g_mime_object_add_header (mime_object, field, value);
-
-void
-rspamd_object_set_header (mime_object, field, value)
-               Mail::Rspamd::Object    mime_object
-               const char *    field
-               const char *    value
-       CODE:
-               g_mime_object_set_header (mime_object, field, value);
-
-const char *
-rspamd_object_get_header (mime_object, field)
-               Mail::Rspamd::Object    mime_object
-               const char *    field
-       CODE:
-               RETVAL = g_mime_object_get_header (mime_object, field);
-       OUTPUT:
-               RETVAL
-
-void
-rspamd_object_remove_header (mime_object, field)
-               Mail::Rspamd::Object    mime_object
-               const char *    field
-       CODE:
-               g_mime_object_remove_header (mime_object, field);
-
-SV *
-rspamd_object_get_headers(mime_object)
-               Mail::Rspamd::Object    mime_object
-       PREINIT:
-               char *          textdata;
-       CODE:
-               textdata = g_mime_object_get_headers(mime_object);
-               if (textdata == NULL) {
-                       XSRETURN_UNDEF;
-               }
-               RETVAL = newSVpv (textdata, 0);
-               g_free (textdata);
-       OUTPUT:
-               RETVAL
-
-SV *
-rspamd_object_to_string(mime_object)
-               Mail::Rspamd::Object    mime_object
-       PREINIT:
-               char *  textdata;
-       CODE:
-               textdata = g_mime_object_to_string (mime_object);
-               if (textdata) {
-                       RETVAL = newSVpv (textdata, 0);
-                       g_free (textdata);
-               } else {
-                       XSRETURN_UNDEF;
-               }
-       OUTPUT:
-               RETVAL
-
-guint
-rspamd_object_get_content_length(mime_object)
-               Mail::Rspamd::Object    mime_object
-       PREINIT:
-               guint                   lsize = 0;
-               GMimePart *             mime_part;
-       CODE:
-               if (mime_object) {
-                       if (GMIME_IS_PART(mime_object)) { // also MESSAGE_PARTIAL
-                               mime_part = GMIME_PART(mime_object);
-                               lsize = (mime_part->content && mime_part->content->stream) ?
-                                                       g_mime_stream_length (mime_part->content->stream) : 0; 
-                               if (lsize) {
-#ifdef GMIME24
-                                       GMimeContentEncoding enc;
-
-                                       enc = _mime_part_get_encoding (mime_part);
-                                       switch (enc) {
-                                               case GMIME_CONTENT_ENCODING_BASE64:
-                                                       lsize = BASE64_ENCODE_LEN (lsize);
-                                                       break;
-                                               case GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE:
-                                                       lsize = QP_ENCODE_LEN (lsize);
-                                                       break;
-                                       }
-#else
-                                       GMimePartEncodingType   enc;
-
-                                       enc = g_mime_part_get_encoding (mime_part);
-                                       switch (enc) {
-                                               case GMIME_PART_ENCODING_BASE64:
-                                                       lsize = BASE64_ENCODE_LEN (lsize);
-                                                       break;
-                                               case GMIME_PART_ENCODING_QUOTEDPRINTABLE:
-                                                       lsize = QP_ENCODE_LEN (lsize);
-                                                       break;
-                                       }
-#endif                         
-                               }
-                       }
-               }
-               RETVAL = lsize;
-       OUTPUT:
-               RETVAL
-
diff --git a/perl/Rspamd/Part.xs b/perl/Rspamd/Part.xs
deleted file mode 100644 (file)
index 5401a1e..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-MODULE = Mail::Rspamd PACKAGE = Mail::Rspamd::Part PREFIX = rspamd_part
-
-Mail::Rspamd::Part
-g_mime_part_new (Class = "Mail::Rspamd::Part", type = "text", subtype = "plain")
-               char *          Class;
-               const char *            type;
-               const char *            subtype;
-       CODE:
-               RETVAL = g_mime_part_new_with_type (type, subtype);
-               plist = g_list_prepend (plist, RETVAL);
-       OUTPUT:
-               RETVAL
-
-void
-DESTROY (mime_part)
-               Mail::Rspamd::Part      mime_part
-       CODE:
-               if (g_list_find (plist,mime_part)) {
-                       g_object_unref (G_OBJECT (mime_part));
-                       plist = g_list_remove (plist, mime_part);
-               }
-
-void
-interface_p_set(mime_part, value)
-       Mail::Rspamd::Part      mime_part
-       char *                          value
-       INTERFACE_MACRO:
-       XSINTERFACE_FUNC
-       XSINTERFACE_FUNC_RSPAMD_PART_SET
-       INTERFACE:
-       set_content_description
-       set_content_md5
-       set_content_location
-       set_filename
-
-
-const char *
-interface_p_get(mime_part)
-       Mail::Rspamd::Part      mime_part
-       INTERFACE_MACRO:
-       XSINTERFACE_FUNC
-       XSINTERFACE_FUNC_RSPAMD_PART_SET
-       INTERFACE:
-       get_content_description
-       get_content_md5
-       get_content_location
-       get_filename
-
-#if !defined(GMIME24)
-
-void
-rspamd_part_set_content_header (mime_part, field, value)
-               Mail::Rspamd::Part      mime_part
-               const char *            field
-               const char *            value
-       CODE:
-               g_mime_part_set_content_header (mime_part, field, value);
-
-const char *
-rspamd_part_get_content_header (mime_part, field)
-               Mail::Rspamd::Part      mime_part
-               const char *            field
-       CODE:
-               RETVAL = g_mime_part_get_content_header (mime_part, field);
-       OUTPUT:
-               RETVAL
-
-#endif
-
-void
-rspamd_part_set_content_type (mime_part, content_type)
-               Mail::Rspamd::Part              mime_part
-               Mail::Rspamd::ContentType       content_type
-       CODE:
-               g_mime_part_set_content_type (mime_part, content_type);
-               plist = g_list_remove (plist, content_type);
-
-
-void
-rspamd_part_set_encoding (mime_part, encoding)
-               Mail::Rspamd::Part                      mime_part
-               Mail::Rspamd::PartEncodingType          encoding
-       CODE:
-               g_mime_part_set_encoding (mime_part, encoding);
-
-Mail::Rspamd::PartEncodingType
-rspamd_part_get_encoding (mime_part)
-               Mail::Rspamd::Part      mime_part
-       CODE:
-               RETVAL = g_mime_part_get_encoding (mime_part);
-       OUTPUT:
-               RETVAL
-
-const char *
-rspamd_part_encoding_to_string (encoding)
-               Mail::Rspamd::PartEncodingType          encoding
-       PREINIT:
-       CODE:
-#ifdef GMIME24
-               RETVAL = g_mime_content_encoding_to_string (encoding);
-#else
-               RETVAL = g_mime_part_encoding_to_string (encoding);
-#endif
-       OUTPUT:
-               RETVAL
-
-Mail::Rspamd::PartEncodingType
-rspamd_part_encoding_from_string (encoding)
-               const char *            encoding
-       CODE:
-#ifdef GMIME24
-               RETVAL = g_mime_content_encoding_from_string (encoding);
-#else
-               RETVAL = g_mime_part_encoding_from_string (encoding);
-#endif
-       OUTPUT:
-               RETVAL
-
-void
-rspamd_part_add_content_disposition_parameter (mime_part, name, value)
-               Mail::Rspamd::Part      mime_part
-               const char *            name
-               const char *            value
-       CODE:
-#ifdef GMIME24
-               g_mime_object_add_content_disposition_parameter (GMIME_OBJECT (mime_part), name, value);
-#else
-               g_mime_part_add_content_disposition_parameter (mime_part, name, value);
-#endif
-
-const char *
-rspamd_part_get_content_disposition_parameter (mime_part, name)
-               Mail::Rspamd::Part      mime_part
-               const char *            name
-       CODE:
-#ifdef GMIME24
-               RETVAL = g_mime_object_get_content_disposition_parameter (GMIME_OBJECT (mime_part), name);
-#else
-               RETVAL = g_mime_part_get_content_disposition_parameter (mime_part, name);
-#endif
-       OUTPUT:
-               RETVAL
-
-
-void
-rspamd_part_set_pre_encoded_content(mime_part, content, encoding)
-               Mail::Rspamd::Part      mime_part
-               SV *            content
-               Mail::Rspamd::PartEncodingType  encoding
-       PREINIT:
-               char *  data;
-               STRLEN  len;
-       CODE:
-               data = SvPV (content, len);
-               g_mime_part_set_pre_encoded_content (mime_part, data, len, encoding);
-
-
-SV *
-rspamd_part_get_content(mime_part)
-               Mail::Rspamd::Part      mime_part
-       PREINIT:
-#ifdef GMIME24
-               GMimeDataWrapper *wrapper;
-        GMimeStream *part_stream;
-        GByteArray *part_content;
-#else
-               guint len;
-               const char * content_char;
-#endif
-               SV * content;
-       CODE:
-               ST(0) = &PL_sv_undef;
-#ifdef GMIME24
-               if (!(mime_part->content) || !(mime_part->content->stream) ||
-                        (wrapper = g_mime_part_get_content_object (mime_part)) == NULL) {
-#else
-               if (!(mime_part->content) || !(mime_part->content->stream) ||
-                        (content_char = g_mime_part_get_content (mime_part, &len)) == NULL) {
-#endif
-                       return;
-               }
-               content = sv_newmortal ();
-               SvUPGRADE (content, SVt_PV);
-               SvREADONLY_on (content);
-#ifdef GMIME24
-               part_stream = g_mime_stream_mem_new ();
-               g_mime_data_wrapper_write_to_stream (wrapper, part_stream);
-               part_content = g_mime_stream_mem_get_byte_array (GMIME_STREAM_MEM (part_stream));
-               SvPVX(content) = (char *) (part_content->data);
-               SvCUR_set (content, part_content->len);
-#else
-               SvPVX(content) = (char *) (content_char);
-               SvCUR_set (content, len);
-#endif
-               SvLEN_set (content, 0);
-               SvPOK_only (content);
-               ST(0) = content;
-
diff --git a/perl/Rspamd/Task.xs b/perl/Rspamd/Task.xs
deleted file mode 100644 (file)
index e46a114..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-
-MODULE = Mail::Rspamd   PACKAGE = Mail::Rspamd::Task PREFIX = rspamd_task_
-PROTOTYPES: DISABLE
-
-Mail::Rspamd::Message
-rspamd_task_get_message (task)
-               Mail::Rspamd::Task task
-       CODE:
-               RETVAL = task->message;
-       OUTPUT:
-               RETVAL
-
-void
-rspamd_task_set_message (message)
-               Mail::Rspamd::Message message
-       CODE:
-               g_object_unref (G_OBJECT(task->message));
-               task->message = message;
-
-SV*
-rspamd_task_ip (task)
-               Mail::Rspamd::Task task
-       CODE:   
-               RETVAL = newSVpv (inet_ntoa (task->from_addr), 0);
-       OUTPUT:
-               RETVAL
-
-SV*
-rspamd_task_from (task)
-               Mail::Rspamd::Task task
-       CODE:
-               if (task->from == NULL) {
-                       XSRETURN_UNDEF;
-               }
-               RETVAL = newSVpv (task->from, 0);
-       OUTPUT:
-               RETVAL
-
-void
-rspamd_task_save_point (task)
-               Mail::Rspamd::Task task
-    CODE:
-       task->save.saved = 1;
-
-void
-rspamd_task_recall_filter (task)
-               Mail::Rspamd::Task task
-    CODE:
-       process_filters (task);
-
-void
-rspamd_task_insert_result (task, metric, symbol, flag)
-               Mail::Rspamd::Task task
-               const char *metric
-               const char *symbol
-               double flag
-       CODE:
-               insert_result (task, metric, symbol, flag, NULL);
-
-Mail::Rspamd::Conf
-rspamd_task_get_conf (task)
-               Mail::Rspamd::Task task
-       CODE:
-               RETVAL = task->cfg;
-       OUTPUT:
-               RETVAL
-
-AV*
-rspamd_task_get_urls (task)
-               Mail::Rspamd::Task task
-       PREINIT:
-               AV* retav;
-               struct uri *url;
-       CODE:
-               retav = newAV ();
-               TAILQ_FOREACH (url, &task->urls, next) {
-                       av_push (retav, newSVpv ((char *)g_strdup (struri (url)), 0));
-               }
-
-               RETVAL = retav;
-       OUTPUT:
-               RETVAL
-
-AV*
-rspamd_task_get_text_parts (task)
-               Mail::Rspamd::Task task
-       PREINIT:
-               AV* retav;
-               GList *cur;
-               SV* ps;
-       CODE:
-               retav = newAV ();
-               cur = g_list_first (task->text_parts);
-               while (cur) {
-                       ps = newSViv (0);
-                       sv_setref_pv (ps, "Mail::Rspamd::TextPart", (Mail__Rspamd__TextPart)(cur->data));
-                       av_push(retav, ps);
-                       cur = g_list_next (task->text_parts);
-               }
-
-               RETVAL = retav;
-       OUTPUT:
-               RETVAL
-
diff --git a/perl/Rspamd/TextPart.xs b/perl/Rspamd/TextPart.xs
deleted file mode 100644 (file)
index 485ee7b..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-MODULE = Mail::Rspamd PACKAGE = Mail::Rspamd::TextPart PREFIX = rspamd_text_part_
-
-SV *
-rspamd_text_part_get_content (mime_part)
-               Mail::Rspamd::TextPart  mime_part
-       PREINIT:
-               SV* content;
-       CODE:
-               ST(0) = &PL_sv_undef;
-               content = sv_newmortal ();
-               SvUPGRADE (content, SVt_PV);
-               SvREADONLY_on (content);
-               SvPVX(content) = (char *) (mime_part->content->data);
-               SvCUR_set (content, mime_part->content->len);
-               SvLEN_set (content, 0);
-               SvPOK_only (content);
-               ST(0) = content;
-
-char *
-rspamd_text_part_get_fuzzy (mime_part)
-               Mail::Rspamd::TextPart  mime_part
-       CODE:
-               RETVAL = mime_part->fuzzy->hash_pipe;
-
-int
-rspamd_text_part_compare_distance (mime_part, other)
-               Mail::Rspamd::TextPart  mime_part
-               Mail::Rspamd::TextPart  other
-       CODE:
-               RETVAL = fuzzy_compare_hashes (mime_part->fuzzy, other->fuzzy);
-       OUTPUT:
-               RETVAL
-
-int
-rspamd_text_part_is_html (mime_part)
-               Mail::Rspamd::TextPart  mime_part
-       CODE:
-               RETVAL = mime_part->is_html;
-       OUTPUT:
-               RETVAL
diff --git a/perl/lib/Mail/Rspamd/Client.pm b/perl/lib/Mail/Rspamd/Client.pm
new file mode 100644 (file)
index 0000000..bb405a7
--- /dev/null
@@ -0,0 +1,470 @@
+
+=head1 NAME
+
+Mail::Rspamd::Client - Client for rspamd Protocol
+
+
+=head1 SYNOPSIS
+
+  my $client = new Mail::Rspamd::Client({port => 11333,
+                                               host => 'localhost',
+                                               ip => '127.0.0.1'});
+
+  if ($client->ping()) {
+    print "Ping is ok\n";
+  }
+
+  my $result = $client->check($testmsg);
+
+  if ($result->{'default'}->{isspam} eq 'True') {
+    do something with spam message here
+  }
+
+=head1 DESCRIPTION
+
+Mail::Rspamd::Client is a module that provides a perl implementation for
+the spamd protocol.
+
+=cut
+
+package Mail::Rspamd::Client;
+
+use IO::Socket;
+use IO::Select;
+
+use vars qw($VERSION);
+$VERSION = "1.00";
+
+my $EOL = "\015\012";
+my $BLANK = $EOL x 2;
+my $PROTOVERSION = 'RSPAMC/1.0';
+
+=head1 PUBLIC METHODS
+
+=head2 new
+
+public class (Mail::Rspamd::Client) new (\% $args)
+
+Description:
+This method creates a new Mail::Rspamd::Client object.
+
+=cut
+
+sub new {
+  my ($class, $args) = @_;
+
+  $class = ref($class) || $class;
+
+  my $self = {};
+
+  # with a sockets_path set then it makes no sense to set host and port
+  if ($args->{socketpath}) {
+    $self->{socketpath} = $args->{socketpath};
+  }
+  else {
+    $self->{hosts} = $args->{hosts};
+    $self->{alive_hosts} = $self->{hosts};
+  }
+
+  if ($args->{username}) {
+    $self->{username} = $args->{username};
+  }
+  if ($args->{ip}) {
+    $self->{ip} = $args->{ip};
+  }
+  if ($args->{from}) {
+    $self->{from} = $args->{from};
+  }
+  if ($args->{subject}) {
+    $self->{subject} = $args->{subject};
+  }
+  if ($args->{rcpt}) {
+    $self->{rcpt} = $args->{rcpt};
+  }
+  if ($args->{timeout}) {
+    $self->{timeout} = $args->{timeout};
+  }
+  else {
+    $self->{timeout} = 5;
+  }
+  if ($args->{password}) {
+    $self->{password} = $args->{password};
+  }
+
+  bless($self, $class);
+
+  $self;
+}
+
+=head2 check
+
+public instance (\%) check (String $msg)
+
+Description:
+This method makes a call to the spamd server and depending on the value of
+C<$is_check_p> either calls PROCESS or CHECK.
+
+The return value is a hash reference containing metrics indexed by name. Each metric
+is hash that contains data:
+
+isspam
+
+score
+
+threshold
+
+symbols - array of symbols
+
+=cut
+
+sub check {
+  my ($self, $msg) = @_;
+
+  my %metrics;
+
+  my $command = 'SYMBOLS';
+
+  $self->_clear_errors();
+
+  my $remote = $self->_create_connection();
+
+  return 0 unless ($remote);
+
+  my $msgsize = length($msg.$EOL);
+
+  local $SIG{PIPE} = 'IGNORE';
+
+  if (!(syswrite($remote, "$command $PROTOVERSION$EOL"))) {
+    $self->_mark_dead($remote);
+    return 0;
+  }
+  syswrite $remote, "Content-length: $msgsize$EOL";
+  syswrite $remote, "User: $self->{username}$EOL" if ($self->{username});
+  syswrite $remote, "From: $self->{from}$EOL" if ($self->{from});
+  syswrite $remote, "IP: $self->{ip}$EOL" if ($self->{ip});
+  syswrite $remote, "Subject: $self->{subject}$EOL" if ($self->{subject});
+  if (ref $self->{rcpt} eq "ARRAY") {
+    foreach ($self->{rcpt}) {
+      syswrite $remote, "Rcpt: $_ $EOL";
+    }
+  }
+  syswrite $remote, $EOL;
+  syswrite $remote, $msg;
+  syswrite $remote, $EOL;
+  
+  return undef unless $self->_get_io_readiness($remote, 0);
+               
+  my $in;
+  return undef unless sysread($remote, $in, 512);
+
+  my ($version, $resp_code, $resp_msg) = $self->_parse_response_line($in);
+
+  $self->{resp_code} = $resp_code;
+  $self->{resp_msg} = $resp_msg;
+
+  return undef unless ($resp_code == 0);
+
+  my $cur_metric;
+  my @lines = split (/^/, $in);
+  foreach my $line (@lines) {
+    if ($line =~ m!Metric: (\S+); (\S+); (\S+) / (\S+)!) {
+      $metrics{$1} = {
+        isspam => $2,
+        score => $3 + 0,
+        threshold => $4 + 0,
+        symbols => [],
+      };
+      $cur_metric = $1;
+    }
+    elsif ($line =~ /^Symbol: (\S+)/ && $cur_metric) {
+      my $symref = $metrics{$cur_metric}->{'symbols'};
+      push(@$symref, $1);
+    }
+    elsif ($line =~ /^${EOL}$/) {
+      last;
+    }
+  }
+
+  close $remote;
+
+  return \%metrics;
+}
+
+sub _auth {
+  my ($self, $sock) = @_;
+
+  local $SIG{PIPE} = 'IGNORE';
+
+  if (!(syswrite($sock, "PASSWORD $self->{password}$EOL"))) {
+    $self->_mark_dead($remote);
+    return 0;
+  }
+
+  return 0 unless $self->_get_io_readiness($sock, 0);
+
+  if (sysread($sock, $reply, 255)) {
+    if ($reply =~ /^password accepted/) {
+      return 1;
+    }
+  }
+
+  return 0;
+  
+}
+
+=head2 learn
+
+public instance (\%) check (String $msg, String $statfile, Boolean in_class)
+
+Description:
+This method makes a call to the spamd learning a statfile with message.
+
+=cut
+
+sub learn {
+  my ($self, $msg, $statfile, $in_class) = @_;
+
+  my %metrics;
+
+  my $command = 'LEARN';
+
+  $self->_clear_errors();
+
+  my $remote = $self->_create_connection();
+
+  return 0 unless ($remote);
+
+  return 0 unless $self->_auth($remote);
+
+  my $msgsize = length($msg.$EOL);
+
+  local $SIG{PIPE} = 'IGNORE';
+
+  if (!(syswrite ($remote, "$command $statfile $msgsize$EOL"))) {
+    $self->_mark_dead($remote);
+    return 0;
+  }
+
+  syswrite($remote, $msg);
+  syswrite($remote, $EOL);
+  
+  return undef unless $self->_get_io_readiness($remote, 0);
+  if (sysread ($remote, $reply, 255)) {
+    if ($reply =~ /^learn ok/) {
+      close $remote;
+      return 1;
+    }
+  }
+
+  close $remote;
+  return 0;
+}
+
+=head2 ping
+
+public instance (Boolean) ping ()
+
+Description:
+This method performs a server ping and returns 0 or 1 depending on
+if the server responded correctly.
+
+=cut
+
+sub ping {
+  my ($self) = @_;
+
+  my $remote = $self->_create_connection();
+
+  return 0 unless ($remote);
+  local $SIG{PIPE} = 'IGNORE';
+
+  if (!(syswrite($remote, "PING $PROTOVERSION$EOL"))) {
+    $self->_mark_dead($remote);
+    return 0;
+  }
+  syswrite($remote, $EOL);
+
+  return undef unless $self->_get_io_readiness($remote, 0);
+       my $line;
+  sysread ($remote, $line, 255);
+  close $remote;
+  return undef unless $line;
+
+  my ($version, $resp_code, $resp_msg) = $self->_parse_response_line($line);
+  return 0 unless ($resp_msg eq 'PONG');
+
+  return 1;
+}
+
+=head1 PRIVATE METHODS
+
+=head2 _create_connection
+
+private instance (IO::Socket) _create_connection ()
+
+Description:
+This method sets up a proper IO::Socket connection based on the arguments
+used when greating the client object.
+
+On failure, it sets an internal error code and returns undef.
+
+=cut
+
+sub _create_connection {
+  my ($self) = @_;
+
+  my $remote;
+  my $tries = 0;
+
+  if ($self->{socketpath}) {
+    $remote = IO::Socket::UNIX->new( Peer => $self->{socketpath},
+                                    Type => SOCK_STREAM,
+             Blocking  => 0,
+                                  );
+    # Get write readiness
+    if ($self->_get_io_readiness($remote, 1) == 0) {
+      print "Connection timed out: $!\n";
+      return undef;
+    }
+  }
+  else {
+    my $server;
+
+    do {
+      $server = $self->_select_server();
+      $tries ++;
+
+      $remote = IO::Socket::INET->new( Proto     => "tcp",
+                PeerAddr  => $server->{host},
+                PeerPort  => $server->{port},
+                Blocking  => 0,
+              );
+      # Get write readiness
+      if ($self->_get_io_readiness($remote, 1) != 0) {
+        return $remote;
+      }
+      else {
+        next;
+      }
+    } while ($tries < 5);
+
+    return undef unless $server;
+  }
+  unless ($remote) {
+    print "Failed to create connection to spamd daemon: $!\n";
+    return undef;
+  }
+  $remote;
+}
+
+sub _revive_dead {
+  my ($self) = @_;
+
+  my $now = time();
+  foreach my $s ($self->{dead_hosts}) {
+    # revive after minute of downtime
+    if (defined($s->{dead}) && $s->{dead} == 1 && $now - $s->{t} > 60) {
+      $s->{dead} = 0;
+      push(@{$self->{alive_hosts}}, $s->{host});
+    }
+  }
+
+  1;
+}
+
+sub _select_server {
+  my($self) = @_;
+    
+  $self->_revive_dead();
+  my $alive_num = scalar(@{$self->{alive_hosts}});
+  if (!$alive_num) {
+    $self->{alive_hosts} = $self->{hosts};
+    $self->{dead_hosts} = ();
+    $alive_num = scalar($self->{alive_hosts});
+  }
+  
+  my $selected = $self->{alive_hosts}[int(rand($alive_num))];
+  if ($selected =~ /^(\S+):(\d+)$/) {
+    my $server = {
+        host => $1,
+        port => $2,
+    };
+    return $server;
+  }
+
+  undef;
+}
+
+
+sub _mark_dead {
+  my ($self, $server) = @_;
+  
+  my $now = time();
+  $self->{dead_hosts}->{$server} = {
+    host => $server,
+    dead => 1,
+    t => $now,
+  };
+  for (my $i = 0; $i < scalar (@{$self->{alive_hosts}}); $i ++) {
+    if ($self->{alive_hosts} == $server) {
+      splice(@{$self->{alive_hosts}}, $i, 1);
+      last;
+    }
+  }
+}
+
+sub _get_io_readiness {
+  my ($self, $sock, $is_write) = @_;
+  my $s = IO::Select->new();
+  $s->add($sock);
+
+  if ($is_write) {
+    @ready = $s->can_write($self->{timeout});
+  }
+  else {
+    @ready = $s->can_read($self->{timeout});
+  }
+  
+
+  scalar(@ready);
+}
+
+=head2 _parse_response_line
+
+private instance (@) _parse_response_line (String $line)
+
+Description:
+This method parses the initial response line/header from the server
+and returns its parts.
+
+We have this as a seperate method in case we ever decide to get fancy
+with the response line.
+
+=cut
+
+sub _parse_response_line {
+  my ($self, $line) = @_;
+
+  $line =~ s/\r?\n$//;
+  return split(/\s+/, $line, 3);
+}
+
+=head2 _clear_errors
+
+private instance () _clear_errors ()
+
+Description:
+This method clears out any current errors.
+
+=cut
+
+sub _clear_errors {
+  my ($self) = @_;
+
+  $self->{resp_code} = undef;
+  $self->{resp_msg} = undef;
+}
+
+1;
+
+
diff --git a/perl/typemap b/perl/typemap
deleted file mode 100644 (file)
index 0ae0ef7..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-TYPEMAP
-
-gint                           T_IV
-guint                          T_UV
-guint32                                T_UV
-off_t                          T_IV
-gboolean                       T_BOOL
-gpointer                       T_PTR
-
-unsigned char *                        T_PV
-const unsigned char *          T_PV
-const char *                   T_PV
-
-# enums
-Mail::Rspamd::PartEncodingType         T_IV
-Mail::Rspamd::InternetAddressType              T_IV
-
-# types
-Mail::Rspamd::Object                   T_PTROBJ
-Mail::Rspamd::Param                    T_PTROBJ
-Mail::Rspamd::Message                  T_PTROBJ
-Mail::Rspamd::Part                     T_PTROBJ
-Mail::Rspamd::TextPart         T_PTROBJ
-Mail::Rspamd::ContentType                      T_PTROBJ
-Mail::Rspamd::InternetAddress          T_PTROBJ
-Mail::Rspamd::Hash::Header             T_PTROBJ
-
-const Mail::Rspamd::Part::EncodingType T_IV