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 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