From 9c45d9ad13fdf439d44d7443ae75da15ea0223ed Mon Sep 17 00:00:00 2001 From: Sam Varshavchik Date: Mon, 19 Aug 2013 16:39:41 -0400 Subject: Initial checkin Imported from subversion report, converted to git. Updated all paths in scripts and makefiles, reflecting the new directory hierarchy. --- rfc822/rfc822hdr.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 rfc822/rfc822hdr.c (limited to 'rfc822/rfc822hdr.c') diff --git a/rfc822/rfc822hdr.c b/rfc822/rfc822hdr.c new file mode 100644 index 0000000..1ce3106 --- /dev/null +++ b/rfc822/rfc822hdr.c @@ -0,0 +1,160 @@ +/* +** Copyright 2001-2011 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#include "config.h" +#include +#include +#include +#include +#include "rfc822hdr.h" + + +/* +** Read the next mail header. +*/ + +int rfc822hdr_read(struct rfc822hdr *h, FILE *f, off_t *pos, off_t epos) +{ + size_t n=0; + int c; + + for (;;) + { + if ( n >= h->hdrsize) + { + size_t hn=h->hdrsize + 1024; + char *p= h->header ? realloc(h->header, hn): + malloc(hn); + + if (!p) + return (-1); + + h->header=p; + h->hdrsize=hn; + } + + if (pos && *pos >= epos) + { + h->header[n]=0; + break; + } + + c=getc(f); + if (c == EOF) + { + if (pos) + *pos=epos; + h->header[n]=0; + break; + } + if (pos) + ++*pos; + + h->header[n]=c; + if (c == '\n') + { + if (n == 0) + { + if (pos) + *pos=epos; + h->header[n]=0; + break; + } + + c=getc(f); + if (c != EOF) + ungetc(c, f); + if (c == '\n' || c == '\r' || + !isspace((int)(unsigned char)c)) + { + h->header[n]=0; + break; + } + } + n++; + if (h->maxsize && n + 2 > h->maxsize) + --n; + } + + if (n == 0) + { + if (pos) + *pos=epos; + h->value=h->header; + return (1); + } + + for (h->value=h->header; *h->value; ++h->value) + { + if (*h->value == ':') + { + *h->value++=0; + while (*h->value && + isspace((int)(unsigned char)*h->value)) + ++h->value; + break; + } + } + return (0); +} + +void rfc822hdr_fixname(struct rfc822hdr *h) +{ + char *p; + + for (p=h->header; *p; p++) + { + *p=tolower((int)(unsigned char)*p); + } +} + +void rfc822hdr_collapse(struct rfc822hdr *h) +{ + char *p, *q; + + for (p=q=h->value; *p; ) + { + if (*p == '\n') + { + while (*p && isspace((int)(unsigned char)*p)) + ++p; + *q++=' '; + continue; + } + *q++ = *p++; + } + *q=0; +} + +/* This is, basically, a case-insensitive US-ASCII comparison function */ + +#define lc(x) ((x) >= 'A' && (x) <= 'Z' ? (x) + ('a'-'A'):(x)) + +int rfc822hdr_namecmp(const char *a, const char *b) +{ + int rc; + + while ((rc=(int)(unsigned char)lc(*a) - (int)(unsigned char)lc(*b))==0) + { + if (!*a) + return 0; + ++a; + ++b; + } + + return rc; +} + +int rfc822hdr_is_addr(const char *hdr) +{ + return rfc822hdr_namecmp(hdr, "from") == 0 || + rfc822hdr_namecmp(hdr, "to") == 0 || + rfc822hdr_namecmp(hdr, "cc") == 0 || + rfc822hdr_namecmp(hdr, "bcc") == 0 || + rfc822hdr_namecmp(hdr, "resent-from") == 0 || + rfc822hdr_namecmp(hdr, "resent-to") == 0 || + rfc822hdr_namecmp(hdr, "resent-cc") == 0 || + rfc822hdr_namecmp(hdr, "resent-bcc") == 0; +} -- cgit v1.2.3