Back to index

courier  0.68.2
rfc822hdr.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 2001-2011 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #include      "config.h"
00007 #include      <stdio.h>
00008 #include      <ctype.h>
00009 #include      <stdlib.h>
00010 #include      <string.h>
00011 #include      "rfc822hdr.h"
00012 
00013 
00014 /*
00015 ** Read the next mail header.
00016 */
00017 
00018 int rfc822hdr_read(struct rfc822hdr *h, FILE *f, off_t *pos, off_t epos)
00019 {
00020        size_t n=0;
00021        int c;
00022 
00023        for (;;)
00024        {
00025               if ( n >= h->hdrsize)
00026               {
00027                      size_t hn=h->hdrsize + 1024;
00028                      char *p= h->header ? realloc(h->header, hn):
00029                             malloc(hn);
00030 
00031                      if (!p)
00032                             return (-1);
00033 
00034                      h->header=p;
00035                      h->hdrsize=hn;
00036               }
00037 
00038               if (pos && *pos >= epos)
00039               {
00040                      h->header[n]=0;
00041                      break;
00042               }
00043 
00044               c=getc(f);
00045               if (c == EOF)
00046               {
00047                      if (pos)
00048                             *pos=epos;
00049                      h->header[n]=0;
00050                      break;
00051               }
00052               if (pos)
00053                      ++*pos;
00054 
00055               h->header[n]=c;
00056               if (c == '\n')
00057               {
00058                      if (n == 0)
00059                      {
00060                             if (pos)
00061                                    *pos=epos;
00062                             h->header[n]=0;
00063                             break;
00064                      }
00065 
00066                      c=getc(f);
00067                      if (c != EOF)
00068                             ungetc(c, f);
00069                      if (c == '\n' || c == '\r' ||
00070                          !isspace((int)(unsigned char)c))
00071                      {
00072                             h->header[n]=0;
00073                             break;
00074                      }
00075               }
00076               n++;
00077               if (h->maxsize && n + 2 > h->maxsize)
00078                      --n;
00079        }
00080 
00081        if (n == 0)
00082        {
00083               if (pos)
00084                      *pos=epos;
00085               h->value=h->header;
00086               return (1);
00087        }
00088 
00089        for (h->value=h->header; *h->value; ++h->value)
00090        {
00091               if (*h->value == ':')
00092               {
00093                      *h->value++=0;
00094                      while (*h->value &&
00095                             isspace((int)(unsigned char)*h->value))
00096                             ++h->value;
00097                      break;
00098               }
00099        }
00100        return (0);
00101 }
00102 
00103 void rfc822hdr_fixname(struct rfc822hdr *h)
00104 {
00105        char *p;
00106 
00107        for (p=h->header; *p; p++)
00108        {
00109               *p=tolower((int)(unsigned char)*p);
00110        }
00111 }
00112 
00113 void rfc822hdr_collapse(struct rfc822hdr *h)
00114 {
00115        char *p, *q;
00116 
00117        for (p=q=h->value; *p; )
00118        {
00119               if (*p == '\n')
00120               {
00121                      while (*p && isspace((int)(unsigned char)*p))
00122                             ++p;
00123                      *q++=' ';
00124                      continue;
00125               }
00126               *q++ = *p++;
00127        }
00128        *q=0;
00129 }
00130 
00131 /* This is, basically, a case-insensitive US-ASCII comparison function */
00132 
00133 #define lc(x) ((x) >= 'A' && (x) <= 'Z' ? (x) + ('a'-'A'):(x))
00134 
00135 int rfc822hdr_namecmp(const char *a, const char *b)
00136 {
00137        int rc;
00138 
00139        while ((rc=(int)(unsigned char)lc(*a) - (int)(unsigned char)lc(*b))==0)
00140        {
00141               if (!*a)
00142                      return 0;
00143               ++a;
00144               ++b;
00145        }
00146 
00147        return rc;
00148 }
00149 
00150 int rfc822hdr_is_addr(const char *hdr)
00151 {
00152        return rfc822hdr_namecmp(hdr, "from") == 0 ||
00153               rfc822hdr_namecmp(hdr, "to") == 0 ||
00154               rfc822hdr_namecmp(hdr, "cc") == 0 ||
00155               rfc822hdr_namecmp(hdr, "bcc") == 0 ||
00156               rfc822hdr_namecmp(hdr, "resent-from") == 0 ||
00157               rfc822hdr_namecmp(hdr, "resent-to") == 0 ||
00158               rfc822hdr_namecmp(hdr, "resent-cc") == 0 ||
00159               rfc822hdr_namecmp(hdr, "resent-bcc") == 0;
00160 }