home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / perl / scripts-convex / now-what < prev    next >
Encoding:
Text File  |  1991-06-24  |  10.9 KB  |  493 lines

  1. #!/usr/bin/perl
  2.  
  3. ($program = $0) =~ s,.*/,,;
  4.  
  5. $| = 1;
  6.  
  7. # &source('sys/ioctl.pl');
  8.  
  9. $TIOCGETP = 0x40067408;
  10. $TIOCSETP = 0x80067409;
  11. $ECHO = 0x8;
  12. $CBREAK = 0x2;
  13.  
  14. $isatty = -t;
  15.  
  16. @SW = ( '-draftmessage draftmessage',
  17.               '-draftfolder +folder',
  18.               '-nodraftfolder',
  19.               '-editor editor',
  20.               '-noeditor',
  21.               '-prompt prompt',
  22.               '-help'
  23.       );
  24.  
  25.  
  26. %cmds = (
  27.     ' ',    'help',
  28.     "\n",    'help',
  29.     '?',    'help',
  30.     'E',    'switch-editor',
  31.     'L',    'display-alternate',
  32.     'Q',    'quit-delete',
  33.     's',    'spell',
  34.     'd',    'quit-delete',
  35.     'e',    'edit',
  36.     'h',    'header',
  37.     't',    'type',
  38.     'l',    'list',
  39.     'p',    'push',
  40.     'q',    'quit',
  41.     'r',    'refile',
  42.     'S',    'send',
  43.     'w',    'whom',
  44.     'W',    'watch',
  45.     'y',    'syslog',
  46.     '!',    'shell'    
  47. );
  48.  
  49. #print "args are $0 $ARGS\n";
  50. #print "environment:\n";
  51. #for $key ( sort keys %ENV) {
  52.     #printf "\t%-12s = %s\n", $key, $ENV{$key};
  53. #} 
  54.  
  55.  
  56. if ($ENV{'mhaltmsg'}) {
  57.     unlink '@';
  58.     symlink($ENV{'mhaltmsg'}, '@'); 
  59.     $linked = 1;
  60. }
  61.  
  62. while (($cmd, $fun) = each %cmds) {
  63.     $fun =~ s/-/_/g;
  64.     if (eval "!defined &$fun") {
  65.     print $program, ": warning: key `", $cmd, 
  66.         "' bound to undefined function `",$fun, "'\n";
  67.     } 
  68.  
  69. ($draftmessage = $ENV{'mhdraft'});
  70.  
  71. &mh_profile; 
  72.  
  73. if ($MH{$program}) {
  74.     unshift(@ARGV,split(' ',$MH{$program}));
  75. }
  76.  
  77. &mh_parse;
  78.  
  79. if ($MH{'msg-protect'}) {
  80.     $mask = oct($MH{'msg-protect'});
  81.     umask (~$mask & 0777);
  82.  
  83. die "$program: only one draft at a time!\n" 
  84.     if $#ARGV > 0;
  85.  
  86. $draftmessage = shift if $#ARGV == 0;
  87.  
  88. ($editor = $SW{'editor'}) || 
  89. ($editor = $ENV   {'mheditor'})  ||
  90. ($editor = $MH    {'editor'}) || 
  91. ($editor = $ENV   {'EDITOR'}) ||
  92. ($editor = 'vi');
  93.  
  94. ($pager = $MH{'listproc'})  ||
  95. ($pager = $ENV{'PAGER'})    ||
  96. ($pager = 'more');
  97.  
  98. $SW{'nodraftfolder'} ||
  99.     ($draftfolder = $SW{'draftfolder'}) || 
  100.     ($draftfolder = $MH    {'draft-folder'});
  101.  
  102. $SW{'noeditor'} = 1 unless $draftmessage;
  103.  
  104. if ($draftfolder) {
  105.     $draftmessage = &mhpath($draftfolder, 
  106.         $SW{'draftmessage'} ? $SW{'draftmessage'} : 'last')
  107.         unless $draftmessage;
  108. } else {
  109.     $draftmessage = $MH{'path'} . '/' . 'drafts'
  110.         unless $draftmessage;
  111.  
  112. $SIG{'TERM'} = 'quit';
  113.  
  114. &edit unless $SW{'noeditor'} || $ENV{'mhdist'};
  115.  
  116. $prompt = 'What now' unless $prompt = $SW{'prompt'};
  117.  
  118. #$SIG{'CONT'} = 'continue';
  119.  
  120. for (;;) {
  121.     print "\n$prompt? ";
  122.     $cmd = &readtty;
  123.     ($fun = $cmds{$cmd}) =~ s/-/_/g;
  124.     if (defined $cmds{$cmd}) {
  125.     if (eval "defined &$fun") {
  126.         print $cmds{$cmd}, "\n";
  127.         &$fun;
  128.     } else {
  129.         print "$program: can't call undefined subroutine $fun\n";
  130.     }
  131.     } else {
  132.     printf "$cmd -- unknown command: `%s' (0x%02x)\n", $cmd, ord($cmd);
  133.     die unless $isatty;
  134.     } 
  135.  
  136. exit (0);
  137.  
  138.  
  139. # ----------------------------------------------------------------------
  140. sub mh_parse {
  141.     local(@argdesc) =  @SW;
  142.     local($wantarg);
  143.  
  144.     grep(s/(\W)/\\$1/g, @argdesc);
  145.  
  146.     while ($ARGV[0] =~ /^-.+/) {
  147.     $ARGV = shift @ARGV;
  148.  
  149.     unless (@matches = grep(/$ARGV/, @argdesc)) {
  150.         print "$program: unknown option: $ARGV\n";
  151.         exit 1;
  152.         &usage;
  153.     } 
  154.  
  155.     for (@matches) { s/\\(\W)/$1/g; } 
  156.  
  157.     if ($#matches > $[) {
  158.         print "$program: ambiguous switch $ARGV matches:\n";
  159.         for (@matches) { 
  160.         print "\    ", $_, "\n"; 
  161.         }
  162.         exit 1;
  163.     } 
  164.  
  165.     ($switch,$wantarg) = $matches[$[] =~ /^-(\S+)\s*(\S*)/;
  166.  
  167.     $SW{$switch} = $wantarg ? shift @ARGV : 1;
  168.     if ($SW{$switch} =~ /^(['"]).*$/ && $SW{$switch} !~ /^(['"]).*\1$/) {
  169.         do {
  170.         $SW{$switch} .= ' ' . (shift @ARGV);
  171.         } until $#ARGV < 0 || $SW{$switch} =~ /^(['"]).*\1$/;
  172.         $SW{$switch} =~ s/^(['"])(.*)\1$/$2/;
  173.     } 
  174.     }
  175. }
  176.  
  177. # ----------------------------------------------------------------------
  178. sub source {
  179.     local($file) = @_;
  180.     local($return) = 0;
  181.  
  182.     $return = do $file;
  183.     die "couldn't do \"$file\": $!" unless defined $return;
  184.     die "couldn't parse \"$file\": $@" if $@;
  185.     die "couldn't run \"$file\"" unless $return;
  186.  
  187. # ----------------------------------------------------------------------
  188. sub usage {
  189.     # global $SW
  190.     $pos = 0;
  191.  
  192.     print "syntax: $0 [switches] [files]\n   switches are:\n    ";
  193.     $pos = 4;
  194.  
  195.     for (@SW) {
  196.     if (($pos += length) > 80)  {
  197.         print "\n    ";
  198.         $pos = 4 + length;
  199.     } 
  200.     print $_, " ";
  201.     $pos++;
  202.     } 
  203.     print "\n";
  204.     exit(1);
  205.  
  206. # ----------------------------------------------------------------------
  207. sub mh_profile {
  208.     local($PROFILE);
  209.  
  210.     ($PROFILE = $ENV{"MH"}) || ($PROFILE = $ENV{"HOME"} . "/.mh_profile");
  211.  
  212.     open PROFILE || "$0: can't read mh_profile $PROFILE: $!\n";
  213.  
  214.     while (<PROFILE>) {
  215.     next if /^#/;
  216.     next unless ($key, $value) = /([^:\s]+):\s*(.+)/;
  217.     $key =~ tr/A-Z/a-z/;
  218.     $MH{$key} = $value;
  219.     } 
  220.     close PROFILE;
  221.     $MH{'path'} = $ENV{'HOME'} . '/' . $MH{'path'};
  222.  
  223. # ----------------------------------------------------------------------
  224. sub mhpath {
  225.     local($folder, $msg) = ($_[0], $_[1]);
  226.     local($biggest) = 0;
  227.  
  228.     $folder =~ s/^\+//;
  229.  
  230.     $folder = $MH{'path'} . '/' . $folder 
  231.     unless $folder =~ m!^/!;
  232.  
  233.     if (-d $folder) {
  234.     if ($msg eq 'new' || $msg eq 'last') {
  235.         opendir(FOLDER, $folder) 
  236.         || die "$program: can't opendir $folder: $!\n";
  237.         while ($msg = readdir(FOLDER)) {
  238.         next unless $msg =~ /^\d+$/;
  239.         $biggest = $msg if $msg > $biggest;
  240.         } 
  241.         closedir FOLDER;
  242.         $msg = $biggest + (($msg eq 'new') ? 1 : 0);
  243.     } 
  244.     } else {
  245.     if (-t) {{
  246.         print "Create folder \"$folder\"? ";
  247.         chop($answer = <STDIN>);
  248.         last     if 'yes' =~ /^$answer/i;
  249.         &exit(0)    if 'no' =~ /^$answer/;
  250.         print "$answer: unknown response\n";
  251.         redo;
  252.     }}
  253.     if (defined $MH{'folder-protect'}) {
  254.         $mode = oct($MH{'folder-protect'});
  255.     } else {
  256.         $mode = 0755;
  257.     } 
  258.     mkdir($folder,$mode) || die "program: can't mkdir $folder: $!\n";
  259.     } 
  260.  
  261.     $folder . '/' . $msg;
  262.  
  263. # ----------------------------------------------------------------------
  264. sub readtty {
  265.     local($cmd);
  266.     &cbreak;
  267.     $cmd = getc(STDIN);
  268.  
  269.  
  270. # ----------------------------------------------------------------------
  271. sub continue { 
  272.     print "$prompt? ";
  273.     &cbreak; 
  274. }
  275.  
  276. # ----------------------------------------------------------------------
  277. sub cbreak {
  278.     &set_cbreak(1) if $isatty;
  279.  
  280. # ----------------------------------------------------------------------
  281. sub cooked {
  282.     &set_cbreak(0) if $isatty;
  283.  
  284. # ----------------------------------------------------------------------
  285. sub set_cbreak {
  286.     local($on) = $_[0];
  287.     local($sgttyb);
  288.  
  289.     $sgttyb_t   = 'C4 S' unless $sgttyb_t;
  290.  
  291.     ioctl(STDIN,$TIOCGETP,$sgttyb)
  292.     || warn "Can't ioctl TIOCGETP: $!";
  293.  
  294.  
  295.     @ary = unpack($sgttyb_t,$sgttyb);
  296.     if ($on) {
  297.     $ary[4] |= $CBREAK;
  298.     $ary[4] &= ~$ECHO;
  299.     } else {
  300.     $ary[4] &= ~$CBREAK;
  301.     $ary[4] |= $ECHO;
  302.     }
  303.     $sgttyb = pack($sgttyb_t,@ary);
  304.     ioctl(STDIN,$TIOCSETP,$sgttyb)
  305.         || warn "Can't ioctl TIOCSETP: $!";
  306.  
  307. }
  308.  
  309. # ----------------------------------------------------------------------
  310. sub help {
  311.     print "Key\tRoutine\n";
  312.     for $key (sort keys %cmds) {
  313.     next if $key =~ /\s/;
  314.     $fun = $cmds{$key};
  315.     $fun =~ s/_/-/g;
  316.     print "$key\t$fun\n";
  317.     }
  318.  
  319. # ----------------------------------------------------------------------)
  320. sub quit {
  321.     $SIG{'TTOU'} = "IGNORE";
  322.     print "$program: draft left on $draftmessage\n"
  323.     if -e $draftmessage;
  324.     &cooked;
  325.     &exit(0);
  326.  
  327. sub exit {
  328.     unlink '@' if $linked;
  329.     exit $_[0];
  330. # ----------------------------------------------------------------------
  331. sub edit {
  332.     local($status, $sigs, $next);
  333.     $status = &run($editor,$draftmessage);
  334.     $sigs = $status & 0xff;;
  335.     $status >>= 8;
  336.     if ($status == 255) {
  337.     print "$program: couldn't exec $editor: $!\n";
  338.     return $status;
  339.     } 
  340.     $editor = $next if $next = $MH{$editor.'-next'};
  341.     return 0 unless $status;
  342.     print "$program: problems with edit--$draftmessage ", 
  343.     $sigs ? "preserved" : "deleted", ".\n" if $status;
  344.     unlink $draftmessage if $status && !$sigs;
  345.     exit 1;
  346.  
  347. # ----------------------------------------------------------------------
  348. sub switch_editor {
  349.     local($neweditor);
  350.     if ($neweditor = &prompt('New editor')) { 
  351.     $editor = $neweditor;
  352.     &edit;
  353.     } else {
  354.     print "(editor still $editor)\n";
  355.     } 
  356.  
  357. # ----------------------------------------------------------------------
  358. sub list {
  359.     &run($pager,$draftmessage);
  360.  
  361. # ----------------------------------------------------------------------
  362. sub run {
  363.     local($status,$mystat);
  364.     &cooked;
  365.     $status = system @_;
  366.     &cbreak;
  367.     $mystat = ($status >> 8) & 0xff;
  368.     if ($mystat == 0xff) {
  369.     print "$program: couldn't run \"@_\": $!\n";
  370.     } elsif ($mystat) {
  371.     print "$program: \"@_\" returned $mystat\n";
  372.     } 
  373.     $status;
  374.  
  375.  
  376. # ----------------------------------------------------------------------
  377. sub quit_delete {
  378.     unlink($draftmessage) 
  379.     || warn "$program: unable to unlink $draftmessage: $!\n";
  380.     &quit;
  381.  
  382. # ----------------------------------------------------------------------
  383. sub push {
  384.     &exit(&run('send','-push', $draftmessage));
  385.     &exit ( &run ( $MH{'sendproc'} || 'send', '-push', $draftmessage));
  386.  
  387. # ----------------------------------------------------------------------
  388. sub refile {
  389.      local($folder);
  390.      return unless $folder = &prompt("Refile into");
  391.      &run('refile',$folder);
  392.  
  393. # ----------------------------------------------------------------------
  394. sub send {
  395.     &exit ( &run ( $MH{'sendproc'} || 'send', $draftmessage));
  396.  
  397. # ----------------------------------------------------------------------
  398. sub spell {
  399.     local($spell) = $MH{'spellproc'};
  400.     $spell = 'spell' unless $spell;
  401.     &run($spell, $draftmessage);
  402.  
  403. # ----------------------------------------------------------------------
  404. sub display_alternate {
  405.     local($alt) = $ENV{'mhaltmsg'};
  406.     if (! $alt) {
  407.     print "No alternate message to display\n";
  408.     } else {
  409.     &run($pager,$alt);
  410.     } 
  411.  
  412. # ----------------------------------------------------------------------
  413. sub prompt {
  414.     local($prompt) = $_[0];
  415.     local($retval);
  416.     &cooked;
  417.     print "$prompt? ";
  418.     chop($retval = <STDIN>);
  419.     return $retval;
  420.  
  421. # ----------------------------------------------------------------------
  422. sub whom {
  423.     &run('whom', '-check', $draftmessage);
  424.  
  425. # ----------------------------------------------------------------------
  426. sub watch {
  427.     &exit(&run($MH{'sendproc'} || 'send', 'nopush -watch -verbose',
  428.             $draftmessage));
  429.  
  430. # ----------------------------------------------------------------------
  431. sub syslog {
  432.     &run('tail -f /usr/spool/mqueue/syslog');
  433.  
  434. # ----------------------------------------------------------------------
  435. sub header {
  436.     if (!open draftmessage) {
  437.     warn "$program: no $draft message\n";
  438.     return;
  439.     } 
  440.     while (<draftmessage>) {
  441.     last if /^-*$/;
  442.     print;
  443.     } 
  444.     close draftmessage;
  445.  
  446. # ----------------------------------------------------------------------
  447. sub type {
  448.     if (!open draftmessage) {
  449.     warn "$program: no $draft message\n";
  450.     return;
  451.     } 
  452.  
  453.     print while <draftmessage>;
  454.  
  455.     close draftmessage;
  456.  
  457. # ----------------------------------------------------------------------
  458. sub shell {
  459.     local($cmd);
  460.     return unless $cmd = &prompt('Shell command');
  461.     &run($cmd);
  462.