home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume1 / 8708 / 21 / mail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-13  |  11.1 KB  |  612 lines

  1. /*
  2.  *    mail.c
  3.  */
  4.  
  5. #define    exit    return
  6.  
  7. #include <stdio.h>
  8. #include "host.h"
  9.  
  10. FILE *FOPEN();
  11. FILE *freopen();
  12.  
  13. int    debuglevel = 1;
  14.  
  15. #define LSIZE       256
  16.  
  17. char    line[LSIZE];
  18. char    resp[LSIZE];
  19.  
  20. char    mfilename[132];
  21.  
  22. struct ldesc {
  23.    int       delete;        /* status of this message */
  24.    long        adr;        /* address of From line */
  25.    long        date;        /* address of Date: line */
  26.    long        subject;    /* address of Subject: line */
  27.    long        from;        /* address of From: line */
  28.    long        size;        /* number of lines */
  29. };
  30.  
  31. struct    ldesc letters[300];
  32.  
  33. int       letternum   = 0;
  34. char       thefilename[50];
  35.  
  36. char       tmailbox[64];
  37. char     tmailbag[64];
  38.  
  39.  
  40. FILE       *fmailbox;
  41. FILE     *rmailbox;
  42. FILE    *fmailbag;
  43.  
  44. int    error = 0;
  45. int    modified;
  46.  
  47. int    printonly;
  48.  
  49. int    PageCount = 0;
  50.  
  51. mailmain(argc, argv)
  52. char **argv;
  53. {
  54.  
  55.     /* HOSTINIT;
  56.     loadenv(); */
  57.  
  58.     mkfilename( tmailbox, tempdir, "mailbox");
  59.     mkfilename( tmailbag, tempdir, "mailbag");
  60.  
  61.     unlink( tmailbox );
  62.  
  63.     if ( mailbox == (char *)NULL )
  64.         mailbox = "???";
  65.  
  66.     if ( argc == 1 ||
  67.         ( argv[1][0] == '-' ) && ( argv[1][1] != 's' ))
  68.         showmail (argc, argv );
  69.     else
  70.         lmail (argc, argv );
  71.  
  72.     finis();
  73.  
  74. }
  75.  
  76. finis()
  77. {
  78.     if ( fmailbag != (FILE *)NULL) fclose( fmailbag );
  79.     unlink( tmailbox );
  80.     unlink( tmailbag );
  81.     exit( error );
  82. }
  83.  
  84. /*    sendmail
  85.     send message n to "line"
  86. */
  87. sendmail( n, line )
  88. {
  89.     char     *argv[50];
  90.     int     argc;
  91.     char    buf[BUFSIZ];
  92.     long     bytes;
  93.  
  94.     /* open a temporary file */
  95.     fmailbag = FOPEN( tmailbag, "w", 'b' );
  96.  
  97.     /* copy nth message to mailbag file */
  98.     fseek( fmailbox, letters[ n ].adr, 0 );
  99.     bytes = letters[ n+1 ].adr - letters[ n ].adr;
  100.  
  101.     while( bytes > 0 && fgets( buf, BUFSIZ, fmailbox) ) {
  102.         fputs( buf, fmailbag  );
  103.         bytes -= strlen( buf );
  104.     }
  105.  
  106.     fclose( fmailbag );
  107.  
  108.     /* use mailbag as stdin to mail delivery */
  109.     fclose( stdin );
  110.     FILEMODE( 'b' );
  111.     if ( freopen( tmailbag, "r", stdin ) != (FILE *)NULL ) {
  112.         argc = getargs( line, argv );
  113.  
  114.         lmail( argc, argv );
  115.  
  116.         fclose( stdin );
  117.     }
  118.     
  119. #ifdef MSDOS
  120.     FILEMODE( 't' );
  121.     freopen( CONSOLE, "r", stdin );
  122. #else
  123.     freopen( device, "r", stdin );
  124. #endif
  125.  
  126.     /* get rid of mailbag */
  127.     unlink( tmailbag );
  128. }
  129.  
  130.  
  131. invert( i )
  132. {
  133.     return( letternum - i - 1 );
  134. }
  135.  
  136. showmail(argc, argv)
  137. char **argv;
  138. {
  139.     int flg, i, j, k, print;
  140.     char *p, *cp, *getnext();
  141.     long nextadr;
  142.     struct ldesc *letter;
  143.  
  144.     /* get mailbox file name */
  145.     mkfilename( mfilename, maildir, mailbox );
  146.  
  147.     /* parse arg's */
  148.     for (; argc > 1; argv++, argc--) {
  149.        if ( argv[1][0] == '-' ) {
  150.           if ( argv[1][1] == 'f' ) {
  151.              if ( argc >= 3) {
  152.                 if ( argv[2][0] == '=' )
  153.                    mkfilename( mfilename, maildir, &argv[2][1] );
  154.                 else
  155.                    strcpy( mfilename, argv[2] );
  156.              argv++;
  157.              argc--;
  158.              }
  159.  
  160.           } else if ( argv[1][1 ]== 'p' ) printonly++;
  161.        else {
  162.           fprintf(stderr, "mail: unknown option %c\n", argv[1][1]);
  163.           finis();
  164.        }
  165.        } else break;
  166.     }
  167.  
  168.  
  169.  
  170.     /* open real mailbox file */
  171.     if (( rmailbox = FOPEN( mfilename, "r", 'b' ))  == (FILE *)NULL) {
  172.         fprintf( stdout, "No mail in %s.\n", mfilename );
  173.         return;
  174.     }
  175.  
  176.     /* open up tmp mailbox file */
  177.       if (( fmailbox = FOPEN( tmailbox, "w", 'b' )) == (FILE *)NULL ) {
  178.         fprintf( stderr, "mail: cannot open %s for writing\n", tmailbox );
  179.         finis();
  180.     }
  181.  
  182.  
  183.     /* copy real mailbox file to tmp mailbox file */
  184.     letternum = 0 ;
  185.     nextadr = 0;
  186.     while ( fgets(line, LSIZE, rmailbox ) != (char *)NULL) {
  187.         fputs( line, fmailbox );
  188.  
  189.         if ( strncmp( line, "From ", 5 ) == SAME ) {
  190.             letter = &letters[letternum++];
  191.             letter->from =
  192.             letter->subject =
  193.             letter->date = -1L;
  194.             letter->adr = nextadr;
  195.             letter->delete = FALSE;
  196.             letter->size = 0L;
  197.         }else if ( strncmp( line, "Date: ", 6 ) == SAME )
  198.             letter->date = nextadr;
  199.         else if ( strncmp( line, "From: ", 6 ) == SAME )
  200.             letter->from = nextadr;
  201.         else if ( strncmp( line, "Subject: ", 9 ) == SAME )
  202.             letter->subject = nextadr;
  203.  
  204.         letter->size += 1L;
  205.         nextadr += strlen( line );
  206.     }
  207.  
  208.     letters[letternum].adr = nextadr;   /* last plus 1 */
  209.  
  210.     /* close mailbox files */
  211.     fclose( rmailbox );
  212.     fclose( fmailbox );
  213.  
  214.     fmailbox = FOPEN( tmailbox, "r", 'b' );
  215.  
  216.     modified = 0;
  217.  
  218.     if ( printonly ) {
  219.         j = letternum;
  220.         while ( j > 0 ) {
  221.             pager( j );
  222.             j--;
  223.         }
  224.  
  225.         return;
  226.      }
  227.  
  228.  
  229.     printsub( -1 );
  230.  
  231.     i = letternum - 1;
  232.     while ( TRUE ) {
  233.  
  234.         if ( i < 0 )
  235.             i = 0;
  236.         if ( i >= letternum)
  237.             i = letternum - 1;
  238.         j = invert( i );
  239.  
  240.         fprintf( stdout, "%d ? ", invert( i ) );
  241.  
  242.         if ( fgets( resp, LSIZE, stdin) == (char *)NULL )
  243.             break;
  244.  
  245.         switch ( resp[0] ) {
  246.         default:
  247.             fprintf(stderr, "usage\n");
  248.         case '?':
  249.             print = 0;
  250.             fprintf( stderr, "q\tquit\n" );
  251.             fprintf( stderr, "x\texit\tmailbox restored\n" );
  252.             fprintf( stderr, "p\tprint message\n" );
  253.             fprintf( stderr, "s[file]\tsave message to a file (default =mbox)\n" );
  254.             fprintf( stderr, "w[file]\ttsave message to a file (default =mbox) without header\n" );
  255.             fprintf( stderr, "-\tprint last message\n" );
  256.             fprintf( stderr, "d\tdelete current message\n" );
  257.             fprintf( stderr, "+\tnext message (no delete)\n" );
  258.             fprintf( stderr, "f user\tforward current message to user\n" );
  259.             fprintf( stderr, "m user\tmail a message to user\n" );
  260.             fprintf( stderr, "g num\t set current message\n" );
  261.             break;
  262.         case '+':
  263.         case 'n':
  264.             i-- ;
  265.             break;
  266.         case 'g':
  267.             i = invert( atoi( resp+2 ) );
  268.             break;
  269.         case '0':
  270.         case '1':
  271.         case '2':
  272.         case '3':
  273.         case '4':
  274.         case '5':
  275.         case '6':
  276.         case '7':
  277.         case '8':
  278.         case '9':
  279.             i = invert( atoi( resp ) );
  280.             break;
  281.  
  282.         case 'x':
  283.             modified = 0;
  284.         case 'q':
  285.             goto donep;
  286.         case '\n':
  287.         case 'p':
  288.             pager( j );
  289.             break;
  290.         case '^':
  291.         case '-':
  292.             i++;
  293.             break;
  294.         case 'y':
  295.         case 'w':
  296.         case 's':
  297.             flg = 0;
  298.             if (resp[1] != '\n' && resp[1] != ' ') {
  299.                 printf("illegal\n");
  300.                 flg++;
  301.                 print = 0;
  302.                 continue;
  303.             }
  304.             if (strlen( resp ) == 1)
  305.                 strcat( resp, " =mbox" );
  306.             for (p = resp+1; (p = getnext( &cp, p )) != (char *)NULL; ) {
  307.                if ( *cp == '=' )
  308.                           mkfilename( thefilename, maildir, ++cp );
  309.                else
  310.                   strcpy( thefilename, cp );
  311.                fprintf( stderr, "%s to %s\n",
  312.                        (resp[0] == 's') ? "Appending":"Writing", thefilename );
  313.                if (( fmailbag=FOPEN( thefilename, "a", 't' )) == (FILE *)NULL ) {
  314.                   fprintf( stdout, "mail: cannot append to %s\n",
  315.                            thefilename );
  316.                flg++;
  317.                continue;
  318.                }
  319.                copymsg( j, fmailbag, resp[0]=='w' );
  320.                fclose( fmailbag );
  321.             }
  322.             if (flg)
  323.                 print = 0;
  324.             else {
  325.                 letters[j].delete = TRUE;
  326.                 modified++;
  327.                 i--;
  328.             }
  329.             break;
  330.         case 'm':
  331.             fprintf( stderr, "mail command not implemented yet!\n" );
  332.             break;
  333.         case 'f':
  334.             flg = 0;
  335.             if (resp[1] == '\n' || resp[1] == '\0') {
  336.                 i++;
  337.                 continue;
  338.             }
  339.             if (resp[1] != ' ') {
  340.                 printf( "invalid command\n" );
  341.                 flg++;
  342.                 print = 0;
  343.                 continue;
  344.             }
  345.  
  346.             sendmail( j, p );
  347.  
  348.             if (flg)
  349.                 print = 0;
  350.             else {
  351.                 letters[j].delete = TRUE;
  352.                 modified++;
  353.                 i++;
  354.             }
  355.             break;
  356.  
  357.         case 'd':
  358.             letters[j].delete = TRUE;
  359.             modified++;
  360.             i--;
  361.             if (resp[1] == 'q')
  362.                 goto donep;
  363.             break;
  364.  
  365.         case 'h':
  366.             printsub( -1 );
  367.             break;
  368.  
  369.         case 'H':
  370.             printsub( i );
  371.             break;
  372.  
  373.         }
  374.  
  375.     }
  376.     donep:
  377.     if ( modified )
  378.         copyback();
  379. }
  380.  
  381. readaline( adr, line )
  382. long adr;
  383. char *line;
  384. {
  385.     char     buf[132];
  386.     char    *cp;
  387.  
  388.     *line = '\0';
  389.     if ( adr != -1L )
  390.         if ( fseek( fmailbox, adr, 0 ) == 0 )
  391.             if ( fgets( buf, 132, fmailbox ) != (char *)NULL )
  392.                 strcpy( line, buf );
  393.  
  394.     if ( (cp = index( line, '\n' ) ) != (char *) NULL)
  395.         *cp = '\0';
  396. }
  397.  
  398.  
  399. /*
  400. returnaddress()
  401. {
  402.     readaline( lp->from, line );
  403.     if (
  404.         ( i = index( line, '<' )) != 0 &&
  405.         ( k = index( line, '>')) != 0 &&
  406.         ( k > i )
  407.         )
  408.     {
  409.         k -= i;
  410.         strncpy( from, line[i], k );
  411.         from[k] = '\0';
  412.     }
  413.     else {
  414.  
  415.  
  416.     }
  417. }
  418. */
  419.  
  420. printsub( K )
  421. {
  422.     struct ldesc    *ld;
  423.     int        j;
  424.     char    from[132], subject[132], date[132], line[132];
  425.     register char    *sp, *dp, *lp, *tp;
  426.     int k, mink, maxk;
  427.  
  428.     pagereset();
  429.  
  430.     if ( K == -1 ) {
  431.         maxk = letternum -1;
  432.         mink = 0;
  433.     }
  434.     else
  435.         maxk = mink = K;
  436.  
  437.     for ( k = maxk ; k >= mink ; k-- ) {
  438.  
  439.         j = invert( k );
  440.         ld = & letters[ j /*k*/];
  441.  
  442.          (void)strcpy(from, "unknown");    /* default to "unknown" */
  443.         readaline( ld->from, line );
  444.         if ( strlen( line ) > 0 ) {
  445.             /* Assume From: mailbox@site.domain */
  446.             /* get first usable stuff after From: */
  447.             sp = index( line, ':' ) + 1;
  448.  
  449.             /* do we have From: mailbox@site.domain ( Proper Name ) */
  450.             if ( ( ( tp = index( line, '(' )) != (char *) NULL &&
  451.                     ( lp = index( line, ')')) != (char *) NULL  ) )
  452.                 sp = ++tp;
  453.             /* or we may have From: Proper Name < mailbox@site.domain > */
  454.             else
  455.                 lp = index( line, '<');
  456.  
  457.             if ( *lp == '<' || *lp == ')' )
  458.                 --lp;
  459.  
  460.             /* if we didn't get either of the last two, just grab line */
  461.             if ( lp < sp || lp == (char *) NULL )
  462.                 lp = line + strlen( line ) - 1;
  463.  
  464.             /*debugMsg("\PCheck isspace *sp");*/
  465.             while ( isspace( *sp ) ) sp++;
  466.  
  467.             /*debugMsg("\PCheck isspace *lp");*/
  468.             while ( isspace( *lp ) ) lp--;
  469.  
  470.             dp = from;
  471.             while ( sp <= lp ) *dp++ = *sp++;
  472.             *dp = '\0';
  473.         }
  474.  
  475.         /* Date: Wed May 13 23:59:53 1987 */
  476.          *date = '\0';    /* default date to null */
  477.         readaline( ld->date, date );
  478.         if ( strlen( date ) > 0 ) {
  479.             sscanf( date, "%*s %*s %s %s", line, subject );
  480.             sprintf( date, "%s %s", line, subject );
  481.         }
  482.  
  483.         strcpy( subject, "--- no subject ---" );
  484.         readaline( ld->subject, line );
  485.         if ( strlen( line ) > 0 ) {
  486.             sp = line;
  487.             while ( !isspace( *sp ) ) sp++;
  488.             while ( isspace( *sp ) ) sp++;
  489.             strcpy( subject, sp );
  490.             }
  491.  
  492.         from[20] = '\0';
  493.         date[6] = '\0';
  494.         subject[35] = '\0';
  495.  
  496.         sprintf( line, "%3d  %6s  %20s %35s (%6d)\n",
  497.                         j, date, from, subject, ld->size );
  498.         if ( pageline( line ) == TRUE )
  499.             break;
  500.     }
  501. }
  502.  
  503.  
  504. copyback()
  505. {
  506.     register i, n, c;
  507.     int new = 0;
  508.  
  509.     if (( fmailbag = FOPEN( mfilename, "w", 'b' )) == (FILE *)NULL ) {
  510.         fprintf (stderr, "mail: can't rewrite %s\n", mfilename );
  511.         finis();
  512.     }
  513.     n = 0;
  514.     for ( i = 0; i < letternum; i++ )
  515.         if ( letters[i].delete == FALSE ) {
  516.             copymsg( i, fmailbag, FALSE );
  517.             n++;
  518.         }
  519.     fclose (fmailbag );
  520. }
  521.  
  522.  
  523. /* copy a message
  524.    if noheaders true, don't copy header lines
  525. */
  526. copymsg( n, f, noheaders )
  527. FILE *f;
  528. {
  529.     long     bytes;
  530.     char    buf[BUFSIZ];
  531.  
  532.     fseek( fmailbox, letters[n].adr, 0 );
  533.     bytes = letters[n+1].adr - letters[n].adr;
  534.  
  535.     while ( bytes > 0 && fgets( buf, BUFSIZ, fmailbox ) != (char *)NULL ) {
  536.         bytes -= strlen( buf );
  537.  
  538.         /* write line */
  539.         if ( !noheaders  )
  540.             fputs( buf, f );
  541.  
  542.         /* reset header */
  543.         if ( noheaders  && strcmp( buf, "\n") == SAME )
  544.             noheaders  = FALSE;
  545.  
  546.     }
  547. }
  548.  
  549. pager(n)
  550. {
  551.     long     bytes;
  552.     char    buf[BUFSIZ];
  553.  
  554.     fseek( fmailbox, letters[n].adr, 0 );
  555.     bytes = letters[n+1].adr - letters[n].adr;
  556.  
  557.     pagereset();
  558.     while ( bytes > 0 && fgets( buf, BUFSIZ, fmailbox ) != (char *)NULL ) {
  559.         bytes -= strlen( buf );
  560.         if ( pageline( buf ) == TRUE )
  561.             break;
  562.     }
  563.  
  564.     pageline( "\n" );
  565. }
  566.  
  567. pagereset()
  568. {
  569.     PageCount = 0;
  570. }
  571.  
  572. pageline( s )
  573. char * s;
  574. {
  575.     char c;
  576.  
  577.     fputs( s, stdout );
  578.     if ( ++PageCount > 24 ) {
  579.         PageCount = 0;
  580.         c = get_one();
  581.         switch( c ) {
  582.         case 'q':
  583.         case 'Q':
  584.         case '\003':
  585.         case 'x':
  586.         case 'X':
  587.             return( TRUE );
  588.         }
  589.     }
  590.     return( FALSE );
  591. }
  592.  
  593. char *getnext( s, p )
  594. register char **s, *p;
  595. {
  596.     *s = (char *)NULL;
  597.     while ( *p == ' ' || *p == '\t' )
  598.         p++;
  599.     if ( *p == '\n' || *p == '\0' )
  600.         return( (char *)NULL );
  601.     *s = p;
  602.     while ( *p != ' ' && *p != '\t' && *p != '\n' && *p != '\0' )
  603.         *p++;
  604.     if ( *p != '\0' )
  605.         *p++ = '\0';
  606.     return(p);
  607. }
  608.  
  609.  
  610.  
  611.  
  612.