/usr/local/CPAN/DJabberd/DJabberd/Util.pm
package DJabberd::Util;
use strict;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(exml tsub lbsub as_bool as_num as_abs_path as_bind_addr);
sub as_bool {
my $val = shift;
return 1 if $val =~ /^1|y|yes|true|t|on|enabled?$/i;
return 0 if $val =~ /^0|n|no|false|f|off|disabled?$/i;
die "Can't determine booleanness of '$val'\n";
}
sub as_num {
my $val = shift;
return $val if $val =~ /^\d+$/;
die "'$val' is not a number\n";
}
sub as_bind_addr {
my $val = shift;
# Must either be like 127.0.0.1:1234, a bare port number or an absolute path to a unix domain socket
if ($val =~ /^(\d\d?\d?\.\d\d?\d?\.\d\d?\d?\.\d\d?\d?:)?\d+$/ || ($val =~ m!^/! && -e $val)) {
return $val;
}
die "'$val' is not a valid bind address or port\n";
}
sub as_abs_path {
my $val = shift;
die "Path '$val' isn't absolute" unless $val =~ m!^/!;
die "File '$val' doesn't exist" unless -f $val;
return $val;
}
sub exml
{
# fast path for the commmon case:
return $_[0] unless $_[0] =~ /[&\"\'<>\x00-\x08\x0B\x0C\x0E-\x1F]/;
# what are those character ranges? XML 1.0 allows:
# #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
my $a = shift;
$a =~ s/\&/&/g;
$a =~ s/\"/"/g;
$a =~ s/\'/'/g;
$a =~ s/</</g;
$a =~ s/>/>/g;
$a =~ s/[\x00-\x08\x0B\x0C\x0E-\x1F]//g;
return $a;
}
sub durl {
my ($a) = @_;
$a =~ tr/+/ /;
$a =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
return $a;
}
# tracked sub
sub tsub (&) {
my $subref = shift;
bless $subref, 'DJabberd::TrackedSub';
DJabberd->track_new_obj($subref);
return $subref;
}
# line-blessed sub
sub lbsub (&) {
my $subref = shift;
my ($pkg, $file, $line) = caller;
my $bpkg = $file . "_" . $line;
$bpkg =~ s/[^\w]/_/g;
return bless $subref, "DJabberd::AnonSubFrom::$bpkg";
}
sub numeric_entity_clean {
my $hex = $_[0];
my $val = hex $hex;
# under a space, only \n, \r, and \t are allowed.
if ($val < 32 && ($val != 13 && $val != 10 && $val != 9)) {
return "";
}
return "&#$hex;";
}
package DJabberd::TrackedSub;
sub DESTROY {
my $self = shift;
DJabberd->track_destroyed_obj($self);
}
1;