package Onis::Users; use strict; use warnings; use Exporter; use Onis::Config (qw(get_config)); use Onis::Data::Persistent (); @Onis::Users::EXPORT_OK = (qw( chatter_to_name name_to_chatter name_to_ident name_to_nick get_realname get_link get_image )); @Onis::Users::ISA = ('Exporter'); =head1 NAME Onis::Users - Management of configures users, so called "names". =head1 DESCRIPTION Parses user-info and provides query-routines. The definition of "name" can be found in L. =head1 USAGE use Onis::Users qw#ident_to_name chatter_to_name get_realname get_link get_image#; # Functions to query the name $name = ident_to_name ($ident); $name = chatter_to_name ($chatter); # Functions to query a name's properties my $realname = get_realname ($name); my $link = get_link ($name); my $image = get_image ($name); =head1 DIAGNOSTIGS Set $::DEBUG to ``0x1000'' to get extra debug messages. =cut our $Users = {}; our $ChatterToName = {}; our $NameToChatter = {}; my $VERSION = '$Id: Users.pm 80 2005-04-17 12:30:33Z octo $'; print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG); read_config (); return (1); =head1 CONFIGURATION OPTIONS =over 4 =item B: I; Sets the file from which to read the user configuration. =back =cut sub read_config { my $config_file = 'users.conf'; my $content; my $fh; if (get_config ('users_config')) { my $temp = get_config ('users_config'); if (-e $temp and -r $temp) { $config_file = $temp; } elsif (-e $temp) { print STDERR $/, __FILE__, ": Unable to read users_config ``$temp'': ", "File not readable. Check your permissions."; } else { print STDERR $/, __FILE__, ": Unable to read users_config ``$temp'': ", "File does not exist."; } } # Fail silently, if fle does not exist.. if (!-e $config_file) { return (0); } print STDERR $/, __FILE__, ": Reading config file ``$config_file''" if ($::DEBUG & 0x1000); # read the file unless (open ($fh, "< $config_file")) { print STDERR $/, __FILE__, ": Unable to open ``$config_file'' for reading: $!"; return (0); } { local ($/) = undef; $content = <$fh>; } close ($fh); # parse the file #$content =~ s/[\n\r\s]+//gs; $content =~ s/#.*$//gm; $content =~ s/[\n\r]+//gs; #while ($content =~ m/([^{]+){([^}]+)}/g) while ($content =~ m/([^\s{]+)\s*{([^}]+)}/g) { my $user = $1; my $line = $2; print STDERR $/, __FILE__, ": User ``$user''" if ($::DEBUG & 0x1000); while ($line =~ m/([^\s:]+)\s*:([^;]+);/g) { my $key = lc ($1); my $val = $2; $val =~ s/^\s+|\s+$//g; print STDERR $/, __FILE__, ": + $key = ``$val''" if ($::DEBUG & 0x1000); if (($key eq 'image') or ($key eq 'link') or ($key eq 'name')) { if (!defined ($Users->{$user}{$key})) { $Users->{$user}{$key} = []; } push (@{$Users->{$user}{$key}}, $val); } elsif (($key eq 'host') or ($key eq 'hostmask')) { my $this_nick; my $this_user; my $this_host; if ($val =~ m/^([^!]+)!([^@]+)@(.+)$/) { $this_nick = quotemeta (lc ($1)); $this_user = quotemeta (lc ($2)); $this_host = quotemeta (lc ($3)); } else { print STDERR $/, __FILE__, ": Invalid hostmask for user $user: ``$val''"; next; } $this_nick =~ s/\\\*/[^!]*/g; $this_nick =~ s/\\\?/[^!]/g; $this_user =~ s/\\\*/[^@]*/g; $this_user =~ s/\\\?/[^@]/g; $this_host =~ s/\\\*/.*/g; $this_host =~ s/\\\?/./g; $val = "$this_nick!$this_user\@$this_host"; if (!defined ($Users->{$user}{'host'})) { $Users->{$user}{'host'} = []; } print STDERR " --> m/^$val\$/i" if ($::DEBUG & 0x1000); push (@{$Users->{$user}{'host'}}, qr/^$val$/i); } else { print STDERR $/, __FILE__, ": Invalid key in users_config: ``$key''"; } } if (!defined ($Users->{$user}{'host'})) { print STDERR $/, __FILE__, ": No hostmask given for user $user. Ignoring him/her."; delete ($Users->{$user}); } } return (1); } =head1 EXPORTED FUNCTIONS =over 4 =item B (I<$chatter>) Passes the ident-part of I<$chatter> to B. =cut sub chatter_to_name { my $chatter = shift; my $retval = ''; if (defined ($ChatterToName->{$chatter})) { return ($ChatterToName->{$chatter}); } USER: for (keys %$Users) { my $name = $_; for (@{$Users->{$name}{'host'}}) { my $re = $_; if ($chatter =~ $re) { $retval = $name; last USER; } } } if (($::DEBUG & 0x1000) and $retval) { print STDERR $/, __FILE__, ": ``$chatter'' identified as ``$retval''"; } $ChatterToName->{$chatter} = $retval; $NameToChatter->{$retval} = $chatter if ($retval); return ($retval); } =item B (I<$name>) Returns the most recent chatter for I<$name>. =cut sub name_to_chatter { my $name = shift; if (defined ($NameToChatter->{$name})) { return ($NameToChatter->{$name}); } else { return (''); } } =item B (I<$name>) Returns the most recent ident for I<$name>. =cut sub name_to_ident { my $name = shift; if (defined ($NameToChatter->{$name})) { my $chatter = $NameToChatter->{$name}; my ($nick, $ident) = split (m/!/, $chatter); return ($ident); } else { return (''); } } =item B (I<$name>) Returns the most recent nick for I<$name>. =cut sub name_to_nick { my $name = shift; if (defined ($NameToChatter->{$name})) { my $chatter = $NameToChatter->{$name}; my ($nick, $ident) = split (m/!/, $chatter); return ($nick); } else { return (''); } } =item B (I<$name>) Returns the B for this (user)name as defined in the config. Sorry for the confusing terms. =cut sub get_realname { my $name = shift; my $retval = ''; if (defined ($Users->{$name}{'name'})) { my $tmp = int (rand (scalar (@{$Users->{$name}{'name'}}))); $retval = $Users->{$name}{'name'}[$tmp]; } return ($retval); } =item B (I<$name>) Returns the URL defined for this name in the config. =cut sub get_link { my $name = shift; my $retval = ''; if (defined ($Users->{$name}{'link'})) { my $tmp = int (rand (scalar (@{$Users->{$name}{'link'}}))); $retval = $Users->{$name}{'link'}[$tmp]; } return ($retval); } =item B (I<$name>) Returns the URL of the (user)name's image, if one is configured. =cut sub get_image { my $name = shift; my $retval = ''; if (defined ($Users->{$name}{'image'})) { my $tmp = int (rand (scalar (@{$Users->{$name}{'image'}}))); $retval = $Users->{$name}{'image'}[$tmp]; } return ($retval); } =back =head1 AUTHOR Florian octo Forster Eocto at verplant.orgE =cut