7 /* tokenize alias/include/.forward entries and deliver
11 /* int deliver_token(state, usr_attr, addr)
13 /* USER_ATTR usr_attr;
16 /* int deliver_token_string(state, usr_attr, string, addr_count)
18 /* USER_ATTR usr_attr;
22 /* int deliver_token_stream(state, usr_attr, fp, addr_count)
24 /* USER_ATTR usr_attr;
28 /* This module delivers to addresses listed in an alias database
29 /* entry, in an include file, or in a .forward file.
31 /* deliver_token() delivers to the address in the given token:
32 /* an absolute /path/name, a ~/path/name relative to the recipient's
33 /* home directory, an :include:/path/name request, an external
34 /* "|command", or a mail address.
36 /* deliver_token_string() delivers to all addresses listed in
37 /* the specified string.
39 /* deliver_token_stream() delivers to all addresses listed in
40 /* the specified stream. Input records > \fIline_length_limit\fR
41 /* are broken up into multiple records, to prevent the mail
42 /* system from using unreasonable amounts of memory.
46 /* The attributes that specify the message, recipient and more.
47 /* Attributes describing alias, include or forward expansion.
48 /* A table with the results from expanding aliases or lists.
49 /* A table with delivered-to: addresses taken from the message.
51 /* Attributes describing user rights and environment.
53 /* A parsed address from an include file, alias file or .forward file.
55 /* A null-terminated string.
59 /* Null pointer, or the address of a counter that is incremented
60 /* by the number of destinations found by the tokenizer.
62 /* Fatal errors: out of memory. The result is non-zero when the
63 /* operation should be tried again. Warnings: malformed address.
65 /* list_token(3) tokenize list
69 /* The Secure Mailer license must be distributed with this software.
72 /* IBM T.J. Watson Research
74 /* Yorktown Heights, NY 10598, USA
83 #ifdef STRCASECMP_IN_STRINGS_H
87 /* Utility library. */
93 #include <readlline.h>
95 #include <vstring_vstream.h>
96 #include <stringops.h>
101 #include <mail_params.h>
105 /* Application-specific. */
109 /* deliver_token_home - expand ~token */
111 static int deliver_token_home(LOCAL_STATE state
, USER_ATTR usr_attr
, char *addr
)
116 if (addr
[1] != '/') { /* disallow ~user */
117 msg_warn("bad home directory syntax for: %s", addr
);
118 dsb_simple(state
.msg_attr
.why
, "5.3.5",
119 "mail system configuration error");
120 status
= bounce_append(BOUNCE_FLAGS(state
.request
),
121 BOUNCE_ATTR(state
.msg_attr
));
122 } else if (usr_attr
.home
== 0) { /* require user context */
123 msg_warn("unknown home directory for: %s", addr
);
124 dsb_simple(state
.msg_attr
.why
, "5.3.5",
125 "mail system configuration error");
126 status
= bounce_append(BOUNCE_FLAGS(state
.request
),
127 BOUNCE_ATTR(state
.msg_attr
));
128 } else if (usr_attr
.home
[0] == '/' && usr_attr
.home
[1] == 0) {
129 status
= deliver_file(state
, usr_attr
, addr
+ 1);
130 } else { /* expand ~ to home */
131 full_path
= concatenate(usr_attr
.home
, addr
+ 1, (char *) 0);
132 status
= deliver_file(state
, usr_attr
, full_path
);
138 /* deliver_token - deliver to expansion of include file or alias */
140 int deliver_token(LOCAL_STATE state
, USER_ATTR usr_attr
, TOK822
*addr
)
142 VSTRING
*addr_buf
= vstring_alloc(100);
143 static char include
[] = ":include:";
147 tok822_internalize(addr_buf
, addr
->head
, TOK822_STR_DEFL
);
149 msg_info("deliver_token: %s", STR(addr_buf
));
151 if (*STR(addr_buf
) == '/') {
152 status
= deliver_file(state
, usr_attr
, STR(addr_buf
));
153 } else if (*STR(addr_buf
) == '~') {
154 status
= deliver_token_home(state
, usr_attr
, STR(addr_buf
));
155 } else if (*STR(addr_buf
) == '|') {
156 if ((local_cmd_deliver_mask
& state
.msg_attr
.exp_type
) == 0) {
157 dsb_simple(state
.msg_attr
.why
, "5.7.1",
158 "mail to command is restricted");
159 status
= bounce_append(BOUNCE_FLAGS(state
.request
),
160 BOUNCE_ATTR(state
.msg_attr
));
162 status
= deliver_command(state
, usr_attr
, STR(addr_buf
) + 1);
163 } else if (strncasecmp(STR(addr_buf
), include
, sizeof(include
) - 1) == 0) {
164 path
= STR(addr_buf
) + sizeof(include
) - 1;
165 status
= deliver_include(state
, usr_attr
, path
);
167 status
= deliver_resolve_tree(state
, usr_attr
, addr
);
169 vstring_free(addr_buf
);
174 /* deliver_token_string - tokenize string and deliver */
176 int deliver_token_string(LOCAL_STATE state
, USER_ATTR usr_attr
,
177 char *string
, int *addr_count
)
184 msg_info("deliver_token_string: %s", string
);
186 tree
= tok822_parse(string
);
187 for (addr
= tree
; addr
!= 0; addr
= addr
->next
) {
188 if (addr
->type
== TOK822_ADDR
) {
191 status
|= deliver_token(state
, usr_attr
, addr
);
194 tok822_free_tree(tree
);
198 /* deliver_token_stream - tokenize stream and deliver */
200 int deliver_token_stream(LOCAL_STATE state
, USER_ATTR usr_attr
,
201 VSTREAM
*fp
, int *addr_count
)
203 VSTRING
*buf
= vstring_alloc(100);
207 msg_info("deliver_token_stream: %s", VSTREAM_PATH(fp
));
209 while (vstring_fgets_bound(buf
, fp
, var_line_limit
)) {
210 if (*STR(buf
) != '#') {
211 status
= deliver_token_string(state
, usr_attr
, STR(buf
), addr_count
);
216 if (vstream_ferror(fp
)) {
217 dsb_simple(state
.msg_attr
.why
, "4.3.0",
218 "error reading forwarding file: %m");
219 status
= defer_append(BOUNCE_FLAGS(state
.request
),
220 BOUNCE_ATTR(state
.msg_attr
));