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