home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl
-
- ($program = $0) =~ s,.*/,,;
-
- $| = 1;
-
- &source('sys/ioctl.pl');
-
-
- @SW = ( '-draftmessage draftmessage',
- '-draftfolder +folder',
- '-nodraftfolder',
- '-editor editor',
- '-noeditor',
- '-prompt prompt',
- '-help'
- );
-
-
- %cmds = (
- ' ', 'help',
- "\n", 'help',
- '?', 'help',
- 'E', 'switch-editor',
- 'L', 'display-alternate',
- 'Q', 'quit-delete',
- 's', 'spell',
- 'd', 'quit-delete',
- 'e', 'edit',
- 'h', 'header',
- 't', 'type',
- 'l', 'list',
- 'p', 'push',
- 'q', 'quit',
- 'r', 'refile',
- 'S', 'send',
- 'w', 'whom',
- 'W', 'watch',
- 'y', 'syslog',
- '!', 'shell'
- );
-
- #print "args are $0 $ARGS\n";
- #print "environment:\n";
- #for $key ( sort grep(/^[a-z]+$/, keys %ENV)) {
- #printf "\t%%-12s = %s\n", $key, $ENV{$key};
- #}
-
- if ($ENV{'mhaltmsg'}) {
- unlink '@';
- symlink($ENV{'mhaltmsg'}, '@');
- $linked = 1;
- }
-
- while (($cmd, $fun) = each %cmds) {
- $fun =~ s/-/_/g;
- if (eval "!defined &$fun") {
- print $program, ": warning: key `", $cmd,
- "' bound to undefined function `",$fun, "'\n";
- }
- }
-
- ($draftmessage = $ENV{'mhdraft'});
-
- &mh_profile;
-
- if ($MH{$program}) {
- unshift(@ARGV,split(' ',$MH{$program}));
- }
-
- &mh_parse;
-
- if ($MH{'msg-protect'}) {
- $mask = oct($MH{'msg-protect'});
- umask (~$mask & 0777);
- }
-
- die "$program: only one draft at a time!\n"
- if $#ARGV > 0;
-
- $draftmessage = shift if $#ARGV == 0;
-
- ($editor = $SW{'editor'}) ||
- ($editor = $ENV {'mheditor'}) ||
- ($editor = $MH {'editor'}) ||
- ($editor = $ENV {'EDITOR'}) ||
- ($editor = 'vi');
-
- ($pager = $MH{'listproc'}) ||
- ($pager = $ENV{'PAGER'}) ||
- ($pager = 'more');
-
- $SW{'nodraftfolder'} ||
- ($draftfolder = $SW{'draftfolder'}) ||
- ($draftfolder = $MH {'draft-folder'});
-
- $SW{'noeditor'} = 1 unless $draftmessage;
-
- if ($draftfolder) {
- $draftmessage = &mhpath($draftfolder,
- $SW{'draftmessage'} ? $SW{'draftmessage'} : 'last')
- unless $draftmessage;
- } else {
- $draftmessage = $MH{'path'} . '/' . 'drafts'
- unless $draftmessage;
- }
-
- $SIG{'TERM'} = 'quit';
-
- &edit unless $SW{'noeditor'};
-
- $prompt = 'What now' unless $prompt = $SW{'prompt'};
-
- $SIG{'CONT'} = 'continue';
-
- for (;;) {
- print "\n$prompt? ";
- $cmd = &readtty;
- ($fun = $cmds{$cmd}) =~ s/-/_/g;
- if (defined $cmds{$cmd}) {
- if (eval "defined &$fun") {
- print $cmds{$cmd}, "\n";
- &$fun;
- } else {
- print "$program: can't call undefined subroutine $fun\n";
- }
- } else {
- printf "$cmd -- unknown command: `%s' (0x%02x)\n", $cmd, ord($cmd);
- }
- }
-
- exit (0);
-
-
- # ----------------------------------------------------------------------
- sub mh_parse {
- local(@argdesc) = @SW;
- local($wantarg);
-
- grep(s/(\W)/\\$1/g, @argdesc);
-
- while ($ARGV[0] =~ /^-.+/) {
- $ARGV = shift @ARGV;
-
- unless (@matches = grep(/$ARGV/, @argdesc)) {
- print "$program: unknown option: $ARGV\n";
- exit 1;
- &usage;
- }
-
- for (@matches) { s/\\(\W)/$1/g; }
-
- if ($#matches > $[) {
- print "$program: ambiguous switch $ARGV matches:\n";
- for (@matches) {
- print "\ ", $_, "\n";
- }
- exit 1;
- }
-
- ($switch,$wantarg) = $matches[$[] =~ /^-(\S+)\s*(\S*)/;
-
- $SW{$switch} = $wantarg ? shift @ARGV : 1;
- if ($SW{$switch} =~ /^(['"]).*$/ && $SW{$switch} !~ /^(['"]).*\1$/) {
- do {
- $SW{$switch} .= ' ' . (shift @ARGV);
- } until $#ARGV < 0 || $SW{$switch} =~ /^(['"]).*\1$/;
- $SW{$switch} =~ s/^(['"])(.*)\1$/$2/;
- }
- }
- }
-
- # ----------------------------------------------------------------------
- sub source {
- local($file) = @_;
- local($return) = 0;
-
- $return = do $file;
- die "couldn't do \"$file\": $!" unless defined $return;
- die "couldn't parse \"$file\": $@" if $@;
- die "couldn't run \"$file\"" unless $return;
- }
-
- # ----------------------------------------------------------------------
- sub usage {
- # global $SW
- $pos = 0;
-
- print "syntax: $0 [switches] [files]\n switches are:\n ";
- $pos = 4;
-
- for (@SW) {
- if (($pos += length) > 80) {
- print "\n ";
- $pos = 4 + length;
- }
- print $_, " ";
- $pos++;
- }
- print "\n";
- exit(1);
- }
-
- # ----------------------------------------------------------------------
- sub mh_profile {
- local($PROFILE);
-
- ($PROFILE = $ENV{"MH"}) || ($PROFILE = $ENV{"HOME"} . "/.mh_profile");
-
- open PROFILE || "$0: can't read mh_profile $PROFILE: $!\n";
-
- while (<PROFILE>) {
- next if /^#/;
- next unless ($key, $value) = /([^:\s]+):\s*(.+)/;
- $key =~ tr/A-Z/a-z/;
- $MH{$key} = $value;
- }
- close PROFILE;
- $MH{'path'} = $ENV{'HOME'} . '/' . $MH{'path'};
- }
-
- # ----------------------------------------------------------------------
- sub mhpath {
- local($folder, $msg) = ($_[0], $_[1]);
- local($biggest) = 0;
-
- $folder =~ s/^\+//;
-
- $folder = $MH{'path'} . '/' . $folder
- unless $folder =~ m!^/!;
-
- if (-d $folder) {
- if ($msg eq 'new' || $msg eq 'last') {
- opendir(FOLDER, $folder)
- || die "$program: can't opendir $folder: $!\n";
- while ($msg = readdir(FOLDER)) {
- next unless $msg =~ /^\d+$/;
- $biggest = $msg if $msg > $biggest;
- }
- closedir FOLDER;
- $msg = $biggest + (($msg eq 'new') ? 1 : 0);
- }
- } else {
- if (-t) {{
- print "Create folder \"$folder\"? ";
- chop($answer = <STDIN>);
- last if 'yes' =~ /^$answer/i;
- &exit(0) if 'no' =~ /^$answer/;
- print "$answer: unknown response\n";
- redo;
- }}
- if (defined $MH{'folder-protect'}) {
- $mode = oct($MH{'folder-protect'});
- } else {
- $mode = 0755;
- }
- mkdir($folder,$mode) || die "program: can't mkdir $folder: $!\n";
- }
-
- $folder . '/' . $msg;
- }
-
- # ----------------------------------------------------------------------
- sub readtty {
- local($cmd);
- &cbreak;
- $cmd = getc(STDIN);
- }
-
-
- # ----------------------------------------------------------------------
- sub continue {
- print "$prompt? ";
- &cbreak;
- }
-
- # ----------------------------------------------------------------------
- sub cbreak {
- &set_cbreak(1);
- }
-
- # ----------------------------------------------------------------------
- sub cooked {
- &set_cbreak(0);
- }
-
- # ----------------------------------------------------------------------
- sub set_cbreak {
- local($on) = $_[0];
- local($sgttyb);
-
- $sgttyb_t = 'C4 S' unless $sgttyb_t;
-
- ioctl(STDIN,$TIOCGETP,$sgttyb)
- || die "Can't ioctl TIOCGETP: $!";
-
-
- @ary = unpack($sgttyb_t,$sgttyb);
- if ($on) {
- $ary[4] |= $CBREAK;
- $ary[4] &= ~$ECHO;
- } else {
- $ary[4] &= ~$CBREAK;
- $ary[4] |= $ECHO;
- }
- $sgttyb = pack($sgttyb_t,@ary);
- ioctl(STDIN,$TIOCSETP,$sgttyb)
- || die "Can't ioctl TIOCSETP: $!";
-
- }
-
- # ----------------------------------------------------------------------
- sub help {
- print "Key\tRoutine\n";
- for $key (sort keys %cmds) {
- next if $key =~ /\s/;
- $fun = $cmds{$key};
- $fun =~ s/_/-/g;
- print "$key\t$fun\n";
- }
- }
-
- # ----------------------------------------------------------------------)
- sub quit {
- $SIG{'TTOU'} = "IGNORE";
- print "$program: draft left on $draftmessage\n"
- if -e $draftmessage;
- &cooked;
- &exit(0);
- }
-
- sub exit {
- unlink '@' if $linked;
- exit $_[0];
- }
- # ----------------------------------------------------------------------
- sub edit {
- local($status, $sigs, $next);
- $status = &run($editor,$draftmessage);
- $sigs = $status & 0xff;;
- $status >>= 8;
- if ($status == 255) {
- print "$program: couldn't exec $editor: $!\n";
- return $status;
- }
- $editor = $next if $next = $MH{$editor.'-next'};
- return 0 unless $status;
- print "$program: problems with edit--$draftmessage ",
- $sigs ? "preserved" : "deleted", ".\n" if $status;
- unlink $draftmessage if $status && !$sigs;
- exit 1;
- }
-
- # ----------------------------------------------------------------------
- sub switch_editor {
- local($neweditor);
- if ($neweditor = &prompt('New editor')) {
- $editor = $neweditor;
- &edit;
- } else {
- print "(editor still $editor)\n";
- }
- }
-
- # ----------------------------------------------------------------------
- sub list {
- &run($pager,$draftmessage);
- }
-
- # ----------------------------------------------------------------------
- sub intr { }
- sub run {
- local(@cmd);
- $SIG{'INT'} = $SIG{'QUIT'} = 'intr';
- &cooked;
- @cmd = split(' ',"@_");
- $status = system @cmd;
- &cbreak;
- $mystat = ($status >> 8) & 0xff;
- if ($mystat == 0xff) {
- print "$program: couldn't run \"@_\": $!\n";
- } else {
- print "$program: \"@_\" returned $mystat\n"
- if $mystat;
- }
- $SIG{'INT'} = $SIG{'QUIT'} = 'DEFAULT';
- return $status;
- }
-
-
- # ----------------------------------------------------------------------
- sub quit_delete {
- unlink($draftmessage)
- || warn "$program: unable to unlink $draftmessage: $!\n";
- &quit;
- }
-
- # ----------------------------------------------------------------------
- sub push {
- &exit(&run('send','-push', $draftmessage));
- }
-
- # ----------------------------------------------------------------------
- sub refile {
- local($folder);
- return unless $folder = &prompt("Refile into");
- &run('refile',$folder);
- }
-
- # ----------------------------------------------------------------------
- sub send {
- &exit(&run('send',$draftmessage));
- }
-
- # ----------------------------------------------------------------------
- sub spell {
- local($spell) = $MH{'spellproc'};
- $spell = 'spell' unless $spell;
- &run($spell, $draftmessage);
- }
-
- # ----------------------------------------------------------------------
- sub display_alternate {
- local($alt) = $ENV{'mhaltmsg'};
- if (! $alt) {
- print "No alternate message to display\n";
- } else {
- &run($pager,$alt);
- }
- }
-
- # ----------------------------------------------------------------------
- sub prompt {
- local($prompt) = $_[0];
- local($retval);
- &cooked;
- print "$prompt? ";
- chop($retval = <STDIN>);
- return $retval;
- }
-
- # ----------------------------------------------------------------------
- sub whom {
- &run('whom', $draftmessage);
- }
-
- # ----------------------------------------------------------------------
- sub watch {
- &exit(&run('send -nopush -watch -verbose', $draftmessage));
- }
-
- # ----------------------------------------------------------------------
- sub syslog {
- &run('tail -f /usr/spool/mqueue/syslog');
- }
-
- # ----------------------------------------------------------------------
- sub header {
- if (!open draftmessage) {
- warn "$program: no $draft message\n";
- return;
- }
- while (<draftmessage>) {
- last if /^-*$/;
- print;
- }
- close draftmessage;
- }
-
- # ----------------------------------------------------------------------
- sub type {
- if (!open draftmessage) {
- warn "$program: no $draft message\n";
- return;
- }
-
- print while <draftmessage>;
-
- close draftmessage;
- }
-
- # ----------------------------------------------------------------------
- sub shell {
- local($cmd);
- return unless $cmd = &prompt('Shell command');
- &run($cmd);
- }
-