#!/usr/bin/perl -w

use strict;
use File::Basename;
use Getopt::Long;
use IO;

sub PROGNAME { 'dspam_genaliases'; }

sub PACKAGE_STRING  { 'dspam 2.10.1'; }
sub PACKAGE_BUGREPORT { 'jonathan@nuclearelephant.com'; }

sub DSPAM_BINARY { '/usr/bin/dspam'; }

sub FALSE   { 0; }
sub TRUE    { !FALSE; }
sub EXIT_SUCCESS    { 0; }
sub EXIT_FAILURE    { 1; }

my $PROG = basename($0);

sub Help()
{
    show_version();
    printf("Script that reads the `/etc/passwd' file and outputs a dspam aliases\n");
    printf("table which can be included in the master aliases table.\n");
    printf("\n");
    printf("Usage:\n");
    printf("    %s [options]\n", $PROG);
    printf("\n");
    printf("Options:\n");
    printf("    -h, --help          This help\n");
    printf("        --version       Show version info\n");
    printf("        --nospam        Generate `nospam-USER' aliases for reporting a false\n");
    printf("                        positives (in addition to the `spam-USER' aliases)\n");
    printf("    -o, --output FILE   Output generated aliases to the FILE.\n");
    printf("                        Special filename `-' is allowed and points\n");
    printf("                        to the stdout.\n");
    printf("                        [default: stdout]\n");
###    printf("        --salt STR      \"Salt\" aliases.  Generate aliases like\n");
###    printf("                        `spam-USER-STR' instead of `spam-USER'\n");
###    printf("                        and `nospam-USER-STR' instead of `nospam-USER-STR'\n");
###    printf("                        (last if generating of `nospam-USER' aliases is\n");
###    printf("                        enabled only.)\n");
    printf("\n");
    printf("Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
}

sub UseHelp()
{
    printf(STDERR "%s: try `%s --help' for help\n", $PROG, $PROG);
}

sub show_version()
{
    printf("%s (%s)\n", PROGNAME, PACKAGE_STRING);
    printf("Copyright (C) 2003 Network Dweebs Corporation\n");
    printf("This is free software; see the source for copying conditions.  There is NO\n");
    printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
    printf("\n");
}

sub main()
{
    my $success;
    my $opt_help;
    my $opt_version;
    my $outfile;
    my $outhandle;
    my $inputfile;
    my $inputhandle;
    my $salt;
    my $opt_generate_nospam = FALSE;

    Getopt::Long::config("no_auto_abbrev",
                         "no_ignore_case",
                         "bundling");
    $success = GetOptions("help|h" => \$opt_help,
                          "version" => \$opt_version,
                          "nospam" => \$opt_generate_nospam,
                          "output|o=s" => \$outfile,
###                          "salt=s" => \$salt
                          );

    if (!$success)
    {
        UseHelp();
        return EXIT_FAILURE;
    }
    if ($opt_help)
    {
        Help();
        return EXIT_SUCCESS;
    }
    if ($opt_version)
    {
        show_version();
        return EXIT_SUCCESS;
    }
    
    if (@ARGV)
    {
        printf(STDERR "%s: too many command line arguments\n", $PROG);
        UseHelp();
        return EXIT_FAILURE;
    }

###    if (!defined($salt) || $salt eq '')
###    {
###        printf("%s: warning: no salt specified, therefore your spam/nospam aliases can be guessed and abused by spammers.  YOU ARE WARNED.\n", $PROG);
###        $salt='';
###    }

    # open input file
    $inputfile = '/etc/passwd';
    $inputhandle = IO::File->new($inputfile, 'r');
    if (!$inputhandle)
    {
            printf(STDERR "%s: error opening `%s' for reading: %s\n",
                   $PROG, $inputfile, $!);
            return EXIT_FAILURE;
    }

    # open output file.
    if (!defined($outfile) || $outfile eq '-')
    {
        $outfile = '';
        $outhandle = *STDOUT{IO};
    }
    else
    {
        $outhandle = IO::File->new($outfile, 'w');
        if (!$outhandle)
        {
            printf(STDERR "%s: error opening output file `%s' for writing: %s\n",
                   $PROG, $outfile, $!);
            return EXIT_FAILURE;
        }
    }


    # do real work
###    my $alias_suffix = $salt eq '' ? '' : '-'.$salt;
    my $alias_suffix = '';
    my $line;
    while (defined($line = $inputhandle->getline()))
    {
        my $username;
        ($username) = split(/:/, $line);
        $success = 
            $outhandle->printf("spam-%s%s:\t\"|'%s' --user '%s' --addspam\"\n",
                               $username, $alias_suffix,
                               DSPAM_BINARY, $username);
        if (!$success)
        {
            printf(STDERR "%s: error writing to the `%s': %s\n",
                   $PROG, $outfile ? $outfile : '(stdout)', $!);
            return EXIT_FAILURE;
        }
        if ($opt_generate_nospam)
        {
            $success = $outhandle->printf("nospam-%s%s:\t\"|'%s' --user '%s' --falsepositive\"\n",
                                          $username, $alias_suffix,
                                          DSPAM_BINARY, $username)
            ;
            if (!$success)
            {
                printf(STDERR "%s: error writing to the `%s': %s\n",
                       $PROG, $outfile ? $outfile : '(stdout)', $!);
                return EXIT_FAILURE;
            }
        }
    }
    $success = $outhandle->close();
    if (!$success)
    {
        printf(STDERR "%s: error writing to the `%s': %s\n",
               $PROG, $outfile ? $outfile : '(stdout)', $!);
        return EXIT_FAILURE;
    }

    $inputhandle->close();

    return EXIT_SUCCESS;
}

my $rc;
$rc = main();
exit($rc);
