home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume27 / psf3 / part05 / psfmail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-20  |  6.3 KB  |  309 lines

  1. /* ta=4 */
  2. /****************************************************************************
  3. *                        p s f m a i l . c                                    *
  4. *                                                                            *
  5. *    postscript mail filter                                                    *
  6. *                                                                            *
  7. *    very simple mail filter to print name and subject in bold letters        *
  8. *    for psf usage.  Generates escape sequences that psf can understand.        *
  9. *    Modify the code if you wish to have various headers ignored for print.    *
  10. *                                                                            *
  11. *    Tony Field.       tony@ajfcal.cuc.ab.ca                                    *
  12. ****************************************************************************/
  13. /*
  14.  * $Id: psfmail.c,v 3.2 1992/01/19 05:50:33 ajf Exp ajf $
  15.  *
  16. */
  17.  
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <ctype.h>
  21. #include "patchlevel.h"
  22. #include "psf.h"
  23.  
  24. #define MAX_C        62            /*    max char wrap point on mail header line    */
  25.  
  26. char    *pgmname;
  27.  
  28. FILE    *outfp;
  29.  
  30. main (argc, argv)
  31. int        argc;
  32. char    *argv[];
  33. {
  34.     int        ignore_garbage, i;
  35.     extern char *optarg;
  36.     extern int    optind;
  37.     FILE    *input_fp;
  38.  
  39.     outfp = stdout;
  40.     pgmname = argv[0];    
  41.     ignore_garbage = 1;
  42.     if (strcmp (argv[1], "-") == 0)
  43.         usage();
  44.     while ((i = getopt(argc, argv, "s-")) != -1)
  45.     {    switch (i)
  46.         {
  47.         case 's':
  48.             ignore_garbage = 0;        /*    print all headers    */
  49.             break;
  50.  
  51.         default:
  52.             usage ();
  53.         }
  54.     }
  55.     if (optind >= argc)
  56.     {    input_fp = stdin;
  57.         print_file (input_fp, ignore_garbage);
  58.     }
  59.     else
  60.     {
  61.         for ( i = 0;  optind < argc;  optind++)
  62.         {    if ((input_fp = fopen (argv[optind], "r")) == NULL)
  63.             {    fprintf (stderr, "%s: File %s not found\n", pgmname, argv[optind]);
  64.             }
  65.             else
  66.             {    if (i)
  67.                     send ("\f");
  68.                 print_file (input_fp, ignore_garbage);
  69.                 fclose (input_fp);
  70.                 i++;
  71.             }
  72.         }
  73.     }
  74.     exit (0);
  75. }
  76.  
  77. print_file (fp, ignore_garbage)
  78. FILE *fp;
  79. int     ignore_garbage;
  80. {
  81.     char    line[900], first[100], tail[800], *strchr();
  82.     int        last_char, header, garbage;
  83.  
  84.     header = garbage = 0;
  85.     while (fgets (line, 999, fp)  != NULL)
  86.     {
  87. newmail:
  88.         last_char = split (line, first, tail);
  89.  
  90.         /*    The following headers will be ignored during printing    */
  91.         
  92.         if (ignore_garbage 
  93.             &&  (strcmp (first, "Distribution:"  ) == 0
  94.             ||   strcmp (first, "Keywords:"      ) == 0
  95.             ||   strcmp (first, "Lines:"         ) == 0
  96.             ||   strcmp (first, "Message-ID:"    ) == 0
  97.             ||   strcmp (first, "Message-Id:"    ) == 0
  98.             ||   strcmp (first, "News-Path:"     ) == 0
  99.             ||   strcmp (first, "Path:"          ) == 0
  100.             ||   strcmp (first, "Posted:"        ) == 0
  101.             ||   strcmp (first, "Received:"      ) == 0
  102.             ||   strcmp (first, "References:"    ) == 0
  103.             ||   strcmp (first, "Sender:"        ) == 0
  104.             ||   strcmp (first, "Status:"        ) == 0
  105.             ||   strncmp(first, "X-",          2 ) == 0))
  106.         {    garbage = 1;
  107.         }
  108.         else if (strcmp (first, "From") == 0)
  109.         {    printclean (first, tail);
  110.             garbage = 0;
  111.         }
  112.         else if (strcmp (first, "From:") == 0
  113.                 ||  strcmp (first, "Reply-To:") == 0
  114.                 ||  strcmp (first, "To:") == 0)
  115.         {    header = 1;
  116.             if ((strchr (tail, '(') == NULL)  &&  (strchr (tail, '<') == NULL))
  117.                 printbold (first, tail);
  118.             else
  119.                 printname (first, tail);
  120.             garbage = 0;
  121.         }
  122.         else if (strcmp (first, "Bcc:") == 0 ||  strcmp (first, "Cc:") == 0)
  123.         {    header = 1;
  124.             printname (first, tail);
  125.             garbage = 0;
  126.         }
  127.         else if (strcmp (first, "Subject:") == 0)
  128.         {    printsubject (first, tail);
  129.             garbage = 0;
  130.         }
  131.         else if (last_char == ':')
  132.         {
  133.             header = 1;
  134.             printclean (first, tail);
  135.             garbage = 0;
  136.         }
  137.         else if (empty (line))
  138.         {    
  139.             send ("\n");
  140.             while (fgets (line, 999, fp) != NULL)
  141.             {    if (strncmp (line, "From ", 5) == 0
  142.                     &&  (strchr (line, ':') < strrchr (line, ':')))
  143.                 {    send ("\f");
  144.                     goto newmail;    /* goto's considered harmful since 1964 */
  145.                 }
  146.                 printf ("%s", line);
  147.             }
  148.             break;
  149.         }
  150.         else if (garbage == 0)
  151.             printclean (" ", line);
  152.     }
  153. }
  154.  
  155. printclean (first, tail)
  156. char    *first, *tail;
  157. {
  158.     printf ("%-14s", first);
  159.     printlong (tail);
  160. }
  161.  
  162. printlong (tail)
  163. char    *tail;
  164. {    char    *c;
  165.     int        marks[100], nmarks, i, j, nchar;
  166.  
  167.     /*    locate all marks that can be use for a line break     */
  168.  
  169.     marks[0] = 0;
  170.     marks[1] = 0;
  171.     c = tail;
  172.     for ( i = nchar = 0, nmarks = 1;  nmarks < 100;  i++, c++, nchar++)
  173.     {
  174.         if (*c == '!'  ||  *c == ' ' ||  *c == '<'  
  175.             ||  *c == '('  ||  *c == '\0')
  176.         {    if (nchar < MAX_C)
  177.                 marks[nmarks] = i;
  178.             else
  179.             {    nchar = i - marks[nmarks];
  180.                 marks[++nmarks] = i;
  181.             }
  182.             if (*c == '\0')
  183.                 break;
  184.         }
  185.     }
  186.     marks[nmarks] = i;
  187.     for (i = 0;  i < nmarks;  i++)
  188.     {
  189.         if (i)
  190.             printf ("%-14s", " ");
  191.         for (j = marks[i];  j < marks[i+1];  j++)
  192.             fputc (tail[j], outfp);
  193.         fputc ('\n', outfp);
  194.     }
  195. }
  196.  
  197. printsubject (first, tail)
  198. char    *first, *tail;
  199. {
  200.     printf ("%-14s", first);
  201.     send (BEGIN_SUBJECT);
  202.     send (tail);
  203.     send (END_SUBJECT);
  204.     send ("\n");
  205. }
  206.  
  207. printbold (first, tail)
  208. char    *first, *tail;
  209. {
  210.     printf ("%-14s", first);
  211.     send (BEGIN_BOLD);
  212.     printlong (tail);
  213.     send (END_BOLD);    
  214. }
  215.  
  216. printname (first, tail)
  217. char    *first, *tail;
  218. {
  219.     printf ("%-14s", first);
  220.  
  221.     if (strchr (tail, '<') != NULL)
  222.     {    /*    address syntax "name <address> stuff" */
  223.         send (BEGIN_NAME);
  224.         while (*tail != '<')
  225.             fputc (*tail++, outfp);
  226.         send (END_NAME);
  227.         fputc (*tail++, outfp);
  228.         while (*tail)
  229.         {    fputc (*tail, outfp);
  230.             if (*tail++ == '>')
  231.             {    if (*tail)
  232.                 {    send (BEGIN_NAME);
  233.                     while (*tail)
  234.                         fputc (*tail++, outfp);
  235.                     send (END_NAME);
  236.                 }
  237.             }
  238.         }
  239.     }
  240.     else
  241.     {    /*    address syntax "address (name)" */
  242.         while (*tail  &&  *tail != '(')
  243.             fputc (*tail++, outfp);
  244.         if (*tail)
  245.         {    send (BEGIN_NAME);
  246.             fputc (*tail++, outfp);
  247.             while (*tail)
  248.             {    fputc (*tail, outfp);
  249.                 if (*tail++ == ')')
  250.                 {    send (END_NAME);
  251.                     while (*tail)
  252.                         fputc (*tail++, outfp);
  253.                     fputc ('\n', outfp);
  254.                     return;
  255.                 }
  256.             }
  257.         }
  258.     }
  259.     fputc ('\n', outfp);
  260. }
  261.  
  262. send (s)
  263. char    *s;
  264. {
  265.     while (*s)
  266.         fputc (*s++, outfp);
  267. }
  268.  
  269. empty (s)
  270. char    *s;
  271. {    while (*s  &&  *s <= ' ')
  272.         s++;
  273.     if (*s)
  274.         return (0);
  275.     else
  276.         return (1);
  277. }
  278.  
  279. split (line, first, tail)
  280. char    *line;            /*    input:    full input line            */
  281. char    *first;            /*    return:    first word of line        */
  282. char    *tail;            /*    return:    all others words of line*/
  283. {    int    last;
  284.  
  285.     last = 0;
  286.     while (*line  &&  isspace (*line) == 0)
  287.     {    last = *line;
  288.         *first++ = *line++;
  289.     }
  290.     *first = '\0';
  291.     
  292.     while (*line  &&  isspace (*line))
  293.         line++;
  294.     
  295.     while (*line  &&  *line != '\n')
  296.         *tail++ = *line++;
  297.     *tail = '\0';
  298.     *line = '\0';
  299.     return (last);
  300. }
  301.  
  302. usage ()
  303. {
  304.     fprintf (stderr, "Usage:   psfmail [-s] files... >out.file\n");
  305.     fprintf (stderr, " where            -s  = show all header lines\n");
  306.     fprintf (stderr, "                files = input files (or stdin)\n");
  307.     exit (0);    
  308. }
  309.