#!/usr/bin/perl -w
#
# Script which allows qmail users with a dial-up connection 
# to read, edit, remove mail in remote queue.
#
# Use sudo to use this script if not root.
#
# Released under the GPL (See http://www.gnu.org/) 
# Copyright: Frank Shute. 23/6/2003.
#
# It works for me but use this at your own risk! 
#
# Any bugs? email me: frank@esperance-linux.co.uk
#

# Apart from Term::ANSIcolor these modules all come with perl 5
#
# For FreeBSD:
#
# cd /usr/ports/devel/p5-Term-ANSIColor
# make install clean
#

use Time::localtime;
use Getopt::Std;
use vars qw( $opt_h $opt_p $opt_d $opt_e $opt_l $opt_f );
use Env qw(PAGER);
use Cwd;
use Term::ANSIColor;


# Initialise some variables

local $rqueue = "/var/qmail/alias/pppdir/new";
local $localdir = cwd();
local $file_no = 0;
local $counter = 0;
local $editor = "vim";   

# You might have to change the above line & appropriate
# line below if you don't use a sensible editor ;-)


# get & set commandline options (-f takes an integer as an arg)

getopts('lpedhf:');


# Read outgoing queue

read_queue();


# do whatever for the various commandline options

SWITCH: {
  # list outgoing messages
    
   if ( $opt_l ) 
        {
        list_mail();
        }
    
  # help message
    
  if ( $opt_h ) 
        {
        help_message();
        } 
    
  # edit message
    
  if (( $opt_e)  && ( $opt_f <= $file_no )) 
        {
      my $file_req = --$opt_f;
      system "$editor \"+syntax off\" $outgoing[$file_req]";
            
      # delete backup file
        
      if ( -e "$outgoing[$file_req]~" ) 
            {
            unlink "$outgoing[$file_req]~";
            print "Deleted: $rqueue/$outgoing[$file_req]~\n";
            } else {
          return 0;
            }
        }
    
  # page message
    
  if (($opt_p) && ( $opt_f <= $file_no ))
        {
        print "Paging message_no: ", $opt_f, "\n";
      my $file_req = --$opt_f;
        sleep 1;
      system "$PAGER $outgoing[$file_req]";
        }
    
  # delete message
    
  if (($opt_d) && ( $opt_f <= $file_no ))
        {
        print "Deleting message ", $opt_f, "\n";
      my $file_req = --$opt_f;
        unlink "$outgoing[$file_req]";
        print "Deleted: ",
              "$rqueue/$outgoing[$file_req]\n";
        read_queue();
        list_mail();
        } 
    
  # file to delete/edit/page doesn't exist
    
  if ((( $opt_d ) || ( $opt_e ) || ( $opt_p )
          && ( $opt_f)) 
          && ( $opt_f  > $file_no))
        {
        print "Message number $opt_f doesn't exist\n";
        }

  # fall through :(
    
  if ( 1 != 1 )
        {
        help_message();
        }
}

# Change back to original dir
    
chdir $localdir;

# End of main


#---------------------#
#### SUB FUNCTIONS ####
#---------------------#

sub help_message {
          print "\nUsage:            [-l]  list outgoing\n",
            "       [-e -f number ]  edit msg_no\n",
            "       [-d -f number ]  delete msg_no\n",
            "       [-p -f number ]  view msg_no\n",
            "                  [-h]  this help\n\n";
    }


# This sub formats secs/mins correctly

sub frmt_time {
if ( $_[0] <= 9 )
        {
    $the_time = $_[0];
        $the_time = "0" . $the_time;
        return $the_time;
        }
        else
        {
    $the_time = $_[0];
        return $the_time;
        }
}


# Grab the Delivered-To: address

sub get_address {
  open(MYFILE, $file) or die "Can't open $file: $!\n";

 LINE: while (defined($line = <MYFILE>))
        {
        chomp $line;
      if ( $line =~ m/^Delivered-To:/ )
            {
            $line =~ s/^Delivered-To: alias-ppp-//;
          last LINE;
            }
        }
  close MYFILE;
  return $line;
}


# list outgoing

sub list_mail {
  if (@outgoing) 
        {    # array contains something
        print color 'bold';
        print "\nTime Sent:\tDate Sent:",
              "\tMsg No:\t\t  To:\n";
        print color 'reset';
        }else{      # contains nothing
        print color 'bold';
        print "No outgoing mail\n";
        print color 'reset';
        }
  # iterate over each file
          foreach $file (@outgoing) 
        {
        ++$counter;
        @file_status = stat $file;
  # Get time created in epoch seconds...
        $time_created = $file_status[9];
  # Convert to localtime
        $tm = localtime($time_created);
      local $the_day = $tm->mday;
      local $the_month = $tm->mon + 1;
      local $the_hour = $tm->hour;
      local $the_minute = $tm->min;
      local $the_sec = $tm->sec;
  # Get address
        $address = get_address();
  # minutes & secs need formatting by subfunction
        $the_minute = frmt_time($the_minute);
        $the_sec = frmt_time($the_sec);
  # print it's details in format required
    print " $the_hour:$the_minute:$the_sec\t",
          "   $the_day/$the_month\t\t   $counter\t   $address\n";
    }
    print "\n";
}


# Read outgoing queue

sub read_queue {
    chdir $rqueue;
    opendir(DIR, $rqueue) or die "Can't open directory $rqueue: $!\n";

  # Stick any files/outgoing mail (apart from . & ..) in an array

    @outgoing = grep !/^\.\.?$/, readdir(DIR);

  # Count them

  foreach $file (@outgoing) {
        $file_no++;
        }

    closedir(DIR);
}