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. --- imap/fetchinfo.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 imap/fetchinfo.c (limited to 'imap/fetchinfo.c') diff --git a/imap/fetchinfo.c b/imap/fetchinfo.c new file mode 100644 index 0000000..96bd1e4 --- /dev/null +++ b/imap/fetchinfo.c @@ -0,0 +1,197 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#ifndef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include "imaptoken.h" +#include "imapwrite.h" +#include "fetchinfo.h" + + +/* This file contains functions to parse a FETCH attribute list */ + +static struct fetchinfo *alloc_headerlist(int); +static char *good_section(char *); + +struct fetchinfo *fetchinfo_alloc(int oneonly) +{ +struct fetchinfo *list, **listtail, *p; +struct imaptoken *tok; + + list=0; + listtail= &list; + + while ((tok=currenttoken())->tokentype == IT_ATOM) + { + if (oneonly && list) break; + *listtail=p=(struct fetchinfo *)malloc(sizeof(*list)); + if (!p) write_error_exit(0); + p->next=0; + p->name=my_strdup(tok->tokenbuf); + p->bodysection=0; + p->bodysublist=0; + p->ispartial=0; + listtail= &p->next; + + if (strcmp(p->name, "ALL") == 0 || + strcmp(p->name, "BODYSTRUCTURE") == 0 || + strcmp(p->name, "ENVELOPE") == 0 || + strcmp(p->name, "FLAGS") == 0 || + strcmp(p->name, "FAST") == 0 || + strcmp(p->name, "FULL") == 0 || + strcmp(p->name, "INTERNALDATE") == 0 || + strcmp(p->name, "RFC822") == 0 || + strcmp(p->name, "RFC822.HEADER") == 0 || + strcmp(p->name, "RFC822.SIZE") == 0 || + strcmp(p->name, "RFC822.TEXT") == 0 || + strcmp(p->name, "UID") == 0) + { + nexttoken(); + continue; + } + if (strcmp(p->name, "BODY") && strcmp(p->name, "BODY.PEEK")) + break; + if (nexttoken()->tokentype != IT_LBRACKET) continue; + + /* Parse BODY[ ... ] */ + + if ((tok=nexttoken())->tokentype != IT_RBRACKET) + { + char *s; + + if ( (tok->tokentype != IT_ATOM && + tok->tokentype != IT_NUMBER) || + !(s=good_section(tok->tokenbuf))) + { + fetchinfo_free(list); + return (0); + } + p->bodysection=my_strdup(tok->tokenbuf); + + if (strcmp(s, "HEADER.FIELDS") == 0 || + strcmp(s, "HEADER.FIELDS.NOT") == 0) + { + /* Must be followed by header list */ + + if ((tok=nexttoken_nouc())->tokentype + != IT_LPAREN) + { + p->bodysublist=alloc_headerlist(1); + if (p->bodysublist == 0) + { + fetchinfo_free(list); + return (0); + } + } + else + { + nexttoken_nouc(); + p->bodysublist=alloc_headerlist(0); + if ( currenttoken()->tokentype + != IT_RPAREN) + { + fetchinfo_free(list); + return (0); + } + } + } + tok=nexttoken(); + + } + else p->bodysection=my_strdup(""); + + if (tok->tokentype != IT_RBRACKET) + { + fetchinfo_free(list); + return (0); + } + tok=nexttoken(); + if (tok->tokentype == IT_ATOM && tok->tokenbuf[0] == '<' && + tok->tokenbuf[strlen(tok->tokenbuf)-1] == '>' && + (p->ispartial=sscanf(tok->tokenbuf+1, "%lu.%lu", + &p->partialstart, &p->partialend)) > 0) + nexttoken(); + } + return (list); +} + +/* Just validate that the syntax of the attribute is correct */ + +static char *good_section(char *p) +{ +int has_mime=0; + + while (isdigit((int)(unsigned char)*p)) + { + if (*p == '0') return (0); + has_mime=1; + while (isdigit((int)(unsigned char)*p)) ++p; + if (*p == '\0') + return (p); + + if (*p != '.') return (0); + ++p; + } + + if (strcmp(p, "HEADER") == 0 || + strcmp(p, "HEADER.FIELDS") == 0 || + strcmp(p, "HEADER.FIELDS.NOT") == 0 || + strcmp(p, "TEXT") == 0) + return (p); + + if (strcmp(p, "MIME") == 0 && has_mime) return (p); + return (0); +} + +/* Header list looks like atoms to me */ + +static struct fetchinfo *alloc_headerlist(int oneonly) +{ +struct fetchinfo *list, **listtail, *p; +struct imaptoken *tok; + + list=0; + listtail= &list; + + while ((tok=currenttoken())->tokentype == IT_ATOM || + tok->tokentype == IT_QUOTED_STRING || + tok->tokentype == IT_NUMBER) + { + *listtail=p=(struct fetchinfo *)malloc(sizeof(*list)); + if (!p) write_error_exit(0); + p->next=0; + p->name=my_strdup(tok->tokenbuf); + p->bodysublist=0; + p->bodysection=0; + listtail= &p->next; + if (oneonly) + break; + nexttoken_nouc(); + } + return (list); +} + +void fetchinfo_free(struct fetchinfo *p) +{ +struct fetchinfo *q; + + while (p) + { + if (p->bodysublist) fetchinfo_free(p->bodysublist); + q=p->next; + if (p->name) free(p->name); + if (p->bodysection) free(p->bodysection); + free(p); + p=q; + } +} -- cgit v1.2.3