summaryrefslogtreecommitdiffstats
path: root/perl
diff options
context:
space:
mode:
Diffstat (limited to 'perl')
-rw-r--r--perl/Makefile.PL.in16
-rw-r--r--perl/Rspamd.pm (renamed from perl/rspamd.pm)4
-rw-r--r--perl/Rspamd.pod562
-rw-r--r--perl/Rspamd.xs324
-rw-r--r--perl/Rspamd/Config.xs141
-rw-r--r--perl/Rspamd/ContentType.xs87
-rw-r--r--perl/Rspamd/Hash.xs258
-rw-r--r--perl/Rspamd/InternetAddress.xs124
-rw-r--r--perl/Rspamd/Message.xs264
-rw-r--r--perl/Rspamd/Object.xs152
-rw-r--r--perl/Rspamd/Part.xs160
-rw-r--r--perl/Rspamd/Task.xs83
-rw-r--r--perl/rspamd.xs501
-rw-r--r--perl/typemap27
14 files changed, 2196 insertions, 507 deletions
diff --git a/perl/Makefile.PL.in b/perl/Makefile.PL.in
index 502e84227..0d70d4270 100644
--- a/perl/Makefile.PL.in
+++ b/perl/Makefile.PL.in
@@ -1,9 +1,21 @@
use ExtUtils::MakeMaker;
WriteMakefile(
- NAME => 'rspamd',
- VERSION_FROM => 'rspamd.pm', # finds $VERSION
+ NAME => 'Mail::Rspamd',
+ AUTHOR => 'Vsevolod Stakhov <vsevolod@rambler-co.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
+},
+ },
);
diff --git a/perl/rspamd.pm b/perl/Rspamd.pm
index 6048f1a3f..2966cb3ca 100644
--- a/perl/rspamd.pm
+++ b/perl/Rspamd.pm
@@ -1,4 +1,4 @@
-package rspamd;
+package Mail::Rspamd;
use 5.006001;
use strict;
@@ -20,7 +20,7 @@ our @EXPORT = qw(
our $VERSION = '0.0.1';
require XSLoader;
-XSLoader::load('rspamd', $VERSION);
+XSLoader::load('Rspamd', $VERSION);
sub module_init {
my ($cfg) = @_;
diff --git a/perl/Rspamd.pod b/perl/Rspamd.pod
new file mode 100644
index 000000000..d40574820
--- /dev/null
+++ b/perl/Rspamd.pod
@@ -0,0 +1,562 @@
+=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 L<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.
+
+=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:
+{
+'name' => name of metric
+'func_name' => consolidation function
+'required_score' => score for metric
+}
+
+=item I<get_statfile> (statfile)
+
+Returns parameters of specified statfile:
+{
+'alias' => alias of statfile
+'pattern' => fs pattern
+'metric' => metric of statfile
+'weight' => weigth of statfile
+'size' => size of statfile
+}
+
+=item I<get_module_param> (modulename, paramname)
+
+Return parameter's value for specified module.
+
+=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
new file mode 100644
index 000000000..c6c33c007
--- /dev/null
+++ b/perl/Rspamd.xs
@@ -0,0 +1,324 @@
+/*
+ * 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"
+
+#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 */
+typedef GMimePartEncodingType Mail__Rspamd__PartEncodingType;
+typedef InternetAddressType Mail__Rspamd__InternetAddressType;
+
+/* C types */
+typedef GMimeObject * Mail__Rspamd__Object;
+typedef GMimeParam * Mail__Rspamd__Param;
+typedef GMimePart * Mail__Rspamd__Part;
+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;
+typedef GMimeDisposition * Mail__Rspamd__Disposition;
+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);
+ }
+}
+/* known header field types */
+enum {
+ HEADER_FROM = 0,
+ HEADER_REPLY_TO,
+ HEADER_TO,
+ HEADER_CC,
+ HEADER_BCC,
+ HEADER_SUBJECT,
+ HEADER_DATE,
+ HEADER_MESSAGE_ID,
+ HEADER_UNKNOWN
+};
+
+static GList *
+local_message_get_header(GMimeMessage *message, const char *field)
+{
+ struct raw_header *h;
+ GList * gret = NULL;
+
+ if (field == NULL) {
+ return NULL;
+ }
+ h = GMIME_OBJECT(message)->headers->headers;
+ while (h) {
+ if (h->value && !g_strncasecmp(field, h->name, strlen(field))) {
+ gret = g_list_prepend(gret, g_strdup(h->value));
+ }
+ h = h->next;
+ }
+ return gret;
+}
+
+/**
+* g_mime_message_set_date_from_string: Set the message sent-date
+* @message: MIME Message
+* @string: A string of date
+*
+* Set the sent-date on a MIME Message.
+**/
+static void
+local_mime_message_set_date_from_string (GMimeMessage *message, const gchar *string)
+{
+ time_t date;
+ int offset = 0;
+
+ date = g_mime_utils_header_decode_date (string, &offset);
+ g_mime_message_set_date (message, date, offset);
+}
+
+
+
+/* different declarations for different types of set and get functions */
+typedef const char *(*GetFunc) (GMimeMessage *message);
+typedef InternetAddressList *(*GetRcptFunc) (GMimeMessage *message, const char *type );
+typedef GList *(*GetListFunc) (GMimeMessage *message, const char *type );
+typedef void (*SetFunc) (GMimeMessage *message, const char *value);
+typedef void (*SetListFunc) (GMimeMessage *message, const char *field, const char *value);
+
+/** different types of functions
+*
+* FUNC_CHARPTR
+* - function with no arguments
+* - get returns char*
+*
+* FUNC_IA (from Internet Address)
+* - function with additional "field" argument from the fieldfunc table,
+* - get returns Glist*
+*
+* FUNC_LIST
+* - function with additional "field" argument (given arbitrary header field name)
+* - get returns Glist*
+**/
+enum {
+ FUNC_CHARPTR = 0,
+ FUNC_CHARFREEPTR,
+ FUNC_IA,
+ FUNC_LIST
+};
+
+/**
+* fieldfunc struct: structure of MIME fields and corresponding get and set
+* functions.
+**/
+static struct {
+ char * name;
+ GetFunc func;
+ GetRcptFunc rcptfunc;
+ GetListFunc getlistfunc;
+ SetFunc setfunc;
+ SetListFunc setlfunc;
+ gint functype;
+} fieldfunc[] = {
+ { "From", g_mime_message_get_sender, NULL, NULL, g_mime_message_set_sender, NULL, FUNC_CHARPTR },
+ { "Reply-To", g_mime_message_get_reply_to, NULL, NULL, g_mime_message_set_reply_to, NULL, FUNC_CHARPTR },
+ { "To", NULL, g_mime_message_get_recipients, NULL, NULL, g_mime_message_add_recipients_from_string, FUNC_IA },
+ { "Cc", NULL, g_mime_message_get_recipients, NULL, NULL, g_mime_message_add_recipients_from_string, FUNC_IA },
+ { "Bcc", NULL, g_mime_message_get_recipients, NULL, NULL, g_mime_message_add_recipients_from_string, FUNC_IA },
+ { "Subject", g_mime_message_get_subject, NULL, NULL, g_mime_message_set_subject, NULL, FUNC_CHARPTR },
+ { "Date", g_mime_message_get_date_string, NULL, NULL, local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR },
+ { "Message-Id", g_mime_message_get_message_id, NULL, NULL, g_mime_message_set_message_id, NULL, FUNC_CHARPTR },
+ { NULL, NULL, NULL, local_message_get_header, NULL, g_mime_message_add_header, FUNC_LIST }
+};
+
+/**
+* message_set_header: set header of any type excluding special (Content- and MIME-Version:)
+**/
+static void
+message_set_header (GMimeMessage *message, const char *field, const char *value)
+{
+ gint i;
+
+
+ if (!g_strcasecmp (field, "MIME-Version:") || !g_strncasecmp (field, "Content-", 8)) {
+ return;
+ }
+ for (i=0; i<=HEADER_UNKNOWN; ++i) {
+ if (!fieldfunc[i].name || !g_strncasecmp(field, fieldfunc[i].name, strlen(fieldfunc[i].name))) {
+ switch (fieldfunc[i].functype) {
+ case FUNC_CHARPTR:
+ (*(fieldfunc[i].setfunc))(message, value);
+ break;
+ case FUNC_IA:
+ (*(fieldfunc[i].setlfunc))(message, fieldfunc[i].name, value);
+ break;
+ case FUNC_LIST:
+ (*(fieldfunc[i].setlfunc))(message, field, value);
+ break;
+ }
+ break;
+ }
+ }
+}
+
+
+/**
+* message_get_header: returns the list of 'any header' values
+* (except of unsupported yet Content- and MIME-Version special headers)
+*
+* You should free the GList list by yourself.
+**/
+static
+GList *
+message_get_header(GMimeMessage *message, const char *field) {
+ gint i;
+ char * ret = NULL;
+ GList * gret = NULL;
+ InternetAddressList *ia_list = NULL, *ia;
+
+ for (i = 0; i <= HEADER_UNKNOWN; ++i) {
+ if (!fieldfunc[i].name || !g_strncasecmp(field, fieldfunc[i].name, strlen(fieldfunc[i].name))) {
+ switch (fieldfunc[i].functype) {
+ case FUNC_CHARFREEPTR:
+ ret = (char *)(*(fieldfunc[i].func))(message);
+ break;
+ case FUNC_CHARPTR:
+ ret = (char *)(*(fieldfunc[i].func))(message);
+ break;
+ case FUNC_IA:
+ ia_list = (*(fieldfunc[i].rcptfunc))(message, field);
+ gret = g_list_alloc();
+ ia = ia_list;
+ while (ia && ia->address) {
+ char *ia_string;
+
+ ia_string = internet_address_to_string ((InternetAddress *)ia->address, FALSE);
+ gret = g_list_append (gret, ia_string);
+ ia = ia->next;
+ }
+ break;
+ case FUNC_LIST:
+ gret = (*(fieldfunc[i].getlistfunc))(message, field);
+ break;
+ }
+ break;
+ }
+ }
+ if (gret == NULL && ret != NULL) {
+ gret = g_list_prepend (gret, g_strdup (ret));
+ }
+ if (fieldfunc[i].functype == FUNC_CHARFREEPTR && ret) {
+ g_free (ret);
+ }
+ return gret;
+}
+
+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
+
+
diff --git a/perl/Rspamd/Config.xs b/perl/Rspamd/Config.xs
new file mode 100644
index 000000000..49b26db2f
--- /dev/null
+++ b/perl/Rspamd/Config.xs
@@ -0,0 +1,141 @@
+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
new file mode 100644
index 000000000..dae8a35ad
--- /dev/null
+++ b/perl/Rspamd/ContentType.xs
@@ -0,0 +1,87 @@
+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
new file mode 100644
index 000000000..b61cebc39
--- /dev/null
+++ b/perl/Rspamd/Hash.xs
@@ -0,0 +1,258 @@
+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 (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 (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:
+ char * key = NULL;
+ char * value = NULL;
+ Mail__Rspamd__Message msg;
+ I32 gimme = GIMME_V;
+ gint i, j, found;
+ local_GMimeHeader * header;
+ struct raw_header *h;
+ INIT:
+ if (ix == 1) {
+ obj->keyindex = -1;
+ }
+ PPCODE:
+ msg = obj->objptr;
+ ++obj->keyindex;
+ i = obj->keyindex;
+ 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;
+ }
+
+ 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 = value;
+ }
+
+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 ();
+
+
diff --git a/perl/Rspamd/InternetAddress.xs b/perl/Rspamd/InternetAddress.xs
new file mode 100644
index 000000000..834117bbe
--- /dev/null
+++ b/perl/Rspamd/InternetAddress.xs
@@ -0,0 +1,124 @@
+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:
+ RETVAL = internet_address_new ();
+ plist = g_list_prepend (plist, RETVAL);
+ OUTPUT:
+ RETVAL
+ CASE: items == 2
+ char * Class
+ char * name
+ CODE:
+ RETVAL = internet_address_new_group (name);
+ plist = g_list_prepend (plist, RETVAL);
+ OUTPUT:
+ RETVAL
+ CASE: items == 3
+ char * Class
+ char * name
+ char * address
+ CODE:
+ RETVAL = internet_address_new_name (name, address);
+ 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;
+ CODE:
+ addrlist = internet_address_parse_string (str);
+ retav = newAV ();
+ 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;
+ }
+ RETVAL = retav;
+ OUTPUT:
+ RETVAL
+
+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
+
+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) {
+ internet_address_list_append (addrlist, addr);
+ }
+ }
+ 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:
+ RETVAL = ia->type;
+ OUTPUT:
+ RETVAL
+
+
diff --git a/perl/Rspamd/Message.xs b/perl/Rspamd/Message.xs
new file mode 100644
index 000000000..6e3a16d8b
--- /dev/null
+++ b/perl/Rspamd/Message.xs
@@ -0,0 +1,264 @@
+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:
+ g_mime_message_add_recipient (message, type, name, address);
+
+void
+rspamd_message_add_recipients_from_string(message, type, recipients)
+ Mail::Rspamd::Message message
+ char * type
+ const char * recipients
+ CODE:
+ g_mime_message_add_recipients_from_string (message, type, recipients);
+
+AV *
+rspamd_message_get_recipients(message, type)
+ Mail::Rspamd::Message message
+ const char * type
+ PREINIT:
+ const InternetAddressList * rcpt;
+ AV * retav;
+ CODE:
+ retav = newAV();
+ rcpt = 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;
+ }
+ 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) {
+ str = g_mime_message_get_date_string (message);
+ 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:
+ g_mime_message_set_header (message, field, value);
+
+void
+rspamd_message_remove_header (message, field)
+ Mail::Rspamd::Message message
+ const char * field
+ CODE:
+ g_mime_object_remove_header (GMIME_OBJECT (message), field);
+
+void
+rspamd_message_add_header (message, field, value)
+ Mail::Rspamd::Message message
+ const char * field
+ const char * value
+ CODE:
+ g_mime_message_set_header (message, field, value);
+
+const char *
+rspamd_message_get_header (message, field)
+ Mail::Rspamd::Message message
+ const char * field
+ CODE:
+ RETVAL = g_mime_message_get_header (message, field);
+ 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);
+
+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
+
+SV *
+rspamd_message_get_headers(message)
+ Mail::Rspamd::Message message
+ PREINIT:
+ char * textdata;
+ CODE:
+ textdata = g_mime_message_get_headers (message);
+ 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
new file mode 100644
index 000000000..89bc09bf8
--- /dev/null
+++ b/perl/Rspamd/Object.xs
@@ -0,0 +1,152 @@
+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;
+ const GMimeContentType *ct;
+ CODE:
+ ct = 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) {
+ 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;
+ }
+ }
+ }
+ }
+ RETVAL = lsize;
+ OUTPUT:
+ RETVAL
+
diff --git a/perl/Rspamd/Part.xs b/perl/Rspamd/Part.xs
new file mode 100644
index 000000000..b95a5fc99
--- /dev/null
+++ b/perl/Rspamd/Part.xs
@@ -0,0 +1,160 @@
+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_content_disposition
+ 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_content_disposition
+ get_filename
+
+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
+
+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
+ CODE:
+ RETVAL = g_mime_part_encoding_to_string (encoding);
+ OUTPUT:
+ RETVAL
+
+Mail::Rspamd::PartEncodingType
+rspamd_part_encoding_from_string (encoding)
+ const char * encoding
+ CODE:
+ RETVAL = g_mime_part_encoding_from_string(encoding);
+ 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:
+ g_mime_part_add_content_disposition_parameter (mime_part, name, value);
+
+const char *
+rspamd_part_get_content_disposition_parameter (mime_part, name)
+ Mail::Rspamd::Part mime_part
+ const char * name
+ CODE:
+ RETVAL = g_mime_part_get_content_disposition_parameter (mime_part, name);
+ 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:
+ guint len;
+ const char * content_char;
+ SV * content;
+ CODE:
+ ST(0) = &PL_sv_undef;
+ if (!(mime_part->content) || !(mime_part->content->stream) ||
+ (content_char = g_mime_part_get_content(mime_part, &len)) == NULL) {
+ return;
+ }
+ content = sv_newmortal ();
+ SvUPGRADE (content, SVt_PV);
+ SvREADONLY_on (content);
+ SvPVX(content) = (char *) (content_char);
+ SvCUR_set (content, len);
+ SvLEN_set (content, 0);
+ SvPOK_only (content);
+ ST(0) = content;
+
diff --git a/perl/Rspamd/Task.xs b/perl/Rspamd/Task.xs
new file mode 100644
index 000000000..dec521660
--- /dev/null
+++ b/perl/Rspamd/Task.xs
@@ -0,0 +1,83 @@
+
+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);
+
+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
+
diff --git a/perl/rspamd.xs b/perl/rspamd.xs
deleted file mode 100644
index c7e1ae776..000000000
--- a/perl/rspamd.xs
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- * Perl XS module for interacting with rspamd
- *
- * vi:ts=4
- */
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
-#include <glib.h>
-
-#include "../src/config.h"
-#include "../src/main.h"
-#include "../src/message.h"
-#include "../src/cfg_file.h"
-#include "../src/perl.h"
-#include "../src/mem_pool.h"
-
-#define perl_set_session(r) \
- r = INT2PTR(struct worker_task *, SvIV((SV *) SvRV(ST(0))))
-
-#define perl_set_config(r) \
- r = INT2PTR(struct config_file *, SvIV((SV *) SvRV(ST(0))))
-
-#define perl_set_targ(p, len) \
- SvUPGRADE(TARG, SVt_PV); \
- SvPOK_on(TARG); \
- sv_setpvn(TARG, (char *) p, len)
-
-MODULE = rspamd PACKAGE = rspamd_task PREFIX = rspamd_task_
-PROTOTYPES: DISABLE
-
-void
-rspamd_task_get_header (r, header)
- CODE:
- dXSTARG;
- struct worker_task *r;
- SV *header;
- char *s;
- STRLEN len;
-
- perl_set_session(r);
-
- header = ST(1);
- if (SvROK (header) && SvTYPE (SvRV (header)) == SVt_PV) {
- header = SvRV (header);
- }
-
- s = (char *) SvPV (header, len);
-
- if ((s = (char *)g_mime_message_get_header (r->message, s)) == NULL) {
- XSRETURN_UNDEF;
- }
- else {
- perl_set_targ (s, strlen (s));
- ST(0) = TARG;
- }
-
-void
-rspamd_task_get_part_num (r)
- CODE:
- dXSTARG;
- struct worker_task *r;
-
- perl_set_session (r);
- sv_upgrade(TARG, SVt_IV);
- sv_setiv(TARG, r->parts_count);
-
- ST(0) = TARG;
-
-
-HV *
-rspamd_task_get_part (r, num)
- CODE:
- struct worker_task *r;
- SV *num;
- int number;
- struct mime_part *part;
- char *type;
-
- perl_set_session (r);
- num = ST(1);
-
- number = (int) SvIV (num);
- if (number < 0 || number > r->parts_count - 1) {
- XSRETURN_UNDEF;
- }
-
- part = g_list_nth_data (r->parts, number);
- RETVAL = newHV();
- type = g_mime_content_type_to_string (part->type);
-
- (void)hv_store_ent (RETVAL,
- newSVpv ("type", sizeof ("type") - 1),
- newSVpv (type, strlen(type)), 0);
- (void)hv_store_ent (RETVAL,
- newSVpv ("content", sizeof ("content") - 1),
- newSVpv ((char *)part->content->data, part->content->len), 0);
- sv_2mortal((SV*)RETVAL);
- OUTPUT:
- RETVAL
-
-void
-rspamd_task_ip (r)
- CODE:
- dXSTARG;
- struct worker_task *r;
- char *ip_str;
-
- perl_set_session (r);
- sv_upgrade(TARG, SVt_PV);
- ip_str = inet_ntoa (r->from_addr);
- sv_setpv(TARG, ip_str);
- ST(0) = TARG;
-
-void
-rspamd_task_from (r)
- CODE:
- dXSTARG;
- struct worker_task *r;
-
- perl_set_session (r);
- if (r->from == NULL) {
- XSRETURN_UNDEF;
- }
- sv_upgrade(TARG, SVt_PV);
- sv_setpv(TARG, r->from);
- ST(0) = TARG;
-
-void
-rspamd_task_save_point (r)
- CODE:
- struct worker_task *r;
-
- perl_set_session (r);
- r->save.saved = 1;
-
-void
-rspamd_task_recall_filter (r)
- CODE:
- struct worker_task *r;
-
- perl_set_session (r);
- process_filters (r);
-
-void
-rspamd_task_insert_result (r, metric, symbol, flag)
- CODE:
- struct worker_task *r;
- char *metric, *symbol;
- int flag;
-
- perl_set_session (r);
- metric = (char *) SvPV_nolen (ST(1));
- symbol = (char *) SvPV_nolen (ST(2));
- flag = (int) SvIV (ST(3));
-
- insert_result (r, metric, symbol, flag);
-
-
-
-void
-rspamd_task_read_memcached_key (r, key, datalen, callback)
- CODE:
- struct worker_task *r;
- char *key;
- unsigned int datalen;
- SV *callback;
- struct _param {
- SV *callback;
- struct worker_task *task;
- } *callback_data;
- memcached_ctx_t *ctx;
- memcached_param_t param;
-
- perl_set_session (r);
- key = (char *) SvPV_nolen (ST(1));
- datalen = (unsigned int) SvIV (ST(2));
- callback = SvRV(ST(3));
-
- /* Copy old ctx to new one */
- ctx = memory_pool_alloc (r->task_pool, sizeof (memcached_ctx_t));
- if (ctx == NULL) {
- XSRETURN_UNDEF;
- }
- memcpy (ctx, r->memc_ctx, sizeof (memcached_ctx_t));
- /* Set perl callback */
- ctx->callback = perl_call_memcached_callback;
- callback_data = memory_pool_alloc (r->task_pool, sizeof (struct _param));
- if (callback_data == NULL) {
- XSRETURN_UNDEF;
- }
- callback_data->callback = callback;
- callback_data->task = r;
- ctx->callback_data = (void *)callback_data;
-
- g_strlcpy (param.key, key, sizeof (param.key));
- param.buf = memory_pool_alloc (r->task_pool, datalen);
- if (param.buf != NULL) {
- param.bufsize = datalen;
- }
- param.bufpos = 0;
- param.expire = 0;
-
- memc_get (ctx, &param);
- /* Set save point */
- r->save.saved = 1;
- XSRETURN_EMPTY;
-
-void
-rspamd_task_write_memcached_key (r, key, data, expire, callback)
- CODE:
- struct worker_task *r;
- char *key, *data;
- SV *callback;
- STRLEN datalen;
- int expire;
- struct _param {
- SV *callback;
- struct worker_task *task;
- } *callback_data;
- memcached_ctx_t *ctx;
- memcached_param_t param;
-
- perl_set_session (r);
- key = (char *) SvPV_nolen (ST(1));
- data = (char *) SvPV (ST(2), datalen);
- expire = (int) SvIV (ST(3));
- callback = SvRV(ST(4));
-
- /* Copy old ctx to new one */
- ctx = memory_pool_alloc (r->task_pool, sizeof (memcached_ctx_t));
- if (ctx == NULL) {
- XSRETURN_UNDEF;
- }
- memcpy (ctx, r->memc_ctx, sizeof (memcached_ctx_t));
- /* Set perl callback */
- ctx->callback = perl_call_memcached_callback;
- callback_data = memory_pool_alloc (r->task_pool, sizeof (struct _param));
- if (callback_data == NULL) {
- XSRETURN_UNDEF;
- }
- callback_data->callback = callback;
- callback_data->task = r;
- ctx->callback_data = (void *)callback_data;
-
- g_strlcpy (param.key, key, sizeof (param.key));
- param.buf = data;
- param.bufsize = datalen;
- param.bufpos = 0;
- param.expire = expire;
-
- memc_set (ctx, &param, expire);
- /* Set save point */
- r->save.saved = 1;
- XSRETURN_EMPTY;
-
-void
-rspamd_task_delete_memcached_key (r, key, callback)
- CODE:
- struct worker_task *r;
- char *key;
- SV *callback;
- struct _param {
- SV *callback;
- struct worker_task *task;
- } *callback_data;
- memcached_ctx_t *ctx;
- memcached_param_t param;
-
- perl_set_session (r);
- key = (char *) SvPV_nolen (ST(1));
- callback = SvRV (ST(2));
-
- /* Copy old ctx to new one */
- ctx = memory_pool_alloc (r->task_pool, sizeof (memcached_ctx_t));
- if (ctx == NULL) {
- XSRETURN_UNDEF;
- }
- memcpy (ctx, r->memc_ctx, sizeof (memcached_ctx_t));
- /* Set perl callback */
- ctx->callback = perl_call_memcached_callback;
- callback_data = memory_pool_alloc (r->task_pool, sizeof (struct _param));
- if (callback_data == NULL) {
- XSRETURN_UNDEF;
- }
- callback_data->callback = callback;
- callback_data->task = r;
- ctx->callback_data = (void *)callback_data;
-
- g_strlcpy (param.key, key, sizeof (param.key));
- param.buf = NULL;
- param.bufsize = 0;
- param.bufpos = 0;
- param.expire = 0;
-
- memc_delete (ctx, &param);
- /* Set save point */
- r->save.saved = 1;
- XSRETURN_EMPTY;
-
-void
-rspamd_task_get_conf (r)
-CODE:
- struct worker_task *r;
- dXSTARG;
-
- perl_set_session (r);
-
- sv_setref_pv (TARG, "rspamd_config", r->cfg);
- ST(0) = TARG;
-
-
-MODULE = rspamd PACKAGE = rspamd_config PREFIX = rspamd_config_
-PROTOTYPES: DISABLE
-
-void
-rspamd_config_get_scalar (r, param)
-CODE:
- struct config_file *r;
- struct config_scalar *sc;
- char *param;
- int val;
- dXSTARG;
-
- perl_set_config (r);
- param = (char *) SvPV_nolen (ST(1));
-
- sc = g_hash_table_lookup (r->cfg_params, param);
- if (sc == NULL) {
- XSRETURN_UNDEF;
- }
- else {
- switch (sc->type) {
- case SCALAR_TYPE_SIZE:
- val = (int)(*(size_t *)sc->pointer);
- sv_upgrade (TARG, SVt_IV);
- sv_setiv (TARG, val);
- break;
- case SCALAR_TYPE_INT:
- case SCALAR_TYPE_UINT:
- val = *(int *)sc->pointer;
- sv_upgrade (TARG, SVt_IV);
- sv_setiv (TARG, val);
- break;
- case SCALAR_TYPE_STR:
- sv_upgrade (TARG, SVt_PV);
- SvPOK_on(TARG);
- sv_setpv (TARG, (char *)sc->pointer);
- break;
- }
- }
- ST(0) = TARG;
-
-void
-rspamd_config_set_scalar (r, param, value)
-CODE:
- struct config_file *r;
- struct config_scalar *sc;
- char *param, *charval;
- int intval;
- dXSTARG;
-
- perl_set_config (r);
- param = (char *) SvPV_nolen (ST(1));
-
- sc = g_hash_table_lookup (r->cfg_params, param);
- if (sc == NULL) {
- XSRETURN_UNDEF;
- }
- else {
- switch (sc->type) {
- case SCALAR_TYPE_SIZE:
- intval = (int)SvIV (ST(2));
- *((size_t *)sc->pointer) = intval;
- sv_upgrade (TARG, SVt_IV);
- sv_setiv (TARG, intval);
- break;
- case SCALAR_TYPE_INT:
- case SCALAR_TYPE_UINT:
- intval = (int)SvIV (ST(2));
- *((int *)sc->pointer) = intval;
- sv_upgrade (TARG, SVt_IV);
- sv_setiv (TARG, intval);
- break;
- case SCALAR_TYPE_STR:
- charval = (char *)SvPVX (ST(2));
- *((char **)sc->pointer) = charval;
- sv_upgrade (TARG, SVt_PV);
- sv_setpv (TARG, charval);
- break;
- }
- }
- ST(0) = TARG;
-
-HV *
-rspamd_config_set_metric (r, name)
-CODE:
- struct config_file *r;
- struct metric *val;
- char *name;
-
- perl_set_config (r);
- name = (char *) SvPV_nolen (ST(1));
-
- 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_set_statfile (r, name)
-CODE:
- struct config_file *r;
- struct statfile *val;
- char *name;
-
- perl_set_config (r);
- name = (char *) SvPV_nolen (ST(1));
-
- 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
-
-void
-rspamd_config_get_module_param (r, modulename, paramname)
- CODE:
- struct config_file *r;
- char *module, *param, *value;
-
- dXSTARG;
- perl_set_config (r);
- module = (char *) SvPV_nolen (ST(1));
- param = (char *) SvPV_nolen (ST(2));
-
- value = get_module_opt (r, module, param);
- if (value == NULL) {
- XSRETURN_UNDEF;
- }
-
- sv_upgrade(TARG, SVt_PV);
- sv_setpv(TARG, value);
-
- ST(0) = TARG;
-
-MODULE = rspamd PACKAGE = rspamd_log PREFIX = rspamd_log_
-PROTOTYPES: DISABLE
-
-void
-rspamd_log_log (level, str)
- CODE:
- int level;
- char *str;
-
- level = (int)SvIV (ST(0));
- str = (char *)SvPV_nolen (ST(1));
-
- g_log (G_LOG_DOMAIN, level, "%s", str);
- XSRETURN_EMPTY;
-
diff --git a/perl/typemap b/perl/typemap
index cdf52b17c..fa2dabb43 100644
--- a/perl/typemap
+++ b/perl/typemap
@@ -1,4 +1,27 @@
TYPEMAP
-rspamd_task T_PTROBJ
-rspamd_config T_PTROBJ
+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::ContentType T_PTROBJ
+Mail::Rspamd::InternetAddress T_PTROBJ
+Mail::Rspamd::Hash::Header T_PTROBJ
+
+const Mail::Rspamd::Part::EncodingType T_IV
orrectly Nextcloud server, a safe home for all your data: https://github.com/nextcloud/serverwww-data
summaryrefslogtreecommitdiffstats
path: root/settings/l10n/sv.php
blob: 7a9f341e4dd0878e422619bd65e3128a8484c5da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php $TRANSLATIONS = array(
"Unable to load list from App Store" => "Kan inte ladda listan från App Store",
"Authentication error" => "Fel vid autentisering",
"Your display name has been changed." => "Ditt visningsnamn har ändrats.",
"Unable to change display name" => "Kan inte ändra visningsnamn",
"Group already exists" => "Gruppen finns redan",
"Unable to add group" => "Kan inte lägga till grupp",
"Could not enable app. " => "Kunde inte aktivera appen.",
"Email saved" => "E-post sparad",
"Invalid email" => "Ogiltig e-post",
"Unable to delete group" => "Kan inte radera grupp",
"Unable to delete user" => "Kan inte radera användare",
"Language changed" => "Språk ändrades",
"Invalid request" => "Ogiltig begäran",
"Admins can't remove themself from the admin group" => "Administratörer kan inte ta bort sig själva från admingruppen",
"Unable to add user to group %s" => "Kan inte lägga till användare i gruppen %s",
"Unable to remove user from group %s" => "Kan inte radera användare från gruppen %s",
"Couldn't update app." => "Kunde inte uppdatera appen.",
"Update to {appversion}" => "Uppdatera till {appversion}",
"Disable" => "Deaktivera",
"Enable" => "Aktivera",
"Please wait...." => "Var god vänta...",
"Error" => "Fel",
"Updating...." => "Uppdaterar...",
"Error while updating app" => "Fel uppstod vid uppdatering av appen",
"Updated" => "Uppdaterad",
"Saving..." => "Sparar...",
"deleted" => "raderad",
"undo" => "ångra",
"Unable to remove user" => "Kan inte ta bort användare",
"Groups" => "Grupper",
"Group Admin" => "Gruppadministratör",
"Delete" => "Radera",
"add group" => "lägg till grupp",
"A valid username must be provided" => "Ett giltigt användarnamn måste anges",
"Error creating user" => "Fel vid skapande av användare",
"A valid password must be provided" => "Ett giltigt lösenord måste anges",
"__language_name__" => "__language_name__",
"Security Warning" => "Säkerhetsvarning",
"Your data directory and your files are probably accessible from the internet. The .htaccess file that ownCloud provides is not working. We strongly suggest that you configure your webserver in a way that the data directory is no longer accessible or you move the data directory outside the webserver document root." => "Din datakatalog och dina filer är förmodligen tillgängliga från Internet. Den .htaccess-fil som ownCloud tillhandahåller fungerar inte. Vi rekommenderar starkt att du konfigurerar webbservern så att datakatalogen inte längre är tillgänglig eller att du flyttar datakatalogen utanför webbserverns dokument-root.",
"Setup Warning" => "Installationsvarning",
"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Din webbserver är inte korrekt konfigurerad för att tillåta filsynkronisering eftersom WebDAV inte verkar fungera.",
"Please double check the <a href='%s'>installation guides</a>." => "Var god kontrollera <a href='%s'>installationsguiden</a>.",
"Module 'fileinfo' missing" => "Modulen \"fileinfo\" saknas",
"The PHP module 'fileinfo' is missing. We strongly recommend to enable this module to get best results with mime-type detection." => "PHP-modulen 'fileinfo' saknas. Vi rekommenderar starkt att aktivera den här modulen för att kunna upptäcka korrekt mime-typ.",
"Locale not working" => "Locale fungerar inte",
"This ownCloud server can't set system locale to %s. This means that there might be problems with certain characters in file names. We strongly suggest to install the required packages on your system to support %s." => "Denna ownCloud server kan inte sätta system locale till %s. Det innebär att det kan vara problem med vissa tecken i filnamnet. Vi vill verkligen rekommendera att du installerar nödvändiga paket på ditt system för att stödja %s.",
"Internet connection not working" => "Internetförbindelsen fungerar inte",
"This ownCloud server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don´t work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features of ownCloud." => "Den här ownCloudservern har ingen fungerande internetförbindelse. Det innebär att några funktioner som t.ex. att montera externa lagringsplatser, meddelanden om uppdateringar eller installation av tredjepartsappar inte fungerar. Det kan vara så att det inte går att få fjärråtkomst till filer och att e-post inte fungerar. Vi rekommenderar att du tillåter internetåtkomst för den här servern om du vill ha tillgång till alla funktioner hos ownCloud",
"Cron" => "Cron",
"Execute one task with each page loaded" => "Exekvera en uppgift vid varje sidladdning",
"cron.php is registered at a webcron service. Call the cron.php page in the owncloud root once a minute over http." => "cron.php är registrerad som en webcron-tjänst. Anropa cron.php sidan i ownCloud en gång i minuten över HTTP.",
"Use systems cron service. Call the cron.php file in the owncloud folder via a system cronjob once a minute." => "Använd system-tjänsten cron. Anropa filen cron.php i ownCloud-mappen via ett cronjobb varje minut.",
"Sharing" => "Dela",
"Enable Share API" => "Aktivera delat API",
"Allow apps to use the Share API" => "Tillåt applikationer att använda delat API",
"Allow links" => "Tillåt länkar",
"Allow users to share items to the public with links" => "Tillåt delning till allmänheten via publika länkar",
"Allow resharing" => "Tillåt vidaredelning",
"Allow users to share items shared with them again" => "Tillåt användare att dela vidare filer som delats med dem",
"Allow users to share with anyone" => "Tillåt delning med alla",
"Allow users to only share with users in their groups" => "Tillåt bara delning med användare i egna grupper",
"Security" => "Säkerhet",
"Enforce HTTPS" => "Kräv HTTPS",
"Enforces the clients to connect to ownCloud via an encrypted connection." => "Tvingar klienter att ansluta till ownCloud via en krypterad förbindelse.",
"Please connect to this ownCloud instance via HTTPS to enable or disable the SSL enforcement." => "Vänligen anslut till denna instans av ownCloud via HTTPS för att aktivera/avaktivera SSL",
"Log" => "Logg",
"Log level" => "Nivå på loggning",
"More" => "Mer",
"Less" => "Mindre",
"Version" => "Version",
"Developed by the <a href=\"http://ownCloud.org/contact\" target=\"_blank\">ownCloud community</a>, the <a href=\"https://github.com/owncloud\" target=\"_blank\">source code</a> is licensed under the <a href=\"http://www.gnu.org/licenses/agpl-3.0.html\" target=\"_blank\"><abbr title=\"Affero General Public License\">AGPL</abbr></a>." => "Utvecklad av <a href=\"http://ownCloud.org/contact\" target=\"_blank\">ownCloud Community</a>, <a href=\"https://github.com/owncloud\" target=\"_blank\">källkoden</a> är licenserad under <a href=\"http://www.gnu.org/licenses/agpl-3.0.html\" target=\"_blank\"><abbr title=\"Affero General Public License\">AGPL</abbr></a>.",
"Add your App" => "Lägg till din applikation",
"More Apps" => "Fler Appar",
"Select an App" => "Välj en App",
"See application page at apps.owncloud.com" => "Se programsida på apps.owncloud.com",
"<span class=\"licence\"></span>-licensed by <span class=\"author\"></span>" => "<span class=\"licence\"></span>-licensierad av <span class=\"author\"></span>",
"Update" => "Uppdatera",
"User Documentation" => "Användardokumentation",
"Administrator Documentation" => "Administratörsdokumentation",
"Online Documentation" => "Onlinedokumentation",
"Forum" => "Forum",
"Bugtracker" => "Bugtracker",
"Commercial Support" => "Kommersiell support",
"Get the apps to sync your files" => "Skaffa apparna för att synkronisera dina filer",
"Show First Run Wizard again" => "Visa Första uppstarts-guiden igen",
"You have used <strong>%s</strong> of the available <strong>%s</strong>" => "Du har använt <strong>%s</strong> av tillgängliga <strong>%s</strong>",
"Password" => "Lösenord",
"Your password was changed" => "Ditt lösenord har ändrats",
"Unable to change your password" => "Kunde inte ändra ditt lösenord",
"Current password" => "Nuvarande lösenord",
"New password" => "Nytt lösenord",
"Change password" => "Ändra lösenord",
"Display Name" => "Visningsnamn",
"Email" => "E-post",
"Your email address" => "Din e-postadress",
"Fill in an email address to enable password recovery" => "Fyll i en e-postadress för att aktivera återställning av lösenord",
"Language" => "Språk",
"Help translate" => "Hjälp att översätta",
"WebDAV" => "WebDAV",
"Use this address to <a href=\"%s/server/5.0/user_manual/files/files.html\" target=\"_blank\">access your Files via WebDAV</a>" => "Använd denna adress för att <a href=\"%s/server/5.0/user_manual/files/files.html\" target=\"_blank\">komma åt dina filer via WebDAV</a>",
"Login Name" => "Inloggningsnamn",
"Create" => "Skapa",
"Admin Recovery Password" => "Admin återställningslösenord",
"Enter the recovery password in order to recover the users files during password change" => "Enter the recovery password in order to recover the users files during password change",
"Default Storage" => "Förvald lagring",
"Unlimited" => "Obegränsad",
"Other" => "Annat",
"Username" => "Användarnamn",
"Storage" => "Lagring",
"change display name" => "ändra visningsnamn",
"set new password" => "ange nytt lösenord",
"Default" => "Förvald"
);