1 /* $NetBSD: fold_addr.c,v 1.2 2017/02/14 01:16:45 christos Exp $ */
2
3 /*++
4 /* NAME
5 /* fold_addr 3
6 /* SUMMARY
7 /* address case folding
8 /* SYNOPSIS
9 /* #include <fold_addr.h>
10 /*
11 /* char *fold_addr(result, addr, flags)
12 /* VSTRING *result;
13 /* const char *addr;
14 /* int flags;
15 /* DESCRIPTION
16 /* fold_addr() case folds an address according to the options
17 /* specified with \fIflags\fR. The result value is the output
18 /* address.
19 /*
20 /* Arguments
21 /* .IP result
22 /* Result buffer with the output address. Note: casefolding
23 /* may change the string length.
24 /* .IP addr
25 /* Null-terminated read-only string with the input address.
26 /* .IP flags
27 /* Zero or the bit-wise OR of:
28 /* .RS
29 /* .IP FOLD_ADDR_USER
30 /* Case fold the address local part.
31 /* .IP FOLD_ADDR_HOST
32 /* Case fold the address domain part.
33 /* .IP FOLD_ADDR_ALL
34 /* Alias for (FOLD_ADDR_USER | FOLD_ADDR_HOST).
35 /* .RE
36 /* SEE ALSO
37 /* msg(3) diagnostics interface
38 /* casefold(3) casefold text
39 /* DIAGNOSTICS
40 /* Fatal errors: memory allocation problem.
41 /* LICENSE
42 /* .ad
43 /* .fi
44 /* The Secure Mailer license must be distributed with this software.
45 /* AUTHOR(S)
46 /* Wietse Venema
47 /* IBM T.J. Watson Research
48 /* P.O. Box 704
49 /* Yorktown Heights, NY 10598, USA
50 /*--*/
51
52 /* System library. */
53
54 #include <sys_defs.h>
55 #include <string.h>
56
57 /* Utility library. */
58
59 #include <stringops.h>
60
61 /* Global library. */
62
63 #include <fold_addr.h>
64
65 #define STR(x) vstring_str(x)
66
67 /* fold_addr - case fold mail address */
68
fold_addr(VSTRING * result,const char * addr,int flags)69 char *fold_addr(VSTRING *result, const char *addr, int flags)
70 {
71 char *cp;
72
73 /*
74 * Fold the address as appropriate.
75 */
76 switch (flags & FOLD_ADDR_ALL) {
77 case FOLD_ADDR_HOST:
78 if ((cp = strrchr(addr, '@')) != 0) {
79 cp += 1;
80 vstring_strncpy(result, addr, cp - addr);
81 casefold_append(result, cp);
82 break;
83 }
84 /* FALLTHROUGH */
85 case 0:
86 vstring_strcpy(result, addr);
87 break;
88 case FOLD_ADDR_USER:
89 if ((cp = strrchr(addr, '@')) != 0) {
90 casefold_len(result, addr, cp - addr);
91 vstring_strcat(result, cp);
92 break;
93 }
94 /* FALLTHROUGH */
95 case FOLD_ADDR_USER | FOLD_ADDR_HOST:
96 casefold(result, addr);
97 break;
98 }
99 return (STR(result));
100 }
101
102 #ifdef TEST
103 #include <stdlib.h>
104 #include <vstream.h>
105 #include <vstring_vstream.h>
106 #include <msg_vstream.h>
107 #include <argv.h>
108
main(int argc,char ** argv)109 int main(int argc, char **argv)
110 {
111 VSTRING *line_buffer = vstring_alloc(1);
112 VSTRING *fold_buffer = vstring_alloc(1);
113 ARGV *cmd;
114 char **args;
115
116 msg_vstream_init(argv[0], VSTREAM_ERR);
117 util_utf8_enable = 1;
118 while (vstring_fgets_nonl(line_buffer, VSTREAM_IN)) {
119 vstream_printf("> %s\n", STR(line_buffer));
120 cmd = argv_split(STR(line_buffer), CHARS_SPACE);
121 if (cmd->argc == 0 || cmd->argv[0][0] == '#') {
122 argv_free(cmd);
123 continue;
124 }
125 args = cmd->argv;
126
127 /*
128 * Fold the host.
129 */
130 if (strcmp(args[0], "host") == 0 && cmd->argc == 2) {
131 vstream_printf("\"%s\" -> \"%s\"\n", args[1], fold_addr(fold_buffer,
132 args[1], FOLD_ADDR_HOST));
133 }
134
135 /*
136 * Fold the user.
137 */
138 else if (strcmp(args[0], "user") == 0 && cmd->argc == 2) {
139 vstream_printf("\"%s\" -> \"%s\"\n", args[1], fold_addr(fold_buffer,
140 args[1], FOLD_ADDR_USER));
141 }
142
143 /*
144 * Fold user and host.
145 */
146 else if (strcmp(args[0], "all") == 0 && cmd->argc == 2) {
147 vstream_printf("\"%s\" -> \"%s\"\n", args[1], fold_addr(fold_buffer,
148 args[1], FOLD_ADDR_ALL));
149 }
150
151 /*
152 * Fold none.
153 */
154 else if (strcmp(args[0], "none") == 0 && cmd->argc == 2) {
155 vstream_printf("\"%s\" -> \"%s\"\n", args[1], fold_addr(fold_buffer,
156 args[1], 0));
157 }
158
159 /*
160 * Usage.
161 */
162 else {
163 vstream_printf("Usage: %s host <addr> | user <addr> | all <addr>\n",
164 argv[0]);
165 }
166 vstream_fflush(VSTREAM_OUT);
167 argv_free(cmd);
168 }
169 vstring_free(line_buffer);
170 vstring_free(fold_buffer);
171 exit(0);
172 }
173
174 #endif /* TEST */
175