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)
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)
# 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
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")
+++ /dev/null
-
-=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;
-
-
--- /dev/null
+Makefile.PL
+MANIFEST
+lib/Mail/Rspamd/Client.pm
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
);
+++ /dev/null
-=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/
+++ /dev/null
-/*
- * 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
-
-
+++ /dev/null
-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
-
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
-
+++ /dev/null
-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
-
+++ /dev/null
-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
-
+++ /dev/null
-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;
-
+++ /dev/null
-
-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
-
+++ /dev/null
-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
--- /dev/null
+
+=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;
+
+
+++ /dev/null
-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