mailfs.in 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #! @PERL@ -w
  2. use bytes;
  3. # MC extfs for (possibly compressed) Berkeley style mailbox files
  4. # Peter Daum <gator@cs.tu-berlin.de> (Jan 1998, mc-4.1.24)
  5. $zcat="zcat"; # gunzip to stdout
  6. $bzcat="bzip2 -dc"; # bunzip2 to stdout
  7. $file="file"; # "file" command
  8. $TZ='GMT'; # default timezone (for Date module)
  9. if (eval "require Date::Parse") {
  10. import Date::Parse;
  11. $parse_date=
  12. sub {
  13. local $ftime = str2time($_[0],$TZ);
  14. $_ = localtime($ftime);
  15. /^(...) (...) ([ \d]\d) (\d\d:\d\d):\d\d (\d\d\d\d)$/;
  16. if ($ftime + 6 * 30 * 24 * 60 * 60 < $now ||
  17. $ftime + 60 * 60 > $now) {
  18. return "$2 $3 $5";
  19. } else {
  20. return "$2 $3 $4";
  21. }
  22. }
  23. } elsif (eval "require Date::Manip") {
  24. import Date::Manip;
  25. $parse_date=
  26. sub {
  27. return UnixDate($_[0], "%l"); # "ls -l" format
  28. }
  29. } else { # use "light" version
  30. $parse_date= sub {
  31. local $mstring='GeeJanFebMarAprMayJunJulAugSepOctNovDec';
  32. # assumes something like: Mon, 5 Jan 1998 16:08:19 +0200 (GMT+0200)
  33. # if you have mails with another date format, add it here
  34. if (/(\d\d?) ([A-Z][a-z][a-z]) (\d\d\d\d) (\d\d?):(\d\d)/) {
  35. $day = $1;
  36. $month = $2;
  37. $mon = index($mstring,$month) / 3;
  38. $year = $3;
  39. $hour = $4;
  40. $min = $5;
  41. # pass time not year for files younger than roughly 6 months
  42. # but not for files with dates more than 1-2 hours in the future
  43. if ($year * 12 + $mon > $thisyear * 12 + $thismon - 7 &&
  44. $year * 12 + $mon <= $thisyear * 12 + $thismon &&
  45. ! (($year * 12 + $mon) * 31 + $day ==
  46. ($thisyear * 12 + $thismon) * 31 + $thisday &&
  47. $hour > $thishour + 2)) {
  48. return "$month $day $hour:$min";
  49. } else {
  50. return "$month $day $year";
  51. }
  52. }
  53. # Y2K bug.
  54. # Date: Mon, 27 Mar 100 16:30:47 +0000 (GMT)
  55. if (/(\d\d?) ([A-Z][a-z][a-z]) (1?\d\d) (\d\d?):(\d\d)/) {
  56. $day = $1;
  57. $month = $2;
  58. $mon = index($mstring,$month) / 3;
  59. $year = 1900 + $3;
  60. $hour = $4;
  61. $min = $5;
  62. if ($year < 1970) {
  63. $year += 100;
  64. }
  65. if ($year * 12 + $mon > $thisyear * 12 + $thismon - 7 &&
  66. $year * 12 + $mon <= $thisyear * 12 + $thismon &&
  67. ! (($year * 12 + $mon) * 31 + $day ==
  68. ($thisyear * 12 + $thismon) * 31 + $thisday &&
  69. $hour > $thishour + 2)) {
  70. return "$month $day $hour:$min";
  71. } else {
  72. return "$month $day $year";
  73. }
  74. }
  75. # AOLMail(SM).
  76. # Date: Sat Jul 01 10:06:06 2000
  77. if (/([A-Z][a-z][a-z]) (\d\d?) (\d\d?):(\d\d)(:\d\d)? (\d\d\d\d)/) {
  78. $month = $1;
  79. $mon = index($mstring,$month) / 3;
  80. $day = $2;
  81. $hour = $3;
  82. $min = $4;
  83. $year = $6;
  84. if ($year * 12 + $mon > $thisyear * 12 + $thismon - 7 &&
  85. $year * 12 + $mon <= $thisyear * 12 + $thismon &&
  86. ! (($year * 12 + $mon) * 31 + $day ==
  87. ($thisyear * 12 + $thismon) * 31 + $thisday &&
  88. $hour > $thishour + 2)) {
  89. return "$month $day $hour:$min";
  90. } else {
  91. return "$month $day $year";
  92. }
  93. }
  94. # Fallback
  95. return $fallback;
  96. }
  97. }
  98. sub process_header {
  99. while (<IN>) {
  100. $size+=length;
  101. s/\r$//;
  102. last if /^$/;
  103. die "unexpected EOF\n" if eof;
  104. if (/^date:\s(.*)$/i) {
  105. $date=&$parse_date($1);
  106. } elsif (/^subject:\s(.*)$/i) {
  107. $subj=lc($1);
  108. $subj=~ s/^(re:\s?)+//gi; # no leading Re:
  109. $subj=~ tr/a-zA-Z0-9//cd; # strip all "special" characters
  110. } elsif (/^from:\s.*?(\w+)\@/i) {
  111. $from=$1;
  112. } elsif (/^to:\s.*?(\w+)\@/i) {
  113. $to=lc($1);
  114. }
  115. }
  116. }
  117. sub print_dir_line {
  118. $from=$to if ($from eq $user); # otherwise, it would look pretty boring
  119. $date=localtime(time) if (!defined $date);
  120. printf "-r-------- 1 $< $< %d %s %3.3d_%.25s\n",
  121. $size, $date, $msg_nr, "${from}_${subj}";
  122. }
  123. sub mailfs_list {
  124. my $blank = 1;
  125. $user=$ENV{USER}||getlogin||getpwuid($<) || "nobody";
  126. while(<IN>) {
  127. s/\r$//;
  128. if($blank && /^from\s+\w+(\.\w+)*@/i) { # Start of header
  129. print_dir_line unless (!$msg_nr);
  130. $size=length;
  131. $msg_nr++;
  132. ($from,$to,$subj,$date)=("none","none","none", "01-01-80");
  133. process_header;
  134. $line=$blank=0;
  135. } else {
  136. $size+=length;
  137. $line++;
  138. $blank= /^$/;
  139. }
  140. }
  141. print_dir_line unless (!$msg_nr);
  142. exit 0;
  143. }
  144. sub mailfs_copyout {
  145. my($source,$dest)=@_;
  146. exit 1 unless (open STDOUT, ">$dest");
  147. ($nr)= ($source =~ /^(\d+)/); # extract message number from "filename"
  148. my $blank = 1;
  149. while(<IN>) {
  150. s/\r$//;
  151. if($blank && /^from\s+\w+(\.\w+)*@/i) {
  152. $msg_nr++;
  153. exit(0) if ($msg_nr > $nr);
  154. $blank= 0;
  155. } else {
  156. $blank= /^$/;
  157. }
  158. print if ($msg_nr == $nr);
  159. }
  160. }
  161. # main {
  162. exit 1 unless ($#ARGV >= 1);
  163. $msg_nr=0;
  164. $cmd=shift;
  165. $mbox_name=shift;
  166. my $mbox_qname = quotemeta ($mbox_name);
  167. $_=`$file $mbox_qname`;
  168. if (/gzip/) {
  169. exit 1 unless (open IN, "$zcat $mbox_qname|");
  170. } elsif (/bzip/) {
  171. exit 1 unless (open IN, "$bzcat $mbox_qname|");
  172. } else {
  173. exit 1 unless (open IN, "<$mbox_name");
  174. }
  175. umask 077;
  176. if($cmd eq "list") {
  177. $now = time;
  178. $_ = localtime($now);
  179. /^... (... [ \d]\d \d\d:\d\d):\d\d \d\d\d\d$/;
  180. $fallback = $1;
  181. $nowstring=`date "+%Y %m %d %H"`;
  182. ($thisyear, $thismon, $thisday, $thishour) = split(/ /, $nowstring);
  183. &mailfs_list;
  184. exit 0;
  185. }
  186. elsif($cmd eq "copyout") { &mailfs_copyout(@ARGV); exit 0; }
  187. exit 1;