#!/usr/bin/perl # list of mails in a Maildir, like elm's frm does with ordinary mailboxes. # version 1.1 (23jul98) # # Copyright (C) 1998 Roger Espel Llima; # this program can be distributed under the terms of the GNU # General Public License version 2. $version = "1.1"; sub printhelp { return if $veryquiet; print <<"_END_"; frm for Maildir folders, version $version (in perl) Copyright (C) 1998 by Roger Espel Llima; freely redistributable under the terms of the GNU General Public License version 2. use: frm [-h] [-c max] [-n] [-S] [ folder | username ] options: -h --- print help -c max --- at most that many messages -n --- number messages -q --- quiet (no message list) -Q --- very quiet (no errors or anything) -s new|old|read --- only this kind(s) of messages -S --- summarize messages by status exit status: 0 --- matching messages found 1 --- mailbox not empty, but no status match 2 --- empty mailbox 3 --- an error occurred _END_ exit 3; } sub bad { print STDERR "Invalid arguments (try frm -h)\n" unless $veryquiet; exit 3; } sub bail { print STDERR $_[0]."\n" if defined($_[0]) && !$veryquiet; exit 3; } $max = 0; $status_spec = 0; $current = 0; while ($#ARGV >= 0 && $ARGV[0] =~ /^-/) { if ($ARGV[0] eq '-c') { shift; bad if $#ARGV < 0; $max = 0+$ARGV[0]; shift; } elsif ($ARGV[0] eq '-q') { $quiet++; shift; } elsif ($ARGV[0] eq '-Q') { $veryquiet++; shift; } elsif ($ARGV[0] eq '-n') { $number++; shift; } elsif ($ARGV[0] eq '-s') { $status_spec++; shift; if ($ARGV[0] =~ /^r(ead)?/i) { $show_read = 1; } elsif ($ARGV[0] =~ /^n(ew)?$/i) { $show_new = 1; } elsif ($ARGV[0] =~ /(^o(ld)?$)|(^u(nread)?$)/i) { $show_old = 1; } else { bad; } shift; } elsif ($ARGV[0] =~ /^-+h/i) { printhelp; } elsif ($ARGV[0] =~ /^-S/) { $summary++; shift; } else { bad; } } if ($#ARGV >= 0) { $maildir = shift; $maildir = "$maildir/Maildir" if !-d "$maildir/cur" && -d "$maildir/Maildir"; if (!-d $maildir) { $maildir = (getpwnam($maildir))[7] . "/Maildir"; undef $maildir if !-d $maildir; } } else { $maildir = $ENV{"MAILDIR"} || $ENV{"MAIL"} || $ENV{"HOME"}."/Maildir"; } bail "Where is your mail?\n" if !$maildir || !-d $maildir; opendir (NEW, "$maildir/new") or bail "Where is your 'new' mail?\n"; opendir (CUR, "$maildir/cur") or bail "Where is your 'current' mail?\n"; sub datesort (@) { return map { $_->[0] } sort { $a->[1] <=> $b->[1] } map { [ $_, /^(\d+)/ ] } @_; } @new = map { "$maildir/new/$_" } datesort grep { /^[^.]/ } readdir NEW; @cur = map { "$maildir/cur/$_" } datesort grep { /^[^.]/ } readdir CUR; closedir NEW; closedir CUR; @mail = (@cur, @new); @toprint = (); $anymatch = $anymail = 0; %total = ("r" => 0, "n" => 0, "o" => 0); for $file (@mail) { readmail($file); } if ($max && 1+$#toprint > $max) { splice (@toprint, $max); } print join("", map { substr($_, 0, 79)."\n" } reverse @toprint); if ($summary) { my ($before, $n, $string) = (0, 0, "You have "); for $status ("new", "old", "read") { $n = $total{$status}; next unless $n; $string =~ s/ and/,/g; $string .= " and " if $before++; $string .= "$n $status message".($n == 1 ? "" : "s"); } $string .= "no mail" if !$before; print $string, ".\n"; } if ($anymatch) { exit 0; } elsif ($anymail) { exit 1; } else { exit 2; } sub readmail { my $file = shift; my ($from, $subject, $status, $skip) = ('', ''); if ($file =~ /:2,\w*S\w*$/) { $status = "read"; $skip = 1 if $status_spec && !$show_read; } elsif ($file =~ m#new/[^\/]+$#) { $status = "new"; $skip = 1 if $status_spec && !$show_new; } else { $status = "old"; $skip = 1 if $status_spec && !$show_old; } # my $date; # if ($file =~ /\/(...\/\d+)/) { # $date = $1; # } else { # $date = "(????????)"; # } $total{$status}++; $anymail++; return if $skip; $anymatch++; open(MAIL, $file); while () { chomp; last if $_ eq ''; if (/^Subject: /) { $subject = $'; $subject =~ s/\s*$//; $subject =~ s/^\s*//; } if (/^From: /) { my $adr = $'; if ($adr =~ s/\<.*\>//) { $from = $adr; } else { $from = $adr; $from = $1 if $from =~ /\((.*)\)/; } $from =~ s/\s*$//; $from =~ s/^\s*//; $from =~ tr/"//d; } } $from = "(unknown)" if $from eq ''; unless ($quiet) { if ($number) { unshift (@toprint, sprintf("%4d %-20s %s", ++$current, $from, $subject)); #unshift (@toprint, sprintf("$date %4d %-20s %s", ++$current, $from, $subject)); } else { unshift (@toprint, sprintf("%-22s %s", $from, $subject)); #unshift (@toprint, sprintf("$date %-22s %s", $from, $subject)); } } close MAIL; }