#!/usr/bin/perl -w # # ispeller.pl # Phil Hollenback # philiph@pobox.com # 5/24/98 # # Purpose: A program to make running ispell on mail messages # a bit easier. # # Arguments: -x - invoke mutt-mode (assume the message doesn't have # a header). # file - mail message file to run ispell on. # # Assumptions: file contains just one mail message, with an optional # header. # # Process: 1. original message is copied to a temp file. Only the # subject is copied from the header. Quoted text is # skipped. Processing stops on the signature (delineated # by '--' on a blank line). # 2. ispell is run on temp file. # 3. Temp file and original file are merged into a final temp # file. # 4. Final temp file is copied over original file. # Get the real name of the program. @name_array = split /\//, $0; $progname = pop @name_array; # # Variables # $ispell = "ispell"; $tmp_msg = "/usr/tmp/$progname-msg-tmp.$$"; $final_msg = "/usr/tmp/$progname-msg-final.$$"; $quote_chars = '[>\|}]+'; # # End variables # # Check command line arguments. if ( ($#ARGV == 1) && ($ARGV[0] eq '-x') ) { $mutt_mode = 1; $orig_msg = $ARGV[1]; } elsif ( $#ARGV == 0 ) { $mutt_mode = 0; $orig_msg = $ARGV[0]; } else { die "Usage: $progname [-x] file\n"; } # Open original file and first temp file. open ORIG_MSG, $orig_msg or die "Can't open message file $orig_msg\n"; open TMP_MSG, ">$tmp_msg" or die "Can't create temporary file $tmp_msg\n"; # Skip everything in the header except for the subject. # This is skipped in mutt-mode. if ( ! $mutt_mode ) { while () { last if /^ *$/; if ( /^Subject:.*/i ) { print TMP_MSG; } else { print TMP_MSG "\n"; } } print TMP_MSG "\n"; } # Read the body, skipping quoted text. # Stop at the signature. while () { last if /^-- *$/; if ( /^$quote_chars/ ) { print TMP_MSG "\n"; } else { print TMP_MSG; } } # Pad the temporary message file with blanks so it matches the # length of the original file. while () { print TMP_MSG "\n"; } print TMP_MSG "\n"; close TMP_MSG; # Actually run ispell. system("$ispell -x $tmp_msg") == 0 or die "Can't run ispell.\n"; # Compare the resultant file with the original message and write # a final message that combines the two. seek ORIG_MSG, 0, 0; open TMP_MSG, $tmp_msg or die "Can't open temporary file $tmp_msg\n"; open FINAL_MSG, ">$final_msg" or die "Can't open final temporary message file $final_msg\n"; $tmp_line = ""; # For each line in the temp file: if line has text on it, copy line # into final temp file. Otherwise, copy corresponding line from the # original file into the final temp file. This merges changes from # ispell. This is also why the temp file is padded to the length of # the original file. while () { $tmp_line = ; if ( $tmp_line ne "\n" ) { print FINAL_MSG $tmp_line; } else { print FINAL_MSG $_; } } # We can now get rid of the first temporary file. close TMP_MSG; unlink $tmp_msg or print STDERR "Warning: Couldn't unlink tmpfile $tmp_msg\n"; # Home stretch. Copy the final temp file over the original file # (check for failure!). Get rid of the temp file. close FINAL_MSG; system("cp $final_msg $orig_msg") == 0 or die "Couldn't copy final temp file $final_msg over original file $orig_msg\n"; unlink $final_msg or print STDERR "Warning: couldn't unlink tmpfile $final_msg\n";; exit 0;