home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / b / bmh02src.zip / HEADER.C < prev    next >
C/C++ Source or Header  |  1992-08-16  |  5KB  |  220 lines

  1. /*
  2.    header.c: Copyright Paul Healy, EI9GL, 1992.
  3.  
  4.    Derived from bm.
  5.  
  6.    Copyright 1986 Bdale Garbee, All Rights Reserved.
  7.    Permission granted for non-commercial copying and use, provided
  8.    this notice is retained.
  9.    Copyright 1987 1988 Dave Trulli NN2Z, All Rights Reserved.
  10.    Permission granted for non-commercial copying and use, provided
  11.    this notice is retained.
  12.  
  13.    920712: Added this header.
  14.    920717: Todo - add line continuation support
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <ctype.h>
  19. #include <string.h>
  20. #include "header.h"
  21. #include "buffer.h"
  22. #include "misc.h"
  23.  
  24. #define MaxHdrLength 10
  25.  
  26. static char hd[][MaxHdrLength] = {
  27.    /*
  28.     * Currently only interested in parsing these headers. 
  29.     */
  30.    "cc",
  31.    "date",
  32.    "from",
  33.    "newsgroup",
  34.    "reply-to",
  35.    "subject",
  36.    "to"
  37. };
  38.  
  39. static const int NumHeaders = sizeof(hd) / MaxHdrLength;
  40.  
  41. /*
  42.  * return the header token type
  43.  * On a undamaged mailfile, this routine should always be called with some
  44.  * kind of header. Line continuations shouldn't reach this far as well.
  45.  *
  46.  */
  47. Header
  48. htype(char *s)
  49. {
  50.    char *p, *k, key[100], *result;
  51.  
  52.    p = s;
  53.    k = key;
  54.    /*
  55.     * check to see if there is a ':' before and white space after
  56.     */
  57.    while (*p && (*p != ':') && (*p != ' ') )
  58.       *k++ = isupper(*p) ? tolower(*p++) : *p++;
  59.    if ( (*p != ':') || ( *(p+1) != ' ') )
  60.       return NOHEADER;
  61.    *k = '\0';
  62.  
  63.    result = bsearch(key, hd, NumHeaders, MaxHdrLength, strcmp);
  64.  
  65.    return result == NULL ? UNKNOWN : (result - (char *) hd) / MaxHdrLength;
  66. }
  67.  
  68. void
  69. freeheader(char *argv[])
  70. {
  71.    int i;
  72.  
  73.    for (i=0; i<MAXHDR; i++)
  74.       if ( argv[i] != NULL )
  75.          free(argv[i]);
  76. }
  77.  
  78. /*
  79.  *  Read from the file parsing headers. Fill in details in the argv array
  80.  *  for any non-null entry.
  81. */
  82. int
  83. parseheader(char **start, char **end, char *argv[])
  84. {
  85.    char line[1024];
  86.    int i;
  87.  
  88.    for (i=0; i<MAXHDR; i++)
  89.       argv[i] = NULL;
  90.  
  91.    while (getstring(start, end, line, sizeof(line)) != NULL) {
  92.       Header h;
  93.  
  94.       if (line[0] == '\0')                        /* end of headers */
  95.          break;
  96.       if (line[0] == ' ' || line[0] == '\t')      /* line continuation */
  97.          continue;                                /* fix this later */
  98.       if (line[0] == '>')  /* Escaped '>From' */
  99.          continue;     
  100.       h = htype(line);
  101.       if ( h == UNKNOWN )
  102.          continue;
  103.       if ( h == NOHEADER ) {
  104.          fprintf(stderr, "parseheader: bad header %s\n", line);
  105.          return -1;
  106.          }
  107.       argv[h] = strdup(line);
  108.       }
  109.    return 0;
  110. }
  111.  
  112. /*
  113.  *  Read from the file parsing headers. Fill in details in the argv array
  114.  *  for any non-null entry. The file is left at the first line of the
  115.  *  message body.
  116.  */
  117. int
  118. parseheaderfile(FILE *fp, char *argv[])
  119. {
  120.    char line[1024];
  121.    int i;
  122.  
  123.    for (i=0; i<MAXHDR; i++)
  124.       argv[i] = NULL;
  125.  
  126.    while (fgets(line, sizeof(line), fp) != NULL) {
  127.       Header h;
  128.  
  129.       if ((*line == '\n') || (*line == '-') ) /* end of headers */
  130.          break;
  131.       if (*line == ' ' || *line == '\t')      /* line continuation */
  132.          continue;                            /* fix this later */
  133.       if (line[0] == '>')  /* Escaped '>From' */
  134.          continue;     
  135.       h = htype(line);
  136.       if ( h == UNKNOWN )
  137.          continue;
  138.       if ( h == NOHEADER ) {
  139.          fprintf(stderr, "parseheader: bad header %s", line);
  140.          return -1;
  141.          }
  142.          
  143.       rip(line);   
  144.       argv[h] = strdup(line);
  145.       }
  146.    return 0;
  147. }
  148.  
  149.  
  150.  
  151.  
  152. /*
  153.  * return the header token type
  154.  * On a undamaged mailfile, this routine should always be called with some
  155.  * kind of header. Line continuations shouldn't reach this far as well.
  156.  *
  157.  */
  158. Header
  159. loosehtype(char *s, char **data)
  160. {
  161.    char *p = s,
  162.       key[100], *k = key, *result;
  163.  
  164.    /*
  165.     * check to see if there is a ':' 
  166.     */
  167.    while (*p && (*p != ':') )
  168.       *k++ = isupper(*p) ? tolower(*p++) : *p++;
  169.    if ( *p != ':' )
  170.       return NOHEADER;
  171.    *k = '\0';
  172.  
  173.    result = bsearch(key, hd, NumHeaders, MaxHdrLength, strcmp);
  174.  
  175.    k = p + 1;
  176.    while (isspace(*k))
  177.       k++;
  178.    *data = k;
  179.  
  180.    return result == NULL ? UNKNOWN : (result - (char *) hd) / MaxHdrLength;
  181. }
  182.  
  183. /*
  184.  *  Read from the file parsing headers. Fill in details in the argv array
  185.  *  for any non-null entry. The file is left at the first line of the
  186.  *  message body.
  187.  */
  188. int
  189. looseparseheaderfile(FILE *fp, char *argv[])
  190. {
  191.    char line[1024];
  192.    int i;
  193.  
  194.    for (i=0; i<MAXHDR; i++)
  195.       argv[i] = NULL;
  196.  
  197.    while (fgets(line, sizeof(line), fp) != NULL) {
  198.       Header h;
  199.       char *data;
  200.  
  201.       if ((*line == '\n') || (*line == '-') ) /* end of headers */
  202.          break;
  203.       if (*line == ' ' || *line == '\t')      /* line continuation */
  204.          continue;                            /* fix this later */
  205.       if (line[0] == '>')  /* Escaped '>From' */
  206.          continue;     
  207.       h = loosehtype(line, &data);
  208.       if ( h == UNKNOWN )
  209.          continue;
  210.       if ( h == NOHEADER ) {
  211.          fprintf(stderr, "looseparseheader: bad header %s", line);
  212.          return -1;
  213.          }
  214.          
  215.       rip(data);   
  216.       argv[h] = strdup(data);
  217.       }
  218.    return 0;
  219. }
  220.