c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#ifndef RFC822_PARSER_H
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#define RFC822_PARSER_H
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainenstruct rfc822_parser_context {
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen const unsigned char *data, *end;
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen string_t *last_comment;
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen};
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen
5bbce06405dd5fc0d67411e48856953785f109f5Timo Sirainen#define IS_ATEXT(c) \
5bbce06405dd5fc0d67411e48856953785f109f5Timo Sirainen (rfc822_atext_chars[(int)(unsigned char)(c)] != 0)
5bbce06405dd5fc0d67411e48856953785f109f5Timo Sirainen#define IS_ATEXT_NON_TSPECIAL(c) \
5bbce06405dd5fc0d67411e48856953785f109f5Timo Sirainen ((rfc822_atext_chars[(int)(unsigned char)(c)] & 3) != 0)
5bbce06405dd5fc0d67411e48856953785f109f5Timo Sirainenextern unsigned char rfc822_atext_chars[256];
5bbce06405dd5fc0d67411e48856953785f109f5Timo Sirainen
75a32ef74f52fd17728cf25ccc6309d35ae65dc2Timo Sirainen/* Parse given data using RFC 822 token parser. */
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainenvoid rfc822_parser_init(struct rfc822_parser_context *ctx,
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen const unsigned char *data, size_t size,
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen string_t *last_comment) ATTR_NULL(4);
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen
75a32ef74f52fd17728cf25ccc6309d35ae65dc2Timo Sirainen/* The functions below return 1 = more data available, 0 = no more data
75a32ef74f52fd17728cf25ccc6309d35ae65dc2Timo Sirainen available (but a value might have been returned now), -1 = invalid input.
75a32ef74f52fd17728cf25ccc6309d35ae65dc2Timo Sirainen
75a32ef74f52fd17728cf25ccc6309d35ae65dc2Timo Sirainen LWSP is automatically skipped after value, but not before it. So typically
75a32ef74f52fd17728cf25ccc6309d35ae65dc2Timo Sirainen you begin with skipping LWSP and then start using the parse functions. */
75a32ef74f52fd17728cf25ccc6309d35ae65dc2Timo Sirainen
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen/* Parse comment. Assumes parser's data points to '(' */
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainenint rfc822_skip_comment(struct rfc822_parser_context *ctx);
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen/* Skip LWSP if there is any */
4e8d6d03c2ff85448df79b181a2ea850fb5d4199Timo Sirainenint ATTR_NOWARN_UNUSED_RESULT
4e8d6d03c2ff85448df79b181a2ea850fb5d4199Timo Sirainenrfc822_skip_lwsp(struct rfc822_parser_context *ctx);
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen/* Stop at next non-atext char */
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainenint rfc822_parse_atom(struct rfc822_parser_context *ctx, string_t *str);
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen/* Like parse_atom() but don't stop at '.' */
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainenint rfc822_parse_dot_atom(struct rfc822_parser_context *ctx, string_t *str);
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen/* Like parse_dot_atom() but stops for '/', '?' and '='.
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen Also it doesn't allow LWSP around '.' chars. */
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainenint rfc822_parse_mime_token(struct rfc822_parser_context *ctx, string_t *str);
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen/* "quoted string" */
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainenint rfc822_parse_quoted_string(struct rfc822_parser_context *ctx,
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen string_t *str);
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen/* atom or quoted-string */
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainenint rfc822_parse_phrase(struct rfc822_parser_context *ctx, string_t *str);
2de709376eddc50ec5fa470358bb57cf0a87bb1fTimo Sirainen/* dot-atom / domain-literal */
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainenint rfc822_parse_domain(struct rfc822_parser_context *ctx, string_t *str);
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen/* Parse Content-Type header's type/subtype. */
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainenint rfc822_parse_content_type(struct rfc822_parser_context *ctx, string_t *str);
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen/* For Content-Type style parameter parsing. Expect ";" key "=" value.
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen value is unescaped if needed. The returned strings are allocated from data
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen stack. Returns 1 = key/value set, 0 = no more data, -1 = invalid input. */
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainenint rfc822_parse_content_param(struct rfc822_parser_context *ctx,
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen const char **key_r, const char **value_r);
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen
a24665de9d5c773115a5918e60ed587aafe67d5cTimo Sirainen#endif