#!/usr/bin/perl
###############################################################################
# a simple mail counter _ _   _  _ 
#   ___ _ __ ___   __ _(_) | | || |     by Chip Marshall <chip@chocobo.cx>  
#  / __| '_ ` _ \ / _` | | | | || |_    http://www.chocobo.cx/chip/
# | (__| | | | | | (_| | | | |__   _|   $Revision: 1.4 $
#  \___|_| |_| |_|\__,_|_|_|    |_| .0  Read LICENSE for license info. duh.
###############################################################################

### Initializations
use Env qw(HOME);
use vars qw($VERSION);
use strict;
use Getopt::Long;

use constant DEFAULT_CONFIG	=> "$HOME/.cmailrc";
use constant DEFAULT_OUTPUT => 'plain';

$VERSION = '4.02';

### Parse command line options
my %options = ();

GetOptions( \%options, "config=s", "output=s", "verbose+" );

my $config	= $options{'config'}	|| DEFAULT_CONFIG;
my $verbose	= $options{'verbose'}	|| 0;

### Read in config file
my %config = ();
my @mailboxes = ();
my $x = 0;

warn "Reading config file $config.\n" if $verbose > 1;

open(CONFIG, "<$config") or die "Can't open config file '$config': $!\n";
foreach my $line (<CONFIG>) {
	$x++;
	chomp $line;
	next if $line =~ /^\s*(#.*)?$/;	# nothing but a comment

	warn "Line: '$line'\n" if $verbose > 2;

	# set lines - form is 'set var value'
	if ( $line =~ /^set\s+([^\s]+)\s+([^\s]+)\s*$/ ) {
		warn "Setting '$1' to '$2'.\n" if $verbose > 1;
		$config{$1} = $2;
		next;
	}

	# mailbox lines - form is 'uri name option'
	if ( $line =~ m{^([a-z0-9]+)(://[^\s]+)\t+([^\t]+)\t*([^\t]*)\s*$} ) {
		my $type = $1;

		eval "require CMail\::In\::$type";
		die "Can't load input module '$type': $@\n" if $@;

		warn "Adding mailbox '$1$2' as '$3' with '$4'.\n" if $verbose > 1;

		my $object = "CMail::In::$type"->new(
			'uri'		=>	$1.$2,
			'name'		=>	$3,
			'option'	=>	$4,
			'verbose'	=>	$verbose,
		);

		push @mailboxes, $object;
		next;
	}

	# didn't match anything
	close CONFIG;
	die "Unknown command in '$config' line $x: '$line'\n";
}
close CONFIG;

# Set output module here, so that it can be set in config file
# or overridden on command line
my $output	= $options{'output'} || $config{'output'} || DEFAULT_OUTPUT;

### Initialize output module
warn "Loading $output output module.\n" if $verbose > 1;
eval "require CMail\::Out\::$output";
die "Can't load output module '$output': $@\n" if $@;
my $out = "CMail::Out::$output"->new(
	'verbose'	=> $verbose,
	'mailboxes'	=> \@mailboxes,
);

### Check mailboxes and display the count
foreach my $mailbox (@mailboxes) {
	$out->display($mailbox, $mailbox->count() );
}

exit;
__END__

=head1 NAME

B<cmail> - a simple and modular mail counter

=head1 SYNOPSIS

B<cmail> [B<--verbose>] [B<--config=>F<config>] [B<--output=>F<output>]

=head1 DESCRIPTION

cmail reads in ~/.cmailrc for a list of mailboxes and reads each box to get
a count of the mail in it. It then displays this information to the user,
usually as a name, total mail count, and new mail count.

Command line options are:

=over 4

=item B<--verbose>

increases the verbosity of cmail, can be specified multiple times to increase
verbosity even more.

=item B<--config=>F<config>

specify a config file other than ~/.cmailrc

=item B<--output=>F<output>

specify an output module on the command line. defaults to plain, and can
also be set in the config file.

=back

All options can be shortened to the shortest unique string. (For example,
'-v' instead of '--verbose'.)

=head1 CONFIGURATION FILE

The cmail configuration file contains a number of lines, each describing
either a mailbox, or an option setting. For options, the format is:

  set variable value

This can be used to set the output module, for instance:

  set output color

Mailbox lines are only slightly more complicated. They are a series of 3
fields, seperated by 1 or more tabs. The fields are mailbox URI,
descriptive name, and output options. For example, the folling is an
entry for /var/mail/chip:

  mbox:///var/mail/chip         Inbox   green

The default input modules are mbox, maildir, pop3, and imap. For pop3
and imap, you also need to specify a username and password. With
imap, you can also specify a mailbox, if none is provided, it will
default to INBOX.

  pop3://user:pass@host/
  imap://user:pass@host/INBOX

To use pop3 or imap over SSL, just add an 's' to the end, so the above
example would become;

  pop3s://user:pass@host/
  imaps://user:pass@host/INBOX

For information on the options field, consult the documentation of the
output module you are using, such as L<CMail::Out::color>.

=head1 MODULES

There are two types of modules in cmail4, input modules and output modules.

Input modules are stored in the CMail::In hierarchy and are used for reading
from mailboxes. They are responsible for counting the mail. For information
on writing an Input modules, read L<CMail::In::Base>.

Output modules are stored in the CMail::Out hierarchy and are used for
displaying the mail count. The base distribution only contains two output
modules, plain and color, which both print to the console, but color uses
Term::ANSIColor to produce color codes. For information on writing an Output
modules, read L<CMail::Out::Base>.

=head1 FILES

=over 4

=item F<~/.cmailrc>

cmail configuration file

=back

=head1 AUTHOR

Chip Marshall E<lt>chip@chocobo.cxE<gt> http://www.chocobo.cx/chip/

=head1 CONTRIBUTORS

=item Ben April E<lt>ben@jlc.netE<gt>

Contributed the original color code.

=item David McNett E<lt>nugget@slacker.comE<gt>

Contributed the atime preservation code for mbox mailfiles. This keeps
the new mail detection in mailreaders like mutt happy.


syntax highlighted by Code2HTML, v. 0.9.1