Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / global / is_header.c
blob7b4b7e8fdf019d341d352b1d698c86bffbb0d89b
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* is_header 3
6 /* SUMMARY
7 /* message header classification
8 /* SYNOPSIS
9 /* #include <is_header.h>
11 /* ssize_t is_header(string)
12 /* const char *string;
14 /* ssize_t is_header_buf(string, len)
15 /* const char *string;
16 /* ssize_t len;
17 /* DESCRIPTION
18 /* is_header() examines the given string and returns non-zero (true)
19 /* when it begins with a mail header name + optional space + colon.
20 /* The result is the length of the mail header name.
22 /* is_header_buf() is a more elaborate interface for use with strings
23 /* that may not be null terminated.
24 /* STANDARDS
25 /* RFC 822 (ARPA Internet Text Messages)
26 /* LICENSE
27 /* .ad
28 /* .fi
29 /* The Secure Mailer license must be distributed with this software.
30 /* AUTHOR(S)
31 /* Wietse Venema
32 /* IBM T.J. Watson Research
33 /* P.O. Box 704
34 /* Yorktown Heights, NY 10598, USA
35 /*--*/
37 /* System library. */
39 #include "sys_defs.h"
40 #include <ctype.h>
42 /* Global library. */
44 #include "is_header.h"
46 /* is_header_buf - determine if this can be a header line */
48 ssize_t is_header_buf(const char *str, ssize_t str_len)
50 const unsigned char *cp;
51 int state;
52 int c;
53 ssize_t len;
55 #define INIT 0
56 #define IN_CHAR 1
57 #define IN_CHAR_SPACE 2
58 #define CU_CHAR_PTR(x) ((const unsigned char *) (x))
61 * XXX RFC 2822 Section 4.5, Obsolete header fields: whitespace may
62 * appear between header label and ":" (see: RFC 822, Section 3.4.2.).
64 * XXX Don't run off the end in case some non-standard iscntrl()
65 * implementation considers null a non-control character...
67 for (len = 0, state = INIT, cp = CU_CHAR_PTR(str); /* see below */; cp++) {
68 if (str_len != IS_HEADER_NULL_TERMINATED && str_len-- <= 0)
69 return (0);
70 switch (c = *cp) {
71 default:
72 if (c == 0 || !ISASCII(c) || ISCNTRL(c))
73 return (0);
74 if (state == INIT)
75 state = IN_CHAR;
76 if (state == IN_CHAR) {
77 len++;
78 continue;
80 return (0);
81 case ' ':
82 case '\t':
83 if (state == IN_CHAR)
84 state = IN_CHAR_SPACE;
85 if (state == IN_CHAR_SPACE)
86 continue;
87 return (0);
88 case ':':
89 return ((state == IN_CHAR || state == IN_CHAR_SPACE) ? len : 0);
92 /* Redundant return for future proofing. */
93 return (0);