#!/bin/perl #-----------------------------------------------------------------------------# # File: n2folder # Function: Convert VM/CMS notebook to Pine mail folder # Usage: # n2folder [-q] [-m maildir] [-r rscsnodes] [-h host] [notebook]... # # If no notebooks are specified, this program reads from standard input # and writes to standard output. -q means quiet. If -m maildir # is not identified, ~/mail/ is presumed as the mail folder directory. # # Folder format requires (1) a header line like... # From someplace Fri Sep 9 09:19:46 1994 # (2) the date here must be in Unix cdate format, # and (3) each note ends with one null (not just blank) line. # Besides insuring this, this program also attemps to reformat VM/CMS note # header email addresses and dates into RFC822 format. # # Update: 1995-07-24 # By: ccgreg@missouri.edu #-----------------------------------------------------------------------------# # The case-insensitive regular expression value of -r $rscsnodes is one or more # RSCS node names, which will be converted to the single internet-style # hostname -h $internethost. -h $internethost will also be used to form # the address where no hostname was given. $rscsnodes ='^mizzou1$|^umcvmb$|^umvma$'; $internethost ='Mizzou1.Missouri.edu'; ### Let's hope you don't need to change more than the above. ### require 'timelocal.pl'; require 'ctime.pl'; $verbose = 1; $blankdelim = 1; # -1/-2 Number of blank lines expected at end of note. $error=0; $script = $0; if ($script =~ /.+\/(.*)/) { $script=$1;} $MONTHS='jan feb mar apr may jun jul aug sep oct nov dec'; # Parse options: foreach $i (0 .. $#ARGV) { if (@ARGV[$i] eq '-0') {$blankdelim=0;} elsif (@ARGV[$i] eq '-1') {$blankdelim=1;} elsif (@ARGV[$i] eq '-2') {$blankdelim=2;} elsif (@ARGV[$i] eq '-q') {$verbose=0;} elsif (@ARGV[$i] eq '-m') {$i++; $maildir = @ARGV[$i]; } elsif (@ARGV[$i] eq '-r') {$i++; $rscsnodes = @ARGV[$i]; } elsif (@ARGV[$i] eq '-h') {$i++; $internethost = @ARGV[$i]; } elsif (@ARGV[$i] =~ /^-/) { print STDERR "usage: $script [-q] [-m maildir]" . " [-r rscsnodes] [-h host] [notebook]...\n"; $error++; } else { $infn = @ARGV[$i]; push (@filelist,$infn); if (! (-r $infn && -f $infn )) { print "Can't read file $infn, $!\n"; $error++; } } } if ($error != 0) {exit 1;} # Check existence & permissions of input and output files # ($login,$x,$x,$x,$x,$x,$x,$home,$x)=getpwuid($>); if (!defined($maildir)) { $maildir = $home . "/mail";} if (defined(@filelist)) { if (! -e $maildir) { mkdir($maildir,'700') || die "Can't create output directory $maildir, $!\n"; } if (! (-d $maildir && -w $maildir && -x $maildir) ) { die "Can't write to directory $maildir $!\n"; } foreach $file (@filelist) { if (-e "$maildir/$file") { print STDERR "\n$script: $maildir/$file\n" . "Output folder exists! Quit/Append/Remove (q/a/r)? "; $ans = getc; if ($ans =~ /^q/i) {exit;} elsif ($ans =~ /^a/i) {} elsif ($ans =~ /^r/i) { unlink "$maildir/$file"; } else {redo}; } } } else {@filelist = ('&STDIN');} ## Main loop: convert each requested notebook ## foreach $infn (@filelist) { open(INFILE,"<$infn") || die "Can't open input file $infn"; "/$infn" =~ /.*\//; $newfn = $'; if ($infn eq '&STDIN') {$outfn='&STDOUT';} else {$outfn = "$maildir/$newfn";} open(OUTFILE,">>$outfn") || die "Can't open output file $outfn"; if ($verbose) {print STDERR "$script: converting $infn ...\n";} $nnotes = 0; $blanksout=9; #counts number of blank lines already output. # Read and dispatch each line of input: while () { if (/^\s*$/) { # we've read a blank line if ($inheader) { # End of header, output accumulated lines $nnotes++; print OUTFILE "From $from $date\n"; if ($verbose) {print STDERR "$script: $nnotes From $from $date\n";} foreach $line (@hdrlines) { print OUTFILE $line,"\n"; } @hdrlines=(); $inheader=0; } $blanksout++; print OUTFILE "\n"; } elsif (/^={72,}/) { # VM/CMS Note separator $inheader=1; while ($blanksout < 2) { print OUTFILE "\n"; $blanksout++; } $from=$login; $date='Mon Jan 1 00:00:00 1970'; $blanksout=0; } elsif ($inheader) { chop; if (/^Date: /i) { $date=&rfcdate; $inaddr=0;} elsif (/^From: /i) { $from=&address; $inaddr=1;} elsif (/^To: |^Cc: /i) { &address; $inaddr=1;} # Reply-to, Bcc, etc. don't need CMS Note conversion. elsif ($inaddr && (! /^\S+: /)) { #addr continuation &address; #append any missing comma to preceding header: if (@hdrlines[$#hdrlines] !~ /,\s*$/) { @hdrlines[$#hdrlines] .= ','; } } else {$inaddr=0;} push (@hdrlines, $_); } else { print OUTFILE; $blanksout=0; } } #while INFILE# while ($blanksout < 2) { print OUTFILE "\n"; $blanksout++; } # Done with this file. close INFILE; close OUTFILE; if ($verbose) { print STDERR "$script: $nnotes notes converted to $outfn\n\n"; } } #main loop# exit; # program n2folder # # Try to convert IBM VM/CMS NOTE addresses to RFC822 # Input $_ is line containing addresses to convert. # $_ may return modified, with proper addresses, # Return value is first email address found, converted to RFC822 form. sub address { @line = split; if (@line[$#line-1] =~ /at/i) { # VM/CMS style address: userid at node $userid = @line[$#line-2]; $node = @line[$#line]; if ($node =~ /$rscsnodes/i) { # convert known local node(s) $node=$internethost; } else {$node = "$node.bitnet";} # otherwise use .bitnet gateway $email = "$userid\@$node"; $#line = $#line - 3; $_ = join(' ',@line) . " <$email>"; } elsif (($email) = grep(/\S+\@\S+/,@line)) { # Blindly assume "@" implies RFC822 if ($email eq '') {$email = 'unknown';} else {$email =~ tr/<>,//d;} } else { # VM/CMS style local address: userid[, userid]... ($email = "@line[1]\@$internethost") =~ tr/,//d; $_ = shift(@line); foreach $addr (@line) { $comma = substr(' ,',($addr =~ tr/,//d),1); $_ .= " $addr\@$internethost$comma"; } } return ( $email ); } # end of sub address # # Folder headers require cdate format... # From someuser Sat Feb 1 14:02:47 1995 # So try to extract date from the Date: line # Return correct cdate format for even if content is bogus. # Also return typical RFC 822 format of original Date: line. # Typical (!) input formats: # RFC 822... Date: Wed, 1 Feb 1995 14:02:46 CST # VM/CMS.... Date: 28 November 94, 15:25:00 CST sub rfcdate { @line = split; shift(@line); # Discard Date: tag if ($#line > 4) {shift(@line);} # Discard day of week $mday=@line[0]; ($mo=substr(@line[1],0,3)) =~ tr/A-Z/a-z/; $mon= index($MONTHS,$mo)/4; ($yr = @line[2]) =~ tr/,//d; if ($yr > 1969 & $yr < 2000) {$yr=$yr-1900;} # I'm taking that cruise! ($hh,$mm,$ss) = split(/:/,@line[3]); $date = &ctime( &timelocal(($ss,$mm,$hh,$mday,$mon,$yr)) ); chop $date; $_ = "Date: " . substr($date,0,3) . "," . substr($date,7,3) . substr($date,3,4) . substr($date,19,5) . substr($date,10,10) ; return ($date); } # end of sub rfcdate # # end of program n2folder #