#-*- perl -*-
#
# Copyright (C) 2003,2004,2005,2006 Ken'ichi Fukamachi
# All rights reserved. This program is free software; you can
# redistribute it and/or modify it under the same terms as Perl itself.
#
# $FML: Alias.pm,v 1.6 2006/11/26 09:10:40 fukachan Exp $
#
package FML::Sys::Alias;
use strict;
use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD);
use Carp;
use Config;
my $debug = 0;
=head1 NAME
FML::Sys::Alias - get mail alias information on this system.
=head1 SYNOPSIS
use FML::Sys::Alias;
my $alias = new FML::Sys::Alias;
$alias->read_alias_file($alias_file);
=head1 DESCRIPTION
This module provides methods to handle mail alias information on this
system.
=head1 METHODS
=head2 new()
constructor.
=cut
# Descriptions: constructor.
# Arguments: OBJ($self)
# Side Effects: none
# Return Value: OBJ
sub new
{
my ($self) = @_;
my ($type) = ref($self) || $self;
my $me = {
_aliases => {},
};
return bless $me, $type;
}
# Descriptions: get entries in $file (e.g. /etc/mail/aliases).
# Arguments: OBJ($self) STR($file)
# Side Effects: update hash on memory.
# Return Value: none
sub read_alias_file
{
my ($self, $file) = @_;
use FileHandle;
my $fh = new FileHandle $file;
if (defined $fh) {
my ($buf, $key, $addrs);
LINE:
while ($buf = <$fh>) {
next LINE if $buf =~ /^\#/o;
next LINE if $buf =~ /^\s*$/o;
chomp $buf;
($key, $addrs) = split(/\s*:\s*/, $buf, 2);
$self->add_key($key, $addrs);
}
$fh->close();
}
}
# Descriptions: add $key into aliases hash table.
# Arguments: OBJ($self) STR($key) STR($addrs)
# Side Effects: update $self->{ _aliases } hash on memory.
# Return Value: none
sub add_key
{
my ($self, $key, $addrs) = @_;
my $aliases = $self->{ _aliases };
$key =~ s/\s*//g;
$addrs =~ s/^\s*//;
$addrs =~ s/\s*$//;
my (@a) = split(/\s*,\s*/, $addrs);
# XXX-TODO: first match ? (only ?)
unless (defined $aliases->{ $key }) {
$aliases->{ $key } = \@a;
}
}
# Descriptions: expand $key.
# Arguments: OBJ($self) STR($key)
# Side Effects: none
# Return Value: ARRAY_REF
sub expand
{
my ($self, $key) = @_;
my $aliases = $self->{ _aliases };
return $self->_expand($key, $aliases->{ $key }, 0);
}
# Descriptions: expand $key and return the result as ARRAY_REF.
# Arguments: OBJ($self) STR($key) ARRAY_REF($value) NUM($recursive)
# Side Effects: none
# Return Value: ARRAY_REF
sub _expand
{
my ($self, $key, $value, $recursive) = @_;
my $aliases = $self->{ _aliases };
my @r = ();
my $r = '';
$recursive++;
if ($recursive > 16) { # avoid infinite loop.
return [ $key ];
}
if ($debug) {
print STDERR " " x $recursive;
print STDERR "INPUT { $key => $value }\n";
}
for my $v (@$value) {
if ($debug) {
print STDERR " " x $recursive;
print STDERR "expand $v =>\n";
}
$r = $self->_expand($v, $aliases->{ $v }, $recursive);
if ($debug) {
print STDERR " " x $recursive;
print STDERR "[ @$r ]\n";
}
push(@r, @$r);
}
@r = sort @r;
OUT:
return($#r >= 0 ? \@r : [ $key ]);
}
#
# debug
#
if ($0 eq __FILE__) {
my $alias_file = $ENV{ ALIASES } || croak("specify env ALIASES=\$FILE $0");
my $alias = new FML::Sys::Alias;
$alias->read_alias_file( $alias_file );
my $buf;
while ($buf = <>) {
if ($buf =~ /^\#/o) {
print $buf;
}
else {
chomp $buf;
my ($k, $v) = split(/\s+/, $buf);
my $a = $alias->expand($v);
printf "%-20s => %s\n", "input> $k", $buf;
printf "%-20s => %s\n", $k, join(" ", @$a);
}
}
}
=head1 CODING STYLE
See C on fml coding style guide.
=head1 AUTHOR
Ken'ichi Fukamachi
=head1 COPYRIGHT
Copyright (C) 2003,2004,2005,2006 Ken'ichi Fukamachi
All rights reserved. This program is free software; you can
redistribute it and/or modify it under the same terms as Perl itself.
=head1 HISTORY
FML::Sys::Alias appeared in fml8 mailing list driver package.
See C for more details.
=cut
1;