7 /* address verification client interface
9 /* #include <verify_clnt.h>
11 /* int verify_clnt_query(addr, status, why)
16 /* int verify_clnt_update(addr, status, why)
21 /* verify_clnt_query() requests information about the given address.
22 /* The result value is one of the valid status values (see
23 /* status description below).
24 /* In all cases the \fBwhy\fR argument provides additional
27 /* verify_clnt_update() requests that the status of the specified
28 /* address be updated. The result status is DEL_REQ_RCPT_STAT_OK upon
29 /* success, DEL_REQ_RCPT_STAT_DEFER upon failure.
33 /* The email address in question.
35 /* One of the following status codes:
37 /* .IP DEL_REQ_RCPT_STAT_OK
38 /* The mail system did not detect any problems.
39 /* .IP DEL_REQ_RCPT_STAT_DEFER
40 /* The status of the address is indeterminate.
41 /* .IP DEL_REQ_RCPT_STAT_BOUNCE
42 /* The address is permanently undeliverable.
45 /* textual description of the status.
47 /* These functions return VRFY_STAT_OK in case of success,
48 /* VRFY_STAT_BAD in case of a malformed request, and
49 /* VRFY_STAT_FAIL when the operation failed.
51 /* verify(8) Postfix address verification server
55 /* The Secure Mailer license must be distributed with this software.
58 /* IBM T.J. Watson Research
60 /* Yorktown Heights, NY 10598, USA
69 /* Utility library. */
78 #include <mail_params.h>
79 #include <mail_proto.h>
80 #include <clnt_stream.h>
81 #include <verify_clnt.h>
83 CLNT_STREAM
*vrfy_clnt
;
85 /* verify_clnt_init - initialize */
87 static void verify_clnt_init(void)
90 msg_panic("verify_clnt_init: multiple initialization");
91 vrfy_clnt
= clnt_stream_create(MAIL_CLASS_PRIVATE
, var_verify_service
,
92 var_ipc_idle_limit
, var_ipc_ttl_limit
);
95 /* verify_clnt_query - request address verification status */
97 int verify_clnt_query(const char *addr
, int *addr_status
, VSTRING
*why
)
104 * Do client-server plumbing.
110 * Request status for this address.
113 stream
= clnt_stream_access(vrfy_clnt
);
116 if (attr_print(stream
, ATTR_FLAG_NONE
,
117 ATTR_TYPE_STR
, MAIL_ATTR_REQ
, VRFY_REQ_QUERY
,
118 ATTR_TYPE_STR
, MAIL_ATTR_ADDR
, addr
,
120 || vstream_fflush(stream
)
121 || attr_scan(stream
, ATTR_FLAG_MISSING
,
122 ATTR_TYPE_INT
, MAIL_ATTR_STATUS
, &request_status
,
123 ATTR_TYPE_INT
, MAIL_ATTR_ADDR_STATUS
, addr_status
,
124 ATTR_TYPE_STR
, MAIL_ATTR_WHY
, why
,
125 ATTR_TYPE_END
) != 3) {
126 if (msg_verbose
|| count
> 1 || (errno
&& errno
!= EPIPE
&& errno
!= ENOENT
))
127 msg_warn("problem talking to service %s: %m",
133 clnt_stream_recover(vrfy_clnt
);
135 return (request_status
);
138 /* verify_clnt_update - request address status update */
140 int verify_clnt_update(const char *addr
, int addr_status
, const char *why
)
146 * Do client-server plumbing.
152 * Send status for this address. Supply a default status if the address
153 * verification service is unavailable.
156 stream
= clnt_stream_access(vrfy_clnt
);
158 if (attr_print(stream
, ATTR_FLAG_NONE
,
159 ATTR_TYPE_STR
, MAIL_ATTR_REQ
, VRFY_REQ_UPDATE
,
160 ATTR_TYPE_STR
, MAIL_ATTR_ADDR
, addr
,
161 ATTR_TYPE_INT
, MAIL_ATTR_ADDR_STATUS
, addr_status
,
162 ATTR_TYPE_STR
, MAIL_ATTR_WHY
, why
,
164 || attr_scan(stream
, ATTR_FLAG_MISSING
,
165 ATTR_TYPE_INT
, MAIL_ATTR_STATUS
, &request_status
,
166 ATTR_TYPE_END
) != 1) {
167 if (msg_verbose
|| (errno
!= EPIPE
&& errno
!= ENOENT
))
168 msg_warn("problem talking to service %s: %m",
174 clnt_stream_recover(vrfy_clnt
);
176 return (request_status
);
180 * Proof-of-concept test client program.
189 #include <msg_vstream.h>
190 #include <stringops.h>
191 #include <vstring_vstream.h>
192 #include <mail_conf.h>
194 #define STR(x) vstring_str(x)
196 static NORETURN
usage(char *myname
)
198 msg_fatal("usage: %s [-v]", myname
);
201 static void query(char *query
, VSTRING
*buf
)
205 switch (verify_clnt_query(query
, &status
, buf
)) {
207 vstream_printf("%-10s %d\n", "status", status
);
208 vstream_printf("%-10s %s\n", "text", STR(buf
));
209 vstream_fflush(VSTREAM_OUT
);
212 msg_warn("bad request format");
215 msg_warn("request failed");
220 static void update(char *query
)
226 if ((addr
= mystrtok(&cp
, " \t\r\n")) == 0
227 || (status_text
= mystrtok(&cp
, " \t\r\n")) == 0) {
228 msg_warn("bad request format");
231 while (*cp
&& ISSPACE(*cp
))
234 msg_warn("bad request format");
237 switch (verify_clnt_update(query
, atoi(status_text
), cp
)) {
239 vstream_printf("OK\n");
240 vstream_fflush(VSTREAM_OUT
);
243 msg_warn("bad request format");
246 msg_warn("request failed");
251 int main(int argc
, char **argv
)
253 VSTRING
*buffer
= vstring_alloc(1);
258 signal(SIGPIPE
, SIG_IGN
);
260 msg_vstream_init(argv
[0], VSTREAM_ERR
);
263 msg_info("using config files in %s", var_config_dir
);
264 if (chdir(var_queue_dir
) < 0)
265 msg_fatal("chdir %s: %m", var_queue_dir
);
267 while ((ch
= GETOPT(argc
, argv
, "v")) > 0) {
276 if (argc
- optind
> 1)
279 while (vstring_fgets_nonl(buffer
, VSTREAM_IN
)) {
281 if ((command
= mystrtok(&cp
, " \t\r\n")) == 0)
283 if (strcmp(command
, "query") == 0)
285 else if (strcmp(command
, "update") == 0)
288 msg_warn("unrecognized command: %s", command
);
290 vstring_free(buffer
);