#!/usr/bin/perl -s
# $dotat: scripts/imapls,v 1.13 2013/04/24 08:48:40 fanf2 Exp $
use warnings;
use strict;

use IO::Socket::INET;
use POSIX;

use vars qw( $d $a );

$| = 1;

system '/bin/stty', '-echo' and die "stty -echo failed\n";
print "Password: ";
my $pass = <STDIN>;
chomp $pass;
system '/bin/stty', 'echo' and die "stty echo failed\n";
print "\n";

my $s;

sub get () {
	my $l = $s->getline;
	return if not defined $l;
	print "get< $l" if $d;
	$l =~ s/\s*$//s;
	return $l;
}

sub put (@) {
	print "put> @_\n" if $d;
	return $s->print("@_\r\n");
}

my $cmd_num = 0;

sub cmd (@) {
	put ++$cmd_num, @_;
	my @r;
	my $f = 0;
	for (;;) {
		my $r = get;
		if (not defined $r) {
			die "connection lost" if $f++;
			&login;
			put $cmd_num, @_;
			@r = ();
			$r = get;
		}
		$r =~ /^(\S+)\s+(.*)$/;
		push @r, $2;
		return @r if $1 eq $cmd_num;
	}
}

sub login () {
	my $host = `grep $ENV{USER} /opt/dist/users/cyrus`;
	$host =~ s/^$ENV{USER}\s+(cyrus-\w+-intramail)\s*$/$1/
	    or die "cyrus server not found for $ENV{USER} in /opt/dist/users/cyrus\n";
	$s = new IO::Socket::INET (
		PeerAddr => $host,
		PeerPort => 'imap'
	) or die "connect $host:imap - $!\n";
	my $r = get;
	die "$r" unless $r =~ /^[*] OK /;
	my @r = cmd "LOGIN $ENV{USER} $pass";
	die "@r" unless $r[$#r] =~ /^OK /;
	if ($d) {
		my $q = <STDIN>;
	} else {
		print "!!";
	}
}

login;

for (;;) {
	my %m;
	for my $r (cmd 'LIST "" "*"') {
		next unless $r =~ m{^LIST [(]\\(Noinferiors|HasNoChildren)[)] "/" "?([^"]*)"?$}s;
		my $m = $2;
		my @r = cmd "STATUS \"$m\" (MESSAGES UNSEEN RECENT)";
		"@r" =~ /RECENT (\d+)/;   my $r = $1;
		"@r" =~ /UNSEEN (\d+)/;   my $u = $1;
		"@r" =~ /MESSAGES (\d+)/; my $t = $1;
		$m{$m} = sprintf " %6d %6d %6d  %s\n", $r, $u, $t, $m;
		print "." unless $d;
	}
	print "\n" unless $d;

	for my $m (sort keys %m) {
		print $m{$m}
		   if $m{$m} !~ / 0 /
		  and $m{$m} !~ / spam$/;
	}
	print strftime "%Y-%m-%d %H:%M:%S %z ", localtime;

	if ($a) {
		alarm $a;
	}
	my $q = eval {
		local $SIG{ALRM} = sub {
			die "alarm\n"
		};
		<STDIN>;
	};
	last if (not defined $q and $@ ne "alarm\n")
	     or (    defined $q and $q =~ /^q/);
}
cmd 'LOGOUT';

exit;
