.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man v6.0.2 (Pod::Simple 3.45) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Required to disable full justification in groff 1.23.0. .if n .ds AD l .\" ======================================================================== .\" .IX Title "Mail::SpamAssassin::Util 3" .TH Mail::SpamAssassin::Util 3 2026-07-23 "perl v5.42.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH NAME Mail::SpamAssassin::Util \- utility functions .SH DESCRIPTION .IX Header "DESCRIPTION" A general class for utility functions. Please use this for functions that stand alone, without requiring a \f(CW$self\fR object, Portability functions especially. .PP NOTE: The functions in this module are to be considered private. Their API may change at any point, and it\*(Aqs expected that they\*(Aqll only be used by other Mail::SpamAssassin modules. (TODO: we should probably revisit this if it\*(Aqs useful for plugin development.) .PP NOTE: Utility functions should not be changing global variables such as \f(CW$_\fR, \f(CW$1\fR, \f(CW$2\fR, ... $/, etc. unless explicitly documented. If these variables are in use by these functions, they should be localized. .SH METHODS .IX Header "METHODS" .ie n .IP untaint_var($var) 4 .el .IP \f(CWuntaint_var($var)\fR 4 .IX Item "untaint_var($var)" This sub takes a scalar or a reference to an array, hash, scalar or another reference and recursively untaints all its values (and keys if it\*(Aqs a reference to a hash). It will return the untainted value if requested but to avoid unnecessary copying, the return value should be ignored when working on lists. .ie n .IP is_fqdn_valid($host) 4 .el .IP \f(CWis_fqdn_valid($host)\fR 4 .IX Item "is_fqdn_valid($host)" Check for full hostname / FQDN / DNS name validity. IP addresses must be validated with other functions like Constants::IP_ADDRESS. Does not check for valid TLD, use \f(CW$self\fR\->{main}\->{registryboundaries}\->\fBis_domain_valid()\fR additionally for that. If \f(CW$is_ascii\fR given and true, skip \fBidn_to_ascii()\fR conversion. .ie n .IP is_valid_utf8($str) 4 .el .IP \f(CWis_valid_utf8($str)\fR 4 .IX Item "is_valid_utf8($str)" The sub returns true if the provided string of octets represents a syntactically valid UTF\-8 string, otherwise a false is returned. .ie n .IP idn_to_ascii($domain) 4 .el .IP \f(CWidn_to_ascii($domain)\fR 4 .IX Item "idn_to_ascii($domain)" Given an international domain name with U\-labels (UTF\-8 or Unicode chars) converts it to ASCII\-compatible encoding (ACE). If the argument is in ASCII (or is an invalid IDN), returns it lowercased but otherwise unchanged. The result is always in octets (utf8 flag off) even if the argument was in Unicode characters. .ie n .IP """exit_status_str($stat, $errno)""" 4 .el .IP "\f(CWexit_status_str($stat, $errno)\fR" 4 .IX Item "exit_status_str($stat, $errno)" map process termination status number to an informative string, and append optional message (dual\-valued errno or a string or a number), returning the resulting string .ie n .IP """proc_status_ok($exit_status, $errno, @success)""" 4 .el .IP "\f(CWproc_status_ok($exit_status, $errno, @success)\fR" 4 .IX Item "proc_status_ok($exit_status, $errno, @success)" check errno to be 0 and a process exit status to be in the list of success status codes, returning true if both are ok, and false otherwise. .ie n .IP parse_rfc822_date($date) 4 .el .IP \f(CWparse_rfc822_date($date)\fR 4 .IX Item "parse_rfc822_date($date)" Parses an RFC 2822 formatted date string and returns a Unix timestamp. Takes a date to parse as input and returns a Unix timestamp (seconds since epoch) if the date can be parsed, or undef on failure. .ie n .IP time_to_rfc822_date($timestamp) 4 .el .IP \f(CWtime_to_rfc822_date($timestamp)\fR 4 .IX Item "time_to_rfc822_date($timestamp)" Converts a Unix timestamp and returns an RFC 2822 formatted date string. .ie n .IP qp_decode($str) 4 .el .IP \f(CWqp_decode($str)\fR 4 .IX Item "qp_decode($str)" Decodes a string that has been encoded using the Quoted\-Printable content transfer encoding. .ie n .IP extract_ipv4_addr_from_string($str) 4 .el .IP \f(CWextract_ipv4_addr_from_string($str)\fR 4 .IX Item "extract_ipv4_addr_from_string($str)" Given a string, extract an IPv4 address from it. .ie n .IP reverse_ip_address($ip) 4 .el .IP \f(CWreverse_ip_address($ip)\fR 4 .IX Item "reverse_ip_address($ip)" Given a quad\-dotted IPv4 address or an IPv6 address, reverses the order of its bytes (IPv4) or nibbles (IPv6), joins them with dots, producing a string suitable for reverse DNS lookups. Returns undef in case of a syntactically invalid IP address. .ie n .IP first_available_module(@module_list) 4 .el .IP \f(CWfirst_available_module(@module_list)\fR 4 .IX Item "first_available_module(@module_list)" Return the name of the first module that can be successfully loaded with \&\f(CW\*(C`require\*(C'\fR from the list. Returns \f(CW\*(C`undef\*(C'\fR if none are available. .Sp This is used instead of \f(CW\*(C`AnyDBM_File\*(C'\fR as follows: .Sp .Vb 3 \& my $module = Mail::SpamAssassin::Util::first_available_module \& (qw(DB_File GDBM_File NDBM_File SDBM_File)); \& tie %hash, $module, $path, [... args]; .Ve .Sp Note that \f(CW\*(C`SDBM_File\*(C'\fR is guaranteed to be present, since it comes with Perl. .ie n .IP """touch_file($file, $args)""" 4 .el .IP "\f(CWtouch_file($file, $args)\fR" 4 .IX Item "touch_file($file, $args)" Touch or create a file. .Sp Possible args: .Sp create_exclusive => 1 Create a new empty file safely, only if not existing before .ie n .IP secure_tmpfile() 4 .el .IP \f(CWsecure_tmpfile()\fR 4 .IX Item "secure_tmpfile()" Generates a filename for a temporary file, opens it exclusively and securely, and returns a filehandle to the open file (opened O_RDWR) and it filename. .Sp If it cannot open a file after 20 tries, it returns \f(CW\*(C`undef\*(C'\fR. .ie n .IP secure_tmpdir() 4 .el .IP \f(CWsecure_tmpdir()\fR 4 .IX Item "secure_tmpdir()" Generates a directory for temporary files. Creates it securely and returns the path to the directory. .Sp If it cannot create a directory after 20 tries, it returns \f(CW\*(C`undef\*(C'\fR. .ie n .IP """compile_regexp($re, $strip_delimiters, $ignore_always_matching)""" 4 .el .IP "\f(CWcompile_regexp($re, $strip_delimiters, $ignore_always_matching)\fR" 4 .IX Item "compile_regexp($re, $strip_delimiters, $ignore_always_matching)" Compiles a regular expression pattern for efficient and safe use within SpamAssassin.