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