home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / communic / pcmail / main / ms_parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  4.0 KB  |  148 lines

  1. /*++
  2. /* NAME
  3. /*      ms_parse 3
  4. /* SUMMARY
  5. /*      message parser
  6. /* PROJECT
  7. /*      pc-mail
  8. /* PACKAGE
  9. /*      mailsh
  10. /* SYNOPSIS
  11. /*    #include "ms_parse.h"
  12. /*
  13. /*    int ms_parse(context, line)
  14. /*    int context;
  15. /*    char *line;
  16. /*
  17. /*    int hscanf(line, prefix, format, result)
  18. /*    char *line;
  19. /*    char *prefix;
  20. /*    char *format;
  21. /*    char *result;
  22. /* DESCRIPTION
  23. /*    The routines in this module recognize
  24. /*    the context in which successive lines of text occur within an
  25. /*    e-mail message, or extract specific information from header
  26. /*    lines.
  27. /*
  28. /*    The expected format of an e-mail message is: UUCP header lines,
  29. /*    RFC822-like header lines, message body. Each of these sections
  30. /*    may be missing from the message. A header line is a line that
  31. /*    has no blanks before the first colon appearing on that line.
  32. /*
  33. /*    ms_parse() determines the context in which a line of text was found:
  34. /*
  35. /* .nf
  36.     MS_UUCP        UUCP-style From_ line
  37.     MS_HEADER    RFC822-like header line
  38.     MS_CONT        Continued header line
  39.     MS_BODY        Line within message body
  40. /* .fi
  41. /*
  42. /*    During the first call of ms_parse(), the context argument should have 
  43. /*    the value MS_UUCP. Upon successive calls the value should be equal
  44. /*    to the last value returned by ms_parse(). The algorithm is transparent
  45. /*    to other context values (i.e. they cause no transitions).
  46. /*
  47. /*    hscanf() compares the beginning of a line with the specified prefix
  48. /*    (ignoring case differences), and if the comparison succeeds, it
  49. /*    invokes sscanf() on the remainder of that line. A zero return value
  50. /*    means that no information was extracted with sscanf.
  51. /* AUTHOR(S)
  52. /*      W.Z. Venema
  53. /*      Eindhoven University of Technology
  54. /*      Department of Mathematics and Computer Science
  55. /*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  56. /* CREATION DATE
  57. /*    Sat Dec  9 18:50:35 MET 1989
  58. /* LAST MODIFICATION
  59. /*    90/01/22 13:02:12
  60. /* VERSION/RELEASE
  61. /*    2.1
  62. /*--*/
  63.  
  64. #include <stdio.h>
  65. #include <ctype.h>
  66.  
  67. #include "defs.h"
  68. #include "ms_parse.h"
  69.  
  70. /* forward declarations */
  71.  
  72. hidden int isheader();
  73.  
  74. /* hscanf - match header and extract info from remainder of header line */
  75.  
  76. public int hscanf(line, pre, fmt, ptr)
  77. char   *line;
  78. char   *pre;
  79. char   *fmt;
  80. char   *ptr;
  81. {
  82.     int     len = strlen(pre);
  83.  
  84.     return (istrncmp(pre, line, len) == 0 && sscanf(line + len, fmt, ptr) == 1);
  85. }
  86.  
  87. /* ms_parse - parse one message line */
  88.  
  89. public int ms_parse(context, line)
  90. register int context;
  91. register char *line;
  92. {
  93.  
  94.     /*
  95.      * A message may begin with UUCP header lines ("From blablabla",
  96.      * sometimes escaped with a ">" character), followed by RFC822-like
  97.      * header lines (lines that start with a word + colon, or continuation
  98.      * lines that start with whitespace), followed by the remainder of the
  99.      * message. Header and body are usually separated by an empty line (on
  100.      * systems that can handle that) but the we do not require this.
  101.      */
  102.  
  103.     switch (context) {
  104.     case MS_UUCP:
  105.     if (line[0] == '>' || strncmp(line, "From ", 5) == 0)
  106.         return (MS_UUCP);
  107.     if (isspace(line[0]))
  108.         return (MS_BODY);
  109.     /* FALLTHROUGH */
  110.     case MS_HEADER:
  111.     case MS_CONT:
  112.     if (isspace(line[0]))
  113.         return (MS_CONT);
  114.     if (isheader(line))
  115.         return (MS_HEADER);
  116.     /* FALLTHROUGH */
  117.     case MS_BODY:
  118.     return (MS_BODY);
  119.     }
  120.     /* NOTREACHED */
  121. }
  122.  
  123. /* isheader - does this line look like a header? */
  124.  
  125. hidden int isheader(buf)
  126. char   *buf;
  127. {
  128.     static char blanks[] = " \t\f";
  129.     char   *cp;
  130.     char   *blk;
  131.     char   *colon;
  132.  
  133.     /*
  134.      * A header line has no blanks before the first colon. Which means that a
  135.      * line that starts with a colon character is treated as header line.
  136.      * This turns out to be what many sendmail implementations do, too.
  137.      */
  138.  
  139.     if ((colon = index(buf, ':')) == 0) {    /* check for colon */
  140.     return (0);
  141.     } else {                    /* find preceding blanks */
  142.     for (cp = blanks; *cp; cp++)
  143.         if ((blk = index(buf, *cp)) != 0 && blk < colon)
  144.         return (0);
  145.     }
  146.     return (1);
  147. }
  148.