Sync usage with man page.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / global / mail_addr_crunch.c
blob6ea11c136ff95e594108249a4a78065e8ff2bec8
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* mail_addr_crunch 3
6 /* SUMMARY
7 /* parse and canonicalize addresses, apply address extension
8 /* SYNOPSIS
9 /* #include <mail_addr_crunch.h>
11 /* ARGV *mail_addr_crunch(string, extension)
12 /* const char *string;
13 /* const char *extension;
14 /* DESCRIPTION
15 /* mail_addr_crunch() parses a string with zero or more addresses,
16 /* rewrites each address to canonical form, and optionally applies
17 /* an address extension to each resulting address. Input and result
18 /* are in external (quoted) format. The caller is expected to pass
19 /* the result to argv_free().
21 /* Arguments:
22 /* .IP string
23 /* A string with zero or more addresses in RFC 822 (external) format.
24 /* .IP extension
25 /* A null pointer, or an address extension (including the recipient
26 /* address delimiter) that is propagated to all result addresses.
27 /* DIAGNOSTICS
28 /* Fatal error: out of memory.
29 /* SEE ALSO
30 /* tok822_parse(3), address parser
31 /* canon_addr(3), address canonicalization
32 /* LICENSE
33 /* .ad
34 /* .fi
35 /* The Secure Mailer license must be distributed with this software.
36 /* AUTHOR(S)
37 /* Wietse Venema
38 /* IBM T.J. Watson Research
39 /* P.O. Box 704
40 /* Yorktown Heights, NY 10598, USA
41 /*--*/
43 /* System library. */
45 #include <sys_defs.h>
46 #include <string.h>
48 /* Utility library. */
50 #include <mymalloc.h>
51 #include <argv.h>
52 #include <vstring.h>
54 /* Global library. */
56 #include <tok822.h>
57 #include <canon_addr.h>
58 #include <mail_addr_crunch.h>
60 /* mail_addr_crunch - break string into addresses, optionally add extension */
62 ARGV *mail_addr_crunch(const char *string, const char *extension)
64 VSTRING *extern_addr = vstring_alloc(100);
65 VSTRING *canon_addr = vstring_alloc(100);
66 ARGV *argv = argv_alloc(1);
67 TOK822 *tree;
68 TOK822 **addr_list;
69 TOK822 **tpp;
70 char *ratsign;
71 ssize_t extlen;
73 if (extension)
74 extlen = strlen(extension);
76 #define STR(x) vstring_str(x)
79 * Parse the string, rewrite each address to canonical form, and convert
80 * the result to external (quoted) form. Optionally apply the extension
81 * to each address found.
83 * XXX Workaround for the null address. This works for envelopes but
84 * produces ugly results for message headers.
86 if (*string == 0 || strcmp(string, "<>") == 0)
87 string = "\"\"";
88 tree = tok822_parse(string);
89 addr_list = tok822_grep(tree, TOK822_ADDR);
90 for (tpp = addr_list; *tpp; tpp++) {
91 tok822_externalize(extern_addr, tpp[0]->head, TOK822_STR_DEFL);
92 canon_addr_external(canon_addr, STR(extern_addr));
93 if (extension) {
94 VSTRING_SPACE(canon_addr, extlen + 1);
95 if ((ratsign = strrchr(STR(canon_addr), '@')) == 0) {
96 vstring_strcat(canon_addr, extension);
97 } else {
98 memmove(ratsign + extlen, ratsign, strlen(ratsign) + 1);
99 memcpy(ratsign, extension, extlen);
100 VSTRING_SKIP(canon_addr);
103 argv_add(argv, STR(canon_addr), ARGV_END);
105 argv_terminate(argv);
106 myfree((char *) addr_list);
107 tok822_free_tree(tree);
108 vstring_free(canon_addr);
109 vstring_free(extern_addr);
110 return (argv);
113 #ifdef TEST
116 * Stand-alone test program, sort of interactive.
118 #include <stdlib.h>
119 #include <unistd.h>
120 #include <msg.h>
121 #include <vstream.h>
122 #include <vstring_vstream.h>
123 #include <mail_conf.h>
124 #include <mail_params.h>
126 int main(int unused_argc, char **unused_argv)
128 VSTRING *extension = vstring_alloc(1);
129 VSTRING *buf = vstring_alloc(1);
130 ARGV *argv;
131 char **cpp;
133 mail_conf_read();
134 if (chdir(var_queue_dir) < 0)
135 msg_fatal("chdir %s: %m", var_queue_dir);
137 vstream_printf("extension: (CR for none): ");
138 vstream_fflush(VSTREAM_OUT);
139 if (vstring_get_nonl(extension, VSTREAM_IN) == VSTREAM_EOF)
140 exit(0);
142 vstream_printf("print strings to be translated, one per line\n");
143 vstream_fflush(VSTREAM_OUT);
144 while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
145 argv = mail_addr_crunch(STR(buf), VSTRING_LEN(extension) ? STR(extension) : 0);
146 for (cpp = argv->argv; *cpp; cpp++)
147 vstream_printf(" %s\n", *cpp);
148 vstream_fflush(VSTREAM_OUT);
150 return (0);
153 #endif