mailfs.in 5.3 KB

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