1 /* $NetBSD: mail_command_client.c,v 1.4 2022/10/08 16:12:45 christos Exp $ */
2
3 /*++
4 /* NAME
5 /* mail_command_client 3
6 /* SUMMARY
7 /* single-command client
8 /* SYNOPSIS
9 /* #include <mail_proto.h>
10 /*
11 /* int mail_command_client(class, name, proto, type, attr, ...)
12 /* const char *class;
13 /* const char *name;
14 /* const char *proto;
15 /* int type;
16 /* const char *attr;
17 /* DESCRIPTION
18 /* This module implements a client interface for single-command
19 /* clients: a client that sends a single command and expects
20 /* a single completion status code.
21 /*
22 /* Arguments:
23 /* .IP class
24 /* Service type: MAIL_CLASS_PUBLIC or MAIL_CLASS_PRIVATE
25 /* .IP name
26 /* Service name (master.cf).
27 /* .IP proto
28 /* The expected protocol name in the server announcement.
29 /* .IP "type, attr, ..."
30 /* Attribute information as defined in attr_print(3).
31 /* DIAGNOSTICS
32 /* The result is -1 if the request could not be sent, otherwise
33 /* the result is the status reported by the server.
34 /* Warnings: problems connecting to the requested service.
35 /* Fatal: out of memory.
36 /* SEE ALSO
37 /* attr_print(3), send attributes over byte stream
38 /* mail_command_server(3), server interface
39 /* mail_proto(3h), client-server protocol
40 /* LICENSE
41 /* .ad
42 /* .fi
43 /* The Secure Mailer license must be distributed with this software.
44 /* AUTHOR(S)
45 /* Wietse Venema
46 /* IBM T.J. Watson Research
47 /* P.O. Box 704
48 /* Yorktown Heights, NY 10598, USA
49 /*
50 /* Wietse Venema
51 /* Google, Inc.
52 /* 111 8th Avenue
53 /* New York, NY 10011, USA
54 /*--*/
55
56 /* System library. */
57
58 #include <sys_defs.h>
59 #include <stdlib.h> /* 44BSD stdarg.h uses abort() */
60 #include <stdarg.h>
61
62 /* Utility library. */
63
64 #include <vstream.h>
65 #include <msg.h>
66
67 /* Global library. */
68
69 #include <mail_proto.h>
70
71 /* mail_command_client - single-command transaction with completion status */
72
mail_command_client(const char * class,const char * name,const char * proto,...)73 int mail_command_client(const char *class, const char *name,
74 const char *proto,...)
75 {
76 va_list ap;
77 VSTREAM *stream;
78 int status;
79
80 /*
81 * Talk a little protocol with the specified service.
82 *
83 * This function is used for non-critical services where it is OK to back
84 * off after the first error. Log what communication stage failed, to
85 * facilitate trouble analysis.
86 */
87 if ((stream = mail_connect(class, name, BLOCKING)) == 0) {
88 msg_warn("connect to %s/%s: %m", class, name);
89 return (-1);
90 }
91 if (attr_scan(stream, ATTR_FLAG_STRICT,
92 RECV_ATTR_STREQ(MAIL_ATTR_PROTO, proto),
93 ATTR_TYPE_END) != 0) {
94 msg_warn("read %s: %m", VSTREAM_PATH(stream));
95 status = -1;
96 } else if (va_start(ap, proto),
97 (status = attr_vprint(stream, ATTR_FLAG_NONE, ap)),
98 va_end(ap),
99 (status != 0)) {
100 msg_warn("write %s: %m", VSTREAM_PATH(stream));
101 status = -1;
102 } else if (attr_scan(stream, ATTR_FLAG_STRICT,
103 RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
104 ATTR_TYPE_END) != 1) {
105 msg_warn("write/read %s: %m", VSTREAM_PATH(stream));
106 status = -1;
107 }
108 (void) vstream_fclose(stream);
109 return (status);
110 }
111