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