#!/usr/bin/perl # MC extfs for (possibly compressed) Berkeley style mailbox files # Peter Daum (Jan 1998, mc-4.1.24) $zcat="zcat"; # gunzip to stdout $bzcat="bzip2 -dc"; # bunzip2 to stdout $file="file"; # "file" command $TZ='GMT'; # default timezone (for Date module) if (eval "require Date::Parse") { # fancy date parsing available? import Date::Parse; $parse_date= sub { local $_ =localtime(str2time($_[0],$TZ)); s/^... (.+) (\d\d:\d\d):\d\d (\d\d\d\d)$/$1 $3 $2/; return $_; } } else { # use "light" version $parse_date= sub { # assumes something like: Mon, 5 Jan 1998 16:08:19 +0200 (GMT+0200) # if you have mails with another date format, add it here if (/(\d\d?) ([A-Z][a-z][a-z]) (\d\d\d\d) (\d\d?:\d\d)/) { return "$2 $1 $3 $4"; } # Y2K bug. # Date: Mon, 27 Mar 100 16:30:47 +0000 (GMT) if (/(\d\d?) ([A-Z][a-z][a-z]) (1?\d\d) (\d\d?:\d\d)/) { $correct_year = 1900 + $3; if ($correct_year < 1970) { $correct_year += 100; } return "$2 $1 $correct_year $4"; } # AOLMail(SM). # Date: Sat Jul 01 10:06:06 2000 if (/([A-Z][a-z][a-z]) (\d\d?) (\d\d?:\d\d)(:\d\d)? (\d\d\d\d)/) { return "$1 $2 $5 $3"; } # Fallback return "Jan 1 1980 00:00"; } } sub process_header { while () { s/\r$//; last if /^$/; die "unexpected EOF\n" if eof; if (/^Date:\s(.*)$/) { $date=&$parse_date($1); } elsif (/^Subject:\s(.*)$/) { $subj=$1; $subj=~ s/^(re:\s?)+//gi; # no leading Re: $subj=~ tr/a-zA-Z0-9//cd; # strip all "special" characters } elsif (/^From:\s.*?(\w+)\@/) { $from=$1; } elsif (/^To:\s.*?(\w+)\@/) { $to=$1; } } } sub print_dir_line { $from=$to if ($from eq $user); # otherwise, it would look pretty boring printf "-r-------- 1 $< $< %d %s %3.3d_%.16s\n", $line, $date, $msg_nr, "${from}_${subj}"; } sub mailfs_list { my $blank = 1; $user=$ENV{USER}||getlogin||getpwuid($<) || "nobody"; while(1) { $_=; s/\r$//; if (!defined($_)) { # EOF print_dir_line; exit 0; } if($blank && /^From /) { # Start of header print_dir_line unless (!$msg_nr); $msg_nr++; ($from,$to,$subj,$date)=("none","none","none", "01-01-80"); process_header; $line=$blank= 0; } else { $line++; $blank= /^$/; } } } sub mailfs_copyout { my($source,$dest)=@_; exit 1 unless (open STDOUT, ">$dest"); ($nr)= ($source =~ /^(\d+)/); # extract message number from "filename" my $blank = 1; while() { s/\r$//; if($blank && /^From /) { $msg_nr++; exit(0) if ($msg_nr > $nr); $blank= 0; } else { $blank= /^$/; } print if ($msg_nr == $nr); } } # main { $msg_nr=0; $cmd=shift; $mbox_name=shift; $_=`$file $mbox_name`; if (/gzip/) { exit 1 unless (open IN, "$zcat $mbox_name|"); } elsif (/bzip/) { exit 1 unless (open IN, "$bzcat $mbox_name|"); } else { exit 1 unless (open IN, "<$mbox_name"); } umask 077; if($cmd eq "list") { &mailfs_list; exit 0; } elsif($cmd eq "copyout") { &mailfs_copyout(@ARGV); exit 0; } exit 1;