#!/usr/bin/perl

use gfio;
use Mail::RFC822::Address qw(valid); 

if (!$ARGV[0]) {
  my @p=split(/\//,$0); my $prog=pop @p;
  print "Usage: $prog mail\@host [mail[\@host]] [mapname]\n"; exit
}

my $mail=$ARGV[0];

if (($mail !~ /^\*?\@/) && !valid($mail)) {
  print " !> Address '$mail' is NOT a valid E-mail address!\n"; exit
}

my $box=$ARGV[1];
if ($box && ($box =~ /\@/) && !valid($box)) {
  print " !> Alias address '$box' is supposed to be, but is NOT a valid E-mail address!\n"; exit
}

sub readdata {
  my ($name) = @_;
  my $file="/etc/postfix/vmail_$name";
  my $db={};
  if (-e $file) {
    my $dat=gfio::content($file);
    foreach my $line (split(/\n/,$dat)) {
      if ($line =~ /[a-z0-9]/i) {
        $line =~ s/\t/ /;
        $line =~ s/[\s]+/ /g;
        $line =~ s/^\s//; $line =~ s/\s$//;
        my ($k,$v) = split(/\s/,$line);
        if (!$k) { $k="" }
        $db->{$k}=$v
      }
    }
  }
  return $db
}

sub savedata {
  my ($db,$name) = @_;
  my $file="/etc/postfix/vmail_$name";
  my @lines=();
  foreach my $k (sort keys %$db) {
    my $kk=$k; $kk =~ s/\~\@/\@/;
    push @lines,"$kk\t$db->{$k}"
  }
  gfio::create($file,join("\n",@lines))
}

my $domain=readdata('domains');
my $boxes=readdata('mailbox');
my $alias=readdata('aliases');

my ($ename,$dom) = split(/\@/,$mail);
if (!$ename) { $ename="~" }
if ($ename eq '*') { $ename="~"; $mail="~\@".$dom }
$domains->{$dom}='OK';
if ($ename eq '~') {
  if (!valid($box) || !$alias->{$box}) {
    print " !> Catchall for '$dom' must point to an existing E-mail address!\n"; exit
  }
  $alias->{$mail}=$box
} else {
  if (!$box) { $box=$mail }
  else {
    if ($box !~ /\@/) { $box="$box\@$dom" }
    if (!$boxes->{$box}) {
      print " !> E-mail address '$box' does not exist!\n"; exit
    }
  }
  $alias->{$mail}=$box;
  if (!$boxes->{$box}) {
    my ($bname,$bdom) = split(/\@/,$box);
    if ($ARGV[2]) { $bname=$ARGV[2] }
    $boxes->{$box}="$bdom/$bname";
    savedata($boxes,'mailbox')
  }
}
savedata($alias,'aliases');
savedata($domains,'domains');

system "postmap /etc/postfix/vmail_domains";
system "postmap /etc/postfix/vmail_mailbox";
system "postmap /etc/postfix/vmail_aliases";

system "/etc/init.d/postfix reload";

print " > E-mail '$mail' succesfully created under map '$box'\n"


