home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mm / mm-0.90 / mm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-18  |  7.5 KB  |  310 lines

  1. /*
  2.  * Copyright (c) 1986, 1990 by The Trustees of Columbia University in
  3.  * the City of New York.  Permission is granted to any individual or
  4.  * institution to use, copy, or redistribute this software so long as it
  5.  * is not sold for profit, provided this copyright notice is retained.
  6.  */
  7.  
  8. #ifndef lint
  9. static char *rcsid = "$Header: /f/src2/encore.bin/cucca/mm/tarring-it-up/RCS/mm.c,v 2.5 90/10/04 18:24:57 melissa Exp $";
  10. #endif
  11.  
  12. /*
  13.  * mm.c - portable "mail manager" program
  14.  */
  15.  
  16.  
  17. #include "mm.h"
  18. #include "parse.h"
  19. #include "cmds.h"
  20. #include "set.h"
  21.  
  22.  
  23. char *progname;
  24. int mode = MM_TOP_LEVEL;
  25. int memdebug = false;
  26. int debug = false;
  27. #define dmsg(msg) if (debug) { printf (msg); fflush(stdout); } else debug = 0
  28.  
  29. #define CMDBUFLEN (10*BUFLEN)
  30. int cmdbuf[CMDBUFLEN];            /* ccmd work buffers */
  31. static buffer wrkbuf;
  32. buffer atmbuf;                /* parsed field */
  33. pval pv;                /* parse value */
  34. fdb *used;                /* which fdb was used to parse field */
  35. extern char cmcont;            /* line continuation character */
  36.  
  37. int mail_check = false;
  38. typedef int (*(*acttab))();
  39. acttab mmactini();
  40. jmp_buf abortbuf;
  41.  
  42. char **Argv;
  43. int Argc,doargs=false;
  44. int gotargs=false;
  45.  
  46. main(argc, argv)
  47. int argc;
  48. char *argv[];
  49. {
  50.     int err, new_mail();
  51.     volatile int doget;
  52.     static fdb userfdb = { _CMUSR };
  53.     char *root = "root";
  54.     char **split_args();
  55.     extern variable set_variables[];
  56.     extern setkey user_level;
  57.  
  58. #ifdef USAGEFILE
  59.     usage_start();
  60. #endif
  61.     Argv = argv;
  62.     Argc = argc;
  63.     doargs = false;
  64. #ifdef MDEBUG
  65.     m_init();
  66. #endif /* MDEBUG */
  67.  
  68.     dmsg ("initialize...");
  69.     initialize (argv);            /* set up some variables */
  70.  
  71.     mode = MM_TOP_LEVEL;
  72.  
  73.     cmcont = '\\';            /* lines are continued with \ */
  74.     cmbufs (cmdbuf, sizeof (cmdbuf)/sizeof(*cmdbuf), /* set up buffers  */
  75.         atmbuf, sizeof (atmbuf)/sizeof(*atmbuf), /*   for ccmd */
  76.         wrkbuf, sizeof (wrkbuf)/sizeof(*wrkbuf));
  77.  
  78.     cmact(mmactini());
  79.     cmcsb._cmntb = "#";            /* comments start with # */
  80.  
  81.     init_signals ();            /* see signals.c */
  82.  
  83.     printf ("%s\n", mm_version);
  84.  
  85.     dmsg ("crunch...");
  86.  
  87.     cmseti(NULL, NULL, NULL);          /* no files needed while reading those */
  88.     cmhst(0);                /* turn off cmd history */
  89.  
  90.     dmsg ("system init...");
  91.     system_init ();            /* take system init file */
  92.  
  93.     dmsg ("group init...");        /* take group init file */
  94.     group_init();
  95.  
  96.     clear_modified();            /* clear modified flags on variables */
  97.  
  98.     dmsg ("mailrc...");
  99.     mailrc();
  100.     if (isatty(0))
  101.     cmseti(stdin, stdout, stderr);    /* DON'T TRY TO PARSE BEFORE HERE */
  102.     else
  103.     cmseti(stdin, NULL, stderr);    /* pipe or file redirect. */
  104.                     /* don't echo */
  105.     dmsg ("user init...");
  106.     user_init ();
  107.  
  108.     if (clear_screen) {            /* var is now appropriately set */
  109.     cmcls();
  110.     printf ("%s\n", mm_version);
  111.     }
  112.     printf ("\
  113. Please report all problems using MM's BUG command, or send mail to BUG-MM.\n\
  114. Suggestions are also welcome.\n");
  115.  
  116.     dmsg ("user rc...");
  117.     user_rc ();
  118.     if (editor == NULL && !set_variables[SET_EDITOR].changed) {
  119.     char *ed;
  120.  
  121.     if ((ed = (char *) getenv ("EDITOR")) != NULL)
  122.         editor = split_args (ed);
  123.     else
  124.         editor = split_args(EDITOR);
  125.     }
  126.     cmhst(100);                /* turn on command history */
  127.     show_route(FALSE);            /* show mail routing if routed */
  128.  
  129.     dmsg ("\n");
  130.  
  131.     doget = true;
  132.     cmseter();
  133.     if (doget && cf == NULL && strlen(mail_file) != 0 && auto_startup_get &&
  134.     Argc == 1) {
  135.     doget = false;
  136.     printf("Reading %s ...\n", mail_file);
  137.     cf = getfile(mail_file,CMD_GET);
  138.     if (cf != NULL)
  139.         do_flagged();        /* show flagged ones */
  140.     }
  141.     mail_check = true;
  142.     doargs = true;
  143.     while (true) {
  144.     err = top_level_parser ();
  145.     switch (err) {
  146.       case CMxEOF:
  147.         done (0);
  148.       default:
  149.         fprintf (stderr, "%s: main: fatal parser error\n", progname, err);
  150.         done (1);
  151.     }
  152.     }
  153. }
  154.     
  155. int
  156. top_level_parser ()
  157. {
  158.     fdb *fdbs;
  159.     extern string default_send_command, default_read_command;
  160.     static int level = 0;        /* see if we are here in a "take" */
  161.     extern int user_aborted;
  162.     volatile int doprev;
  163.  
  164.     level++;                /* count this entry */
  165.     cmcsb._cmerr = CMxOK;        /* assume no error */
  166.     while (true) {
  167.     setjmp(abortbuf);
  168.     allow_aborts = false;
  169. #ifdef undef
  170.     debug_validate_msgvec("top level loop");
  171. #endif
  172.     if (mail_check)
  173.         new_mail(true);        /* check for new mail. */
  174.     if (cmseteof ()) {
  175.         level--;            /* count the return */
  176.         return CMxEOF;
  177.     }
  178.     doprev = false;
  179.     if (cmseter ()) {        /* errors return here */
  180.         if (cmcsb._cmerr == CMxEOF) {
  181.         level--;
  182.         return CMxEOF;
  183.         }
  184.         else
  185.         doprev = true;
  186.     }
  187.  
  188.     if (user_aborted) {
  189.         mode &= ~(MM_SEND|MM_REPLY|MM_ANSWER);
  190.         user_aborted = false;
  191.     }
  192.  
  193.     if (doargs && level <= 1) {
  194.         fdbs = fdbchn (&mm_top_fdb_abbr, &mm_top_fdb_1, &mm_top_fdb_2, 
  195.                &mm_top_fdb_3, &mm_top_fdb_4, &mm_top_fdb_5, 
  196.                &mm_top_fdb_6, &mm_top_fdb_7, &mm_top_fdb_inv, 
  197.                &shell_fdb, nil);
  198.         if (cmargs(Argc,Argv)) 
  199.         gotargs = true;
  200.     }
  201.  
  202.     if (gotargs && doargs && level <= 1) {
  203.         cmsetrp();
  204.     }
  205.     else if (mode == MM_REPLY) {
  206.         cm_set_ind(TRUE);        /* allow indirections */
  207.         alarm(0);            /* we don't get to the parse */
  208.         do_reply_many();        /*   further down where alarm is */
  209.         continue;            /*   turned off so do it here */
  210.     } 
  211.     else if (mode & MM_SEND) {
  212.         if (!doprev)
  213.         novice_banner(MM_SEND);
  214.         prompt (send_prompt);
  215.         cmsetrp ();            /* reparse comes back here */
  216.         fdbs = fdbchn (&mm_send_fdb_abbr, &mm_send_fdb_1, 
  217.                &mm_send_fdb_2, &mm_send_fdb_3, &mm_send_fdb_4, 
  218.                &mm_send_fdb_5, &mm_send_fdb_inv, 
  219.                &shell_fdb, nil);
  220.         if (default_send_command[0] == '\0')
  221.         mm_send_fdb_abbr._cmdef = NULL;
  222.         else
  223.         mm_send_fdb_abbr._cmdef = default_send_command;
  224.     }
  225.     else if (mode & MM_BROWSE) {
  226.         alarm(0);
  227.         browse_message();
  228.         continue;
  229.     }
  230.     else if (mode & MM_READ) {
  231.         if (!doprev)
  232.         novice_banner(MM_READ);
  233.         prompt (read_prompt);
  234.         cmsetrp ();            /* reparse comes back here */
  235.         fdbs = fdbchn (&mm_read_fdb_abbr, &mm_read_fdb_1, 
  236.                &mm_read_fdb_2, &mm_read_fdb_3, &mm_read_fdb_4, 
  237.                &mm_read_fdb_5, &mm_read_fdb_6, &mm_read_fdb_7, 
  238.                &mm_read_fdb_inv, 
  239.                &shell_fdb, nil);
  240.         if (default_read_command[0] == '\0')
  241.         mm_read_fdb_abbr._cmdef = NULL;
  242.         else
  243.         mm_read_fdb_abbr._cmdef = default_read_command;
  244.     }
  245.     else {
  246.         if (gotargs && level <= 1) {
  247.         if (cf && !update(&cf,UPD_SAVEMOD) && (cf->flags & MF_WRITERR))
  248.             gotargs = FALSE;    /* don't exit if write fails */
  249.         else
  250.             done(0);
  251.         }
  252.         if (!doprev)
  253.         novice_banner(MM_TOP_LEVEL);
  254.         prompt (top_level_prompt);
  255.         cmsetrp ();            /* reparse comes back here */
  256.         fdbs = fdbchn (&mm_top_fdb_abbr, &mm_top_fdb_1, &mm_top_fdb_2, 
  257.                &mm_top_fdb_3, &mm_top_fdb_4, &mm_top_fdb_5, 
  258.                &mm_top_fdb_6, &mm_top_fdb_7, &mm_top_fdb_inv, 
  259.                &shell_fdb, nil);
  260.     }
  261.     if (doprev) {
  262.         doprev = false;
  263.         prevcmd();
  264.     }
  265.     cmcsb._cmerh = ccmd_error;    /* reset in case of reparse */
  266.     cm_set_ind(TRUE);        /* allow indirections */
  267.     if (fdbs->_cmdef != nil)
  268.         cmcsb._cmflg |= CM_PRS;    /* XXX kludge! */
  269.     doargs = false;
  270.     parse (fdbs, &pv, &used);
  271.     alarm(0);
  272.     if (used == &shell_fdb)
  273.         (void) shell_escape ();
  274.     else {
  275.         keywrd *k;
  276.  
  277.         k = (keywrd *) pv._pvkey;
  278.         (void) (*mm_cmds[k->_kwval]) (k->_kwval);
  279.     }
  280.  
  281.     }
  282. }
  283.  
  284. /* 
  285.  * parse an (optional) shell command and invoke the shell
  286.  */ 
  287.  
  288. shell_escape ()
  289. {
  290.     static fdb cmdfdb = { _CMTXT };
  291.  
  292.     parse (&cmdfdb, &pv, &used);    /* parse a line of text */
  293.     if (strlen (atmbuf) == 0)
  294.     shell (nil);
  295.     else
  296.     shell (atmbuf);
  297. }
  298.  
  299. cmd_debug (n)
  300. int n;
  301. {
  302.     debug = parse_yesnoask("yes");
  303. }
  304.  
  305. cmd_debug_memory (n)
  306. int n;
  307. {
  308.     memdebug = parse_yesnoask("yes");
  309. }
  310.