xref: /netbsd-src/external/ibm-public/postfix/dist/src/global/mail_command_client.c (revision 67b9b338a7386232ac596b5fd0cd5a9cc8a03c71)
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