Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / global / xtext.c
blobbb6724419d7767813c6f1c4f1d38635f18ce4ac9
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* xtext 3
6 /* SUMMARY
7 /* quote/unquote text, xtext style.
8 /* SYNOPSIS
9 /* #include <xtext.h>
11 /* VSTRING *xtext_quote(quoted, unquoted, special)
12 /* VSTRING *quoted;
13 /* const char *unquoted;
14 /* const char *special;
16 /* VSTRING *xtext_quote_append(unquoted, quoted, special)
17 /* VSTRING *unquoted;
18 /* const char *quoted;
19 /* const char *special;
21 /* VSTRING *xtext_unquote(unquoted, quoted)
22 /* VSTRING *unquoted;
23 /* const char *quoted;
24 /* DESCRIPTION
25 /* xtext_quote() takes a null-terminated string and replaces characters
26 /* +, <33(10) and >126(10), as well as characters specified with "special"
27 /* by +XX, XX being the two-digit uppercase hexadecimal equivalent.
29 /* xtext_quote_append() is like xtext_quote(), but appends the conversion
30 /* result to the result buffer.
32 /* xtext_unquote() performs the opposite transformation. This function
33 /* understands lowercase, uppercase, and mixed case +XX sequences. The
34 /* result value is the unquoted argument in case of success, a null pointer
35 /* otherwise.
36 /* BUGS
37 /* This module cannot process null characters in data.
38 /* LICENSE
39 /* .ad
40 /* .fi
41 /* The Secure Mailer license must be distributed with this software.
42 /* AUTHOR(S)
43 /* Wietse Venema
44 /* IBM T.J. Watson Research
45 /* P.O. Box 704
46 /* Yorktown Heights, NY 10598, USA
47 /*--*/
49 /* System library. */
51 #include <sys_defs.h>
52 #include <string.h>
53 #include <ctype.h>
55 /* Utility library. */
57 #include "msg.h"
58 #include "vstring.h"
59 #include "xtext.h"
61 /* Application-specific. */
63 #define STR(x) vstring_str(x)
64 #define LEN(x) VSTRING_LEN(x)
66 /* xtext_quote_append - append unquoted data to quoted data */
68 VSTRING *xtext_quote_append(VSTRING *quoted, const char *unquoted,
69 const char *special)
71 const char *cp;
72 int ch;
74 for (cp = unquoted; (ch = *(unsigned const char *) cp) != 0; cp++) {
75 if (ch != '+' && ch > 32 && ch < 127
76 && (*special == 0 || strchr(special, ch) == 0)) {
77 VSTRING_ADDCH(quoted, ch);
78 } else {
79 vstring_sprintf_append(quoted, "+%02X", ch);
82 VSTRING_TERMINATE(quoted);
83 return (quoted);
86 /* xtext_quote - unquoted data to quoted */
88 VSTRING *xtext_quote(VSTRING *quoted, const char *unquoted, const char *special)
90 VSTRING_RESET(quoted);
91 xtext_quote_append(quoted, unquoted, special);
92 return (quoted);
95 /* xtext_unquote - quoted data to unquoted */
97 VSTRING *xtext_unquote(VSTRING *unquoted, const char *quoted)
99 const char *cp;
100 int ch;
102 VSTRING_RESET(unquoted);
103 for (cp = quoted; (ch = *cp) != 0; cp++) {
104 if (ch == '+') {
105 if (ISDIGIT(cp[1]))
106 ch = (cp[1] - '0') << 4;
107 else if (cp[1] >= 'a' && cp[1] <= 'f')
108 ch = (cp[1] - 'a' + 10) << 4;
109 else if (cp[1] >= 'A' && cp[1] <= 'F')
110 ch = (cp[1] - 'A' + 10) << 4;
111 else
112 return (0);
113 if (ISDIGIT(cp[2]))
114 ch |= (cp[2] - '0');
115 else if (cp[2] >= 'a' && cp[2] <= 'f')
116 ch |= (cp[2] - 'a' + 10);
117 else if (cp[2] >= 'A' && cp[2] <= 'F')
118 ch |= (cp[2] - 'A' + 10);
119 else
120 return (0);
121 cp += 2;
123 VSTRING_ADDCH(unquoted, ch);
125 VSTRING_TERMINATE(unquoted);
126 return (unquoted);
129 #ifdef TEST
132 * Proof-of-concept test program: convert to quoted and back.
134 #include <vstream.h>
136 #define BUFLEN 1024
138 static ssize_t read_buf(VSTREAM *fp, VSTRING *buf)
140 ssize_t len;
142 VSTRING_RESET(buf);
143 len = vstream_fread(fp, STR(buf), vstring_avail(buf));
144 VSTRING_AT_OFFSET(buf, len); /* XXX */
145 VSTRING_TERMINATE(buf);
146 return (len);
149 int main(int unused_argc, char **unused_argv)
151 VSTRING *unquoted = vstring_alloc(BUFLEN);
152 VSTRING *quoted = vstring_alloc(100);
153 ssize_t len;
155 while ((len = read_buf(VSTREAM_IN, unquoted)) > 0) {
156 xtext_quote(quoted, STR(unquoted), "+=");
157 if (xtext_unquote(unquoted, STR(quoted)) == 0)
158 msg_fatal("bad input: %.100s", STR(quoted));
159 if (LEN(unquoted) != len)
160 msg_fatal("len %ld != unquoted len %ld",
161 (long) len, (long) LEN(unquoted));
162 if (vstream_fwrite(VSTREAM_OUT, STR(unquoted), LEN(unquoted)) != LEN(unquoted))
163 msg_fatal("write error: %m");
165 vstream_fflush(VSTREAM_OUT);
166 vstring_free(unquoted);
167 vstring_free(quoted);
168 return (0);
171 #endif