home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / hamradio / bm332c.zip / MAIN.C < prev    next >
C/C++ Source or Header  |  1993-02-24  |  19KB  |  794 lines

  1. /*
  2.  *    Simple mail user interface for KA9Q IP/TCP package.
  3.  *    A.D. Barksdale Garbee II, aka Bdale, N3EUA
  4.  *    Copyright 1986 Bdale Garbee, All Rights Reserved.
  5.  *    Permission granted for non-commercial copying and use, provided
  6.  *    this notice is retained.
  7.  *    Copyright 1987 1988 Dave Trulli NN2Z, All Rights Reserved.
  8.  *    Permission granted for non-commercial copying and use, provided
  9.  *    this notice is retained.
  10.  *      Copyright 1992,1993 Costas Krallis SV1XV, All Rights Reserved.
  11.  *      Permission granted for AMPRnet use only.
  12.  *
  13.  * Revision history:
  14.  *
  15.  *  v3.3.2c 930223 K. Krallis SV1XV
  16.  *      Included alias enhancements by Jerzy Tarasiuk <jt@fuw.edu.pl>.
  17.  *  v3.3.2b 930112 K. Krallis SV1XV
  18.  *      Removed all non MSDOS, non Turbo-C stuff from sources.
  19.  *      Added "getopt.h" header file.
  20.  *      "Organization: " and alias config keywords made compatible
  21.  *         to P.Healy's (EI9GL) "bmh02" mailer.
  22.  *  v3.3.2a 921224 K. Krallis SV1XV
  23.  *    Add "Organization: " field to outgoing mail.
  24.  *    Allow "alias" pathname to be set in BM.RC file
  25.  *  v3.3 870467 D. Trulli NN2Z
  26.  *  v3.2 870314 D. Trulli NN2Z
  27.  *  v3.1 870117 D. Trulli NN2Z
  28.  *    Add multiple arguments mail commands.
  29.  *    Send to multiple users.
  30.  *    Add status commands;
  31.  *  v3.0 871225 D. Trulli NN2Z
  32.  *    Heavily restructured program to use a index array of message.
  33.  *    More compatible with UNIX type mail commands.
  34.  *  v2.7 871214 D. Trulli NN2Z
  35.  *    Cleaned up header and message parsing to prevent lock up.
  36.  *    Revised command structure.
  37.  *  v2.6 870826 Bdale Garbee N3EUG
  38.  *    integrate PA0GRI's interface/gateway to the WA7MBL PBBS
  39.  *  v2.5 870713 Bdale Garbee N3EUG
  40.  *      integrate additional patches from PA0GRI, minor cleanup
  41.  *  v2.4 870614 - Phil Karn KA9Q
  42.  *      "smart gateway" function moved to smtp client code in net.exe.
  43.  *    User interface for sending mail reworked to resemble Berkeley Mail
  44.  *  v2.3 870524
  45.  *      Extensive addition/revision by Gerard PA0GRI.  Now supports a healthy
  46.  *      set of real commands.  
  47.  *  v2.1,2.2
  48.  *      exact change history lost.
  49.  *  v2.0 c.870115
  50.  *      First version with command parser, only send and quit work.
  51.  *  v1.0
  52.  *      First attempt.  Send messages only.
  53.  */
  54.  
  55. #include <stdio.h>
  56. #include <ctype.h>
  57. #include <string.h>
  58. #include "bm.h"
  59. #include "getopt.h"
  60.  
  61. extern char version[];
  62. static char copyright1[] = 
  63. "Copyright 1987 Bdale Garbee, permission granted for non-commercial use.";
  64. static char copyright2[] = 
  65. "Copyright 1988 Dave Trulli NN2Z, permission granted for non-commercial use.";
  66. static char copyright3[] =
  67. "Copyright 1993 Costas Krallis SV1XV, permission granted for AMPRnet use only.";
  68.  
  69. /* comands valid in BM.RC */
  70.  
  71. struct token rccmds[] = {
  72.     "smtp", SMTP,
  73.     "host", HOST,
  74.     "user", USER,
  75.     "edit", EDIT,
  76.     "fullname", NAME,
  77.     "reply", REPLY,
  78.     "maxlet", MAXLET,
  79.     "mbox", MBOX,
  80.     "record", RECORD,
  81.     "screen", SCREEN,
  82.     "folder", FOLDER,
  83.     "mqueue", MQUEUE,
  84.     "organ", ORG,
  85.     "alias", ALIAS,
  86.     NULLCHAR, 0
  87. };
  88.  
  89. FILE    *mfile = NULLFILE;
  90. char     *hostname = NULLCHAR;        /* name of this host from rc file */
  91. char    *username = NULLCHAR;        /* name of this user from rc file */
  92. char    *fullname = NULLCHAR;        /* fullname of this user from rc file */
  93. char    *replyto = NULLCHAR;        /* address for reply-to header */
  94. char    *organization = NULLCHAR;    /* Organization field,    (SV1XV)    */
  95. char    *aliases = NULLCHAR;        /* alias file,        (SV1XV)    */
  96. char    *maildir = NULLCHAR;        /* defined mail directory */
  97. char    *mqueue = NULLCHAR;        /* defined mqueue outbound directory */
  98. char    *savebox = NULLCHAR;        /* name of the mbox text file */
  99. char    *record = NULLCHAR;        /* record  outbound mail in this file */
  100. char    *folder = NULLCHAR;        /* directory for saveing read mail */
  101. char    *editor = NULLCHAR;        /* user's favorite text editor */
  102. char    notename[9];            /* name of current notesfile */
  103. char    notefile[SLINELEN];        /* full pathname of mail text file */
  104. char    *mfilename = notefile;    /* pointer to current mbox or mail file -f */
  105. int    current;            /* the current message number */
  106. int    nmsgs;            /* the number of messages in the notesfile */
  107. int    newmsgs;        /* Number of new unread message */
  108. int    change;            /* indicates that the mail file has been
  109.                  * changed in this session */
  110. int    fflag = 0;        /* true if current notesfile is not an mbox */
  111. int    qflag = 0;        /* true if bm is used just to queue files */
  112. unsigned maxlet = NLET+1;    /* max number of messages in mailbox */
  113. int    tty = 0;        /* tells if stdin is a tty */
  114. struct let *mbox;        /* pointer to the array of messages */
  115.  
  116.  
  117. char usage[] = "Usage: bm [-u user] [-f file] \n  or bm [-s subject] [-q] addr .. addr\n";
  118. char badmsg[] = "Invalid Message number %d\n";
  119. char nomail[] = "No messages\n";
  120. char noaccess[] = "Unable to access %s\n";
  121.  
  122.  
  123. int main(int argc, char **argv)
  124. {
  125.     char *subjectline = NULLCHAR;
  126.     long    tmp;
  127.     int    c;
  128.     int    ret;
  129.  
  130.     (void) fclose(stdaux);
  131.     (void) fclose(stdprn);
  132.  
  133.     loadconfig();
  134.  
  135.     if(isatty(fileno(stdin))){        /* announce ourselves */
  136.         cls();
  137.         printf("%s\n%s\n%s\n%s\n\n",
  138.             version,
  139.             copyright1,
  140.             copyright2,
  141.             copyright3
  142.             );
  143.         tty = 1;
  144.     } 
  145.  
  146.     current = 1;
  147.     nmsgs = 0;
  148.  
  149.     /* check for important directories */
  150.     if(access(maildir,0)){
  151.         printf(noaccess,maildir);
  152.         exit(1);
  153.     }
  154.     if(access(mqueue,0)){
  155.         printf(noaccess,mqueue);
  156.         exit(1);
  157.     }
  158.     strncpy(notename,username,8);
  159.     notename[8] = '\0';
  160.  
  161.     while ((c = getopt(argc,argv,"u:f:s:q")) != -1) {
  162.         switch(c) {
  163.         case 'f':
  164.             fflag++;
  165.             mfilename = optarg;
  166.             break;
  167.         case 'q':
  168.             qflag++;
  169.             break;
  170.         case 's':
  171.             subjectline = optarg;
  172.             break;
  173.         case 'u':
  174.             strncpy(notename,optarg,8);
  175.             notename[8] = '\0';
  176.             break;
  177.         case '?':
  178.             printf(usage);
  179.             exit(1);
  180.         }
  181.     }
  182.  
  183.     /* set any signal handlers to catch break */
  184.     setsignals();
  185.  
  186.     if(optind < argc){
  187.         dosmtpsend(NULLFILE,&argv[optind],argc-optind,subjectline);
  188.         (void) exit(0);
  189.     }
  190.  
  191.     tmp = (long)maxlet * (long)sizeof(struct let);
  192.  
  193.     /*
  194.     * Since we are in the dos small model make sure that we
  195.     * don't overflow a unsigned short on the number bytes
  196.     * need for mallloc. If not checked malloc will
  197.     * succeed and we will be trashing ourself in no time.
  198.     */
  199.     if ((tmp & 0xffff0000) ||
  200.         (mbox=(struct let *)malloc((unsigned short)tmp)) == (struct let *)NULL){
  201.         fprintf(stderr,
  202.         "Can't allocate memory table for %d messages\n",
  203.             maxlet);
  204.         (void) exit(1);
  205.     }
  206.  
  207.     sprintf(notefile,"%s/%s.txt",maildir,notename);
  208.     if (!fflag && lockit())
  209.         exit(1);
  210.     ret = initnotes();
  211.     if (!fflag)
  212.         rmlock(maildir,notename);
  213.     if (ret != 0)
  214.         exit(1);
  215.     listnotes();
  216.     
  217.     getcommand();
  218.     return 0;
  219. }
  220.  
  221. loadconfig()
  222. {
  223.     FILE    *rcfp;    /* handle for the configuration file */
  224.     char    rcline[LINELEN]; /* buffer for config file reading */
  225.     register char *s,*p;
  226.     int line = 0;
  227.     char runcom[LINELEN];
  228.     char *getenv();
  229.  
  230.     /* check for BMRC in the ENV */
  231.     if ((p = getenv("BMRC")) != NULLCHAR)
  232.         strcpy(runcom,p);
  233.     else
  234.         strcpy(runcom,RUNCOM);
  235.  
  236.     if ((rcfp = fopen(runcom,"r")) == NULLFILE) {    /* open config file */
  237.         printf("Cannot open '%s', check your installation\n",runcom);
  238.         (void) exit(1);
  239.         }
  240.     while (!feof(rcfp)) {
  241.         if (fgets(rcline,LINELEN,rcfp) == NULLCHAR)
  242.             break;
  243.         line++;
  244.         rip(rcline);
  245.         if (*rcline == '\0' || *rcline == ';'|| *rcline == '#')
  246.             continue;
  247.         /* find the argument to the command */
  248.  
  249.         s = rcline;
  250.         /* skip the white space */
  251.         while(*s == ' ' || *s == '\t')
  252.                 s++;
  253.         p = s;
  254.         /* skip the command */
  255.         while(*p && *p != ' ' && *p != '\t')
  256.                 p++;
  257.         /* skip the white space */
  258.         while(*p == ' ' || *p == '\t')
  259.                 p++;
  260.         if (*s == '\0')
  261.             continue;
  262.  
  263.         switch (rc_line_type(s)) {
  264.         case HOST:
  265.             hostname = savestr(p);
  266.             break;
  267.         case USER:
  268.             username = savestr(p);
  269.             break;
  270.         case REPLY:
  271.             replyto = savestr(p);
  272.             break;
  273.         case EDIT:
  274.             editor = savestr(p);
  275.             break;
  276.         case SMTP:
  277.             maildir = savestr(p);
  278.             break;
  279.         case NAME:
  280.             fullname = savestr(p);
  281.             break;
  282.         case MAXLET:
  283.             maxlet = atoi(p)+1;
  284.             break;
  285.         case MBOX:
  286.             savebox = savestr(p);
  287.             break;
  288.         case RECORD:
  289.             record = savestr(p);
  290.             break;
  291.         case SCREEN:
  292.             setvideo(p);
  293.             break;
  294.         case FOLDER:
  295.             folder = savestr(p);
  296.             break;
  297.         case MQUEUE:
  298.             mqueue = savestr(p);
  299.             break;
  300.         case ORG:            /* added by SV1XV    */
  301.             organization = savestr(p);
  302.             break;
  303.         case ALIAS:            /* added by SV1XV     */
  304.             aliases = savestr(p);
  305.             break;
  306.         default:
  307.             fprintf(stderr,
  308.             "%s: line %d Invalid command: '%s'\n",
  309.             runcom,line,rcline);
  310.             exit(1);
  311.         }
  312.     }
  313.     (void) fclose(rcfp);
  314.     if(maildir == NULLCHAR)
  315.         maildir = mailspool;
  316.     if(mqueue == NULLCHAR)
  317.         mqueue = mailqdir;
  318.     if(savebox == NULLCHAR)
  319.         savebox = "mbox";
  320.     if(hostname == NULLCHAR) {
  321.         fprintf(stderr,"%s: hostname not set\n",runcom);
  322.         exit(1);
  323.     }
  324.     if(username == NULLCHAR) {
  325.         fprintf(stderr,"%s: username not set\n",runcom);
  326.         exit(1);
  327.     }
  328. }
  329.  
  330. /* return the line_type from a line of the configuration file */
  331. rc_line_type(register char *s)
  332. {
  333.     register struct token *tp;
  334.     for (tp = rccmds; tp->str != NULLCHAR; tp++) 
  335.         if (strncmp(tp->str,s,strlen(tp->str)) == 0)
  336.             return(tp->type);
  337.     return (NONE);
  338. }
  339.  
  340. /* replace terminating end of line marker(s) with null */
  341. rip(s)
  342. register char *s;
  343. {
  344.     for (; *s; s++)
  345.         if (*s == '\r' || *s == '\n') {
  346.             *s = '\0';
  347.             break;
  348.         }
  349. }
  350.  
  351. /* copy a string return a pointer to it */
  352. char *
  353. savestr(char *s)
  354. {
  355.     register  char *p;
  356.     p = malloc(strlen(s)+1);
  357.     if (p == NULLCHAR) 
  358.         printf("No more memory\n");
  359.     else
  360.         strcpy(p,s);
  361.     return p;
  362. }
  363.  
  364. dohelp()
  365. {
  366.     cls();
  367.     printf("\n\n");
  368.     printf(" d [msglist]           delete a message\n");
  369.     printf(" m userlist            mail a message\n");
  370.     printf(" s [msglist] [file]    save message in file (default mbox)\n");
  371.     printf(" w [msglist] file      save message in file no header\n");
  372.     printf(" f [msg]               forward message\n");
  373.     printf(" b [msg]               bounce message (remail)\n");
  374.     printf(" r [msg]               reply to a message\n");
  375.     printf(" u [msglst]            undelete a message\n");
  376.     printf(" p [msglst]            print message on printer (DOS only)\n");
  377.     printf(" .                     display current message\n");
  378.     printf(" h                     display message headers in notefile\n");
  379.     printf(" l                     list unsent messages\n");
  380.     printf(" k                     kill unsent messages\n");
  381.     printf(" n [file]              display or change notesfile\n");
  382.     printf(" #                     where # is the number of message to read\n");
  383.     printf(" x                     quit without changing mail file\n");
  384.     printf(" q                     quit\n");
  385.     printf(" ! cmd                 run dos command\n");
  386.     printf(" $                     sync the notefile\n");
  387.     printf(" ?                     print this help screen\n");
  388. }
  389.  
  390.  
  391. /* save a message list in a file in mailbox format */
  392. savemsg(argc,argv)
  393. int argc;
  394. register char *argv[];
  395. {
  396.     register char *savefile;
  397.     int msgnum;
  398.     int    i;
  399.     FILE *tfile;
  400.     char buf[LINELEN];
  401.  
  402.     if (mfile == NULLFILE){
  403.         printf(nomail);
  404.         return;
  405.     }
  406.     if (argc == 0 || isdigit(*argv[argc - 1])) {
  407.         savefile = savebox;
  408.     } else {
  409.         savefile = argv[argc - 1];
  410.         --argc;
  411.         /* if it is just a file name and not a path name then check
  412.         ** for a folder path defined and use that path to
  413.         ** save the file.
  414.         */
  415.         if (strpbrk(savefile,"/\\") == NULLCHAR && folder != NULLCHAR) {
  416.             sprintf(buf,"%s/%s",folder,savefile);
  417.             savefile = buf;
  418.         }
  419.     }
  420.     if ((tfile = fopen(savefile,"a")) == NULLFILE) {
  421.         perror(savefile);
  422.         return;
  423.     }
  424.     if (argc == 0)
  425.         msgtofile(current, tfile, 0);
  426.     else {
  427.         for (i = 0; i < argc; i++) {
  428.             msgnum = atoi(argv[i]);
  429.             if (msgnum >= 1 && msgnum <= nmsgs)
  430.                 msgtofile(msgnum, tfile, 0);
  431.             else
  432.                 printf(badmsg,msgnum);
  433.         }
  434.     }
  435.         (void) fclose(tfile);
  436.         printf("%s appended\n",savefile);
  437. }
  438.  
  439. /* send messages to the print device */
  440. printmsg(int argc, char *argv[])
  441. {
  442.     FILE *prn;
  443.     int msgnum;
  444.     int    i;
  445.  
  446.     if (mfile == NULLFILE){
  447.         printf(nomail);
  448.         return;
  449.     }
  450.     if ((prn = fopen("PRN","a")) == NULL) {
  451.         perror("PRN");
  452.         return;
  453.     }
  454.     if (argc == 0)
  455.         msgtofile(current, prn, 0);
  456.     else {
  457.         for (i = 0; i < argc; i++) {
  458.             msgnum = atoi(argv[i]);
  459.             if (msgnum >= 1 && msgnum <= nmsgs)
  460.                 msgtofile(msgnum, prn, 0);
  461.             else
  462.                 printf(badmsg,msgnum);
  463.         }
  464.     }
  465.     fclose(prn);
  466. }
  467.  
  468. writemsg(argc,argv)
  469. int argc;
  470. char *argv[];
  471. {
  472.     char *writefile;
  473.     int msgnum;
  474.     int    i;
  475.     FILE *tfile;
  476.  
  477.     if (mfile == NULLFILE){
  478.         printf(nomail);
  479.         return;
  480.     }
  481.     if (argc == 0 || isdigit(*argv[argc - 1])) {
  482.         printf("no file specified\n");
  483.         return;
  484.     } else {
  485.         writefile = argv[argc - 1];
  486.         --argc;
  487.     }
  488.     if ((tfile = fopen(writefile,"a")) == NULLFILE) {
  489.         perror(writefile);
  490.         return;
  491.     }
  492.     if (argc == 0)
  493.         msgtofile(current, tfile, 1);
  494.     else {
  495.         for (i = 0; i < argc; i++) {
  496.             msgnum = atoi(argv[i]);
  497.             if (msgnum >= 1 && msgnum <= nmsgs)
  498.                 msgtofile(msgnum, tfile, 1);
  499.             else
  500.                 printf(badmsg,msgnum);
  501.         }
  502.     }
  503.     (void) fclose(tfile);
  504.     printf("%s appended\n",writefile);
  505. }
  506.  
  507. bmexit(x)
  508. int x;
  509. {
  510.     if(!fflag && lockit())
  511.         exit(1);
  512.     (void) closenotes();
  513.     if (!fflag)
  514.         rmlock(maildir,notename);
  515.     exit(x);
  516. }
  517.  
  518. /* this is the main command processing loop */
  519. getcommand()
  520. {
  521.     FILE *tfile, *tmpfile();
  522.     char    command[LINELEN];    /* command line */
  523.     char    *args[MAXARGS];
  524.     int    nargs;
  525.     char    *cp;
  526.     register int    msgnum;
  527.     register int    i;
  528.     int ret;
  529.  
  530.     printf("\nType ? for help.\n");
  531.  
  532.     /* command parsing loop */
  533.     while(1) {
  534.         printf("\"%s\"> ",notename);
  535.         gets(command);
  536.  
  537.         if (feof(stdin))        /* someone hit ^Z! */
  538.             strcpy(command,"q");    /* treat it like 'q' */
  539.             
  540.         if(*command == '!') {
  541.             if (system(&command[1]))
  542.                 perror("system");
  543.             continue;
  544.         }
  545.         if (*command) {
  546.             cp = command;
  547.             while (*cp && *cp != ' ')
  548.                 cp++;
  549.             nargs = parse(cp,args,MAXARGS);
  550.         }
  551.  
  552.         switch (*command) {
  553.         case 'm':        /* send msg */
  554.             if (nargs == 0) {
  555.                 printf("To: ");
  556.                 gets(command);
  557.                 nargs = parse(command,args,MAXARGS);
  558.             }
  559.             dosmtpsend(NULLFILE,args,nargs,NULLCHAR);
  560.             break;
  561.  
  562.         case 's':        /* save current msg to file */
  563.             savemsg(nargs,args);
  564.             break;
  565.  
  566.         case 'w':        /* write current msg to file */
  567.             writemsg(nargs,args);
  568.             break;
  569.  
  570.         case 'x':        /* abort */
  571.             (void) fclose(mfile);
  572.             (void) exit(0);
  573.             /* NOTREACHED */
  574.             break;
  575.  
  576.         case 'p':        /* print message */
  577.             printmsg(nargs,args);
  578.             break;
  579.  
  580.         case 'r':            /* reply */
  581.             if (nargs == 0)
  582.                 msgnum = current;
  583.             else
  584.                 msgnum = atoi(args[0]);
  585.             if (msgnum >= 1 && msgnum <= nmsgs)
  586.                 reply(msgnum);
  587.             else
  588.                 printf(badmsg,msgnum);
  589.             break;
  590.  
  591.         case 'f':
  592.             if(nargs == 0)
  593.                 msgnum = current;
  594.             else 
  595.                 msgnum = atoi(args[0]);
  596.             if (msgnum < 1 || msgnum > nmsgs) {
  597.                 printf(badmsg,msgnum);
  598.                 break;
  599.             }
  600.             if((tfile = tmpfile()) == NULLFILE)
  601.                 printf("\nCannot open temp file\n");
  602.             else {
  603.                 msgtofile(msgnum,tfile,0);
  604.                 fseek(tfile,0L,0);
  605.                 printf("To: ");
  606.                 gets(command);
  607.                 nargs = parse(command,args,MAXARGS);
  608.                 dosmtpsend(tfile,args,nargs,NULLCHAR);
  609.                 (void) fclose(tfile);
  610.             }
  611.             break;
  612.  
  613.         case 'b':        /* bounce a message */
  614.             if(nargs == 0)
  615.                 msgnum = current;
  616.             else 
  617.                 msgnum = atoi(args[0]);
  618.             if (msgnum < 1 || msgnum > nmsgs) {
  619.                 printf(badmsg,msgnum);
  620.                 break;
  621.             }
  622.             if((tfile = tmpfile()) == NULLFILE)
  623.                 printf("\nCannot open temp file\n");
  624.             else {
  625.                 msgtofile(msgnum,tfile,0);
  626.                 fseek(tfile,0L,0);
  627.                 printf("To: ");
  628.                 gets(command);
  629.                 nargs = parse(command,args,MAXARGS);
  630.                 bouncemsg(tfile,args,nargs);
  631.                 (void) fclose(tfile);
  632.             }
  633.             break;
  634.  
  635.         case 'u':
  636.             if (nargs == 0)
  637.                 mbox[current].status &= ~DELETE;
  638.             else
  639.                 for (i = 0; i < nargs; i++) {
  640.                     msgnum = atoi(args[i]);
  641.                     if( msgnum >= 1 && msgnum <= nmsgs)
  642.                         mbox[msgnum].status &= ~DELETE;
  643.                     else
  644.                         printf(badmsg,msgnum);
  645.                 }
  646.             break;
  647.  
  648.         case 'l':        /* display unsent messages */
  649.             listqueue();
  650.             break;
  651.         case 'k':
  652.             if (nargs == 0)
  653.                 printf("No job id specified\n");
  654.             else
  655.                 for (i = 0; i < nargs; i++) 
  656.                     killjob(args[i]);
  657.             break;
  658.  
  659.         case 'n':     /* display or change notefiles */
  660.             mboxnames(nargs,args);
  661.             break;
  662.         case 'q':        /* quit */
  663.             if (isnewmail()) {
  664.                 printf("New mail has arrived\n");
  665.                 reinit();
  666.             } else
  667.                 bmexit(0);
  668.             /* NOTREACHED */
  669.             break;
  670.         case '$':
  671.             reinit();
  672.             break;
  673.  
  674.         case 'd':        /* delete a message */
  675.             if (nargs == 0)
  676.                 delmsg(current);
  677.             else
  678.                 for ( i = 0; i < nargs; i++) {
  679.                     msgnum = atoi(args[i]);
  680.                     if( msgnum >= 1 && msgnum <= nmsgs)
  681.                         delmsg(msgnum);
  682.                     else
  683.                         printf(badmsg,msgnum);
  684.                 }
  685.             break;
  686.  
  687.         case 'h':        /* list message headers in notesfile */
  688.  
  689.             listnotes();
  690.             break;
  691.  
  692.         case '\0':    /* a blank line prints next message */
  693.             printnext();
  694.             break;
  695.  
  696.         case '?':        /* help */
  697.             dohelp();
  698.             break;
  699.  
  700.         case  '.':
  701.             displaymsg(current);
  702.             break;
  703.         default:
  704.             if (!isdigit(*command))
  705.                 printf("Invalid command - ? for help\n");
  706.             else {
  707.                 msgnum = atoi(command);
  708.                 if (msgnum < 0 || msgnum > nmsgs)
  709.                     printf(badmsg,msgnum);
  710.                 else {
  711.                     current = msgnum;
  712.                     displaymsg(current);
  713.                 }
  714.             }
  715.             break;
  716.         }
  717.     }
  718. }
  719.  
  720. /* list or change mbox */
  721. mboxnames(argc,argv)
  722. int argc;
  723. char *argv[];
  724. {
  725.     register char *cp;
  726.     int ret;
  727.     char    line[80];
  728.     char    buf[LINELEN];
  729.  
  730.     if(argc != 0) {
  731.         if(!fflag && lockit())
  732.             return;
  733.         ret = closenotes();
  734.         if (!fflag)
  735.             rmlock(maildir,notename);
  736.             if (ret != 0)
  737.                 exit(1);
  738.             if (strpbrk(argv[0],"/\\") != NULLCHAR) {
  739.                 fflag = 1;
  740.                 mfilename = argv[0];
  741.             } else {
  742.                 fflag = 0;
  743.                 mfilename = notefile;
  744.                 strncpy(notename,argv[0],8);
  745.                 notename[8] = '\0';
  746.                 sprintf(notefile,"%s/%s.txt",maildir,notename);
  747.             }
  748.             if (!fflag && lockit()) {
  749.                 mfile = NULLFILE;
  750.                 printf("Mail file is busy\n");
  751.                 return;
  752.             }
  753.             ret = initnotes();
  754.             if (!fflag)
  755.                 rmlock(maildir,notename);
  756.             if (ret != 0)
  757.                 exit(1);
  758.             listnotes();
  759.  
  760.         } else {  /* he wants to see what notefiles there are */
  761.             sprintf(buf,"%s/*.txt",maildir,notename);
  762.             filedir(buf,0,line);
  763.             while(line[0] != '\0') {
  764.                 cp = strchr(line,'.');
  765.                 *cp = '\0';
  766.                 printf("notesfile -> %s\n",line);
  767.                 filedir(buf,1,line);
  768.             }
  769.         }
  770. }
  771.  
  772. reinit()
  773. {
  774.     int ret;
  775.     if (!fflag && lockit())
  776.         return;
  777.     ret = closenotes();
  778.     if (!fflag)
  779.         rmlock(maildir,notename);
  780.     if (ret != 0)
  781.         exit(1);
  782.     if (!fflag && lockit()) {
  783.         mfile = NULLFILE;
  784.         printf("Mail file is busy\n");
  785.         return;
  786.     }
  787.     ret = initnotes();
  788.     if (!fflag)
  789.         rmlock(maildir,notename);
  790.     if (ret != 0)
  791.         exit(1);
  792.     listnotes();
  793. }
  794.