home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume12 / psf2 / part03 / pmf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-19  |  6.3 KB  |  306 lines

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