home *** CD-ROM | disk | FTP | other *** search
/ Unix System Administration Handbook 1997 October / usah_oct97.iso / news / cnews.tar / relay / hdrparse.c < prev    next >
C/C++ Source or Header  |  1993-02-08  |  3KB  |  109 lines

  1. /*
  2.  * Usenet header parsing and remembering.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <sys/types.h>
  8. #include "libc.h"
  9. #include "news.h"
  10. #include "headers.h"
  11. #include "relay.h"
  12. #include "case.h"
  13. #include "hdrint.h"
  14.  
  15. #undef RFC1036                /* alters hdrparse behaviour */
  16.  
  17. /*
  18.  * Parse (assumed) RFC822 or 850/1036 header in "line" (ishdr(line) can
  19.  * verify this) into "hdrs" using hdrlst set of keywords by retaining the
  20.  * value of any matching keyword.  Keyword matching is case-insensitive.
  21.  * If the keyword in "line" matches one in hdrlst, store the value in
  22.  * *malloc'ed memory* (N.B.) pointed to by a member of "hdrs".
  23.  * freeheader() will free this memory.
  24.  */
  25. int                    /* NO, YES or YES+1 (error) */
  26. hdrparse(hdrs, line, hdrlst)
  27. register struct headers *hdrs;
  28. char *line;
  29. hdrlist hdrlst;                /* headers of positive utility */
  30. {
  31.     register struct hdrdef **hpp;
  32.     register char *hackline = hackhybrid(line);
  33.     register int match = NO;
  34.  
  35.     for (hpp = hdrlst; *hpp != NULL; hpp++) {
  36.         register char *hdrnm = (*hpp)->hdrnm;
  37.  
  38.         if (CISTREQN(hackline, hdrnm, (int)(*hpp)->hdrlen) &&
  39.             (*hpp)->hdroff >= 0        /* paranoia */
  40. #ifdef RFC1036
  41.             && hackline[(*hpp)->hdrlen] == ' '
  42. #endif
  43.             ) {
  44.             match = YES;
  45.             break;
  46.         }
  47.     }
  48.     if (match) {
  49.         register char **ptrp = (char **)((char *)hdrs+(*hpp)->hdroff);
  50.  
  51.         if (*ptrp != NULL && hdrlst == reqdhdrs)
  52.             match = YES+1;        /* duplicate req'd hdr */
  53.         else {
  54.             nnfree(ptrp);    /* free prev. value in this article */
  55.             *ptrp = strsave(skipsp(&hackline[(*hpp)->hdrlen]));
  56.             if (*ptrp != NULL)
  57.                 trim(*ptrp);    /* cut trailing \n */
  58.         }
  59.     }
  60.     free(hackline);
  61.     return match;
  62. }
  63.  
  64. /*
  65.  * default missing header values
  66.  *
  67.  * If strsave ever returns NULL on failure, instead of exiting,
  68.  * then the strsave calls need to check for failure.
  69.  *
  70.  * An article lacking a Message-ID: but possessing an (obsolete)
  71.  * Article-I.D.: gets the transformed Article-I.D. as its Message-ID:.
  72.  */
  73. void
  74. hdrdeflt(hdrs)
  75. register struct headers *hdrs;
  76. {
  77.     if (hdrs->h_distr == NULL)
  78.         hdrs->h_distr = strsave(DEFDIST);
  79.     if (hdrs->h_msgid == NULL && hdrs->h_artid != NULL)
  80.         hdrs->h_msgid = str3save("<", hdrs->h_artid, ">");
  81.     if (hdrs->h_expiry == NULL || hdrs->h_expiry[0] == '\0') {
  82.         nnfree(&hdrs->h_expiry);
  83.         hdrs->h_expiry = strsave(DEFEXP);
  84.     }
  85. }
  86.  
  87. /*
  88.  * require the headers required by RFC 1036.
  89.  */
  90. char *                    /* error string */
  91. hdrreq(hdrs)
  92. register struct headers *hdrs;
  93. {
  94.     register struct hdrdef **hpp;
  95.     static char errbuf[100];
  96.  
  97.     /* require all required headers and that they have non-empty contents */
  98.     for (hpp = reqdhdrs; *hpp != NULL; hpp++) {
  99.         register char *hdrp = *(char **)((char *)hdrs + (*hpp)->hdroff);
  100.  
  101.         if (hdrp == NULL || hdrp[0] == '\0') {
  102.             (void) sprintf(errbuf, "%s %s header\n",
  103.                 (hdrp == NULL? "no": "empty"), (*hpp)->hdrnm);
  104.             return errbuf;
  105.         }
  106.     }
  107.     return NULL;
  108. }
  109.