#!/usr/bin/eperl
###
#
# Copyright (c) Ensim Corporation 2000, 2001   All Rights Reserved.
#
# This software is furnished under a license and may be used and copied
# only  in  accordance  with  the  terms  of such  license and with the
# inclusion of the above copyright notice. This software or any other
# copies thereof may not be provided or otherwise made available to any
# other person. No title to and ownership of the software is hereby
# transferred.
#
# The information in this software is subject to change without notice
# and  should  not be  construed  as  a commitment by Ensim Corporation.
# Ensim assumes no responsibility for the use or  reliability  of its
# software on equipment which is not supplied by Ensim.
#
# Exit codes (on failure error message goes to stderr):
#  0 - success
#  1 - failure
# 
# Boolean arguments on the command line are given as 0 or 1. All the
# command line arguments are encoded to avoid problems with escapes.
#
# All functions defined here either return an error message if an
# error occured and "" if everything went well or allways return a
# valid value, but exit (with code 1) printing an error message if an
# error occurs. This second type of functions have _e appended to
# their name. Functions are allowed to print results onto stdout, but
# errors are printed only in the main program.
#
# ----------------------------------------------------------------------
# Usage: update_alias <alias> <name1> [ <name2> ... ]
# ----------------------------------------------------------------------

push @INC, ($ENV{'OCW_SVCPATH'} || "/usr/lib/opcenter")."/sendmail";
push @INC, ($ENV{'OCW_SVCPATH'} || "/usr/lib/opcenter")."/cmdline_common";

use strict;
use Getopt::Std;
require sendmailconf;
require sendmail;
require CmdLineCoder;
require Locking;

use lib ($ENV{OCW_SVCPATH} or "/usr/lib/opcenter") . "/sendmail";
use lib ($ENV{OCW_SVCPATH} or "/usr/lib/opcenter") . "/cmdline_common";

use ERRORS;
use Carper;

&CmdLineCoder::decode_args();

my( $sendmailcf );    # The 'sendmail.cf' config file in a perl data structure
my( @aliases );       # List of all aliases in perl data structure
my( $aliasname );     # The name of the alias we are updating (from args)
my( $oldalias );      # The entry for the alias we are updating from @aliases
my( $type );          # The type of alias we are updating
my( @newvalues );     # The new values of the alias
my( $a );             # Temp variable for alias

if ( $ARGV[0] eq '-a' ) {
    $type = 1;
    shift;
} elsif ( $ARGV[0] eq '-f' ) {
    $type = 3;
    shift;
} elsif ( $ARGV[0] eq '-r' ) {
    $type = 4;
    shift;
} else {
    $type = 1;  # default value
}

$aliasname = shift;

&Locking::PushLock ($sendmailconf::config{'sendmail_cf'});
$sendmailcf = &sendmail::get_sendmailcf();
@aliases = &sendmail::list_aliases(&sendmail::aliases_file($sendmailcf));

# Ignore aliases that are commented out
@aliases = grep { $_->{'enabled'} == 1 } @aliases;

# Find the alias we are updating
@aliases = grep { $_->{'name'} eq $aliasname } @aliases;

if ( @aliases ) {
    $oldalias = $aliases[0];  # We are only interested in the first entry
    # All entries of different type will be untouched and therefore members
    # of @newvalues.
    @newvalues = grep { &sendmail::alias_type($_) != $type } @{$oldalias->{'values'}};
}

# Check if all the new aliases are of the right type and add them to
# the new aliases array.
for $a ( @ARGV ) {
  if (&sendmail::alias_type($a) != $type) {
    $cerr += $E_INVALIDARGTYPE and $cerr += { arg => $a } ;
    print STDERR "Argument $a of invalid type\n"; 
    &Locking::ReleasePushedLocks;
    exit 1;
  }
  push @newvalues, $a;
}
      
my( $newalias, $lines, @filelines, $filename );
$newalias = &sendmail::stringitize_values(@newvalues)."\n";
$newalias = $aliasname.":  ".$newalias;

if ( $oldalias ) {
    $filename = $oldalias->{'file'};
} else {
    $filename = @{&sendmail::aliases_file($sendmailcf)}[0];
}

# Read the alias file entries
open ALIASFILE, "$filename";
@filelines = <ALIASFILE>;
close ALIASFILE;

if ( $oldalias ) {
    $lines = $oldalias->{'eline'} - $oldalias->{'line'} + 1;
    # if we have additional values and its not an alias change
    # or if it is an alias change and it has arguments, splice in
    if (( @newvalues ) and (($type != 1) or (($type == 1) and ($#ARGV!=-1)))) {
        splice(@filelines, $oldalias->{'line'}, $lines, $newalias );
    } else {
        # No values -> alias deleted
        splice(@filelines, $oldalias->{'line'}, $lines );
    }
    # if we are changing a responder, remove old responder files
    # or if we are removing the alias, remove the old responder files
    if ( ( $type == 4 ) or ( ( $type == 1 ) and ($#ARGV == -1) ) ) {
        #delete the respondeer files
        my(@filtered) = grep { /^\|responder\.sh\s/ } @{$oldalias->{'values'}};
        my(@x) = split (/\s+/,$filtered[0]);
        my($filename) = pop @x;
        unlink ($filename);
    }
} else {
    if ( @newvalues ) {
        push @filelines, $newalias;
    }
}

# Write out the aliases file
open ALIASFILE, ">$filename";
print ALIASFILE @filelines;
close ALIASFILE;

&Locking::ReleasePushedLocks;

# Now we recreate the aliases.db file.
&sendmail::newaliases();

exit 0;
