1 /* $NetBSD: msg_stats_scan.c,v 1.2 2017/02/14 01:16:45 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* msg_stats_scan 6 /* SUMMARY 7 /* read MSG_STATS from stream 8 /* SYNOPSIS 9 /* #include <msg_stats.h> 10 /* 11 /* int msg_stats_scan(scan_fn, stream, flags, ptr) 12 /* ATTR_SCAN_MASTER_FN scan_fn; 13 /* VSTREAM *stream; 14 /* int flags; 15 /* void *ptr; 16 /* DESCRIPTION 17 /* msg_stats_scan() reads an MSG_STATS from the named stream 18 /* using the specified attribute scan routine. msg_stats_scan() 19 /* is meant to be passed as a call-back to attr_scan(), thusly: 20 /* 21 /* ... RECV_ATTR_FUNC(msg_stats_scan, (void *) &stats), ... 22 /* DIAGNOSTICS 23 /* Fatal: out of memory. 24 /* LICENSE 25 /* .ad 26 /* .fi 27 /* The Secure Mailer license must be distributed with this software. 28 /* AUTHOR(S) 29 /* Wietse Venema 30 /* IBM T.J. Watson Research 31 /* P.O. Box 704 32 /* Yorktown Heights, NY 10598, USA 33 /*--*/ 34 35 /* System library. */ 36 37 #include <sys_defs.h> 38 39 /* Utility library. */ 40 41 #include <attr.h> 42 #include <vstring.h> 43 #include <msg.h> 44 45 /* Global library. */ 46 47 #include <mail_proto.h> 48 #include <msg_stats.h> 49 50 /* 51 * SLMs. 52 */ 53 #define STR(x) vstring_str(x) 54 #define LEN(x) VSTRING_LEN(x) 55 56 /* msg_stats_scan - read MSG_STATS from stream */ 57 58 int msg_stats_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp, 59 int flags, void *ptr) 60 { 61 MSG_STATS *stats = (MSG_STATS *) ptr; 62 VSTRING *buf = vstring_alloc(sizeof(MSG_STATS) * 2); 63 int ret; 64 65 /* 66 * Receive the entire structure. This is not only simpler but also likely 67 * to be quicker than having the sender figure out what fields need to be 68 * sent, converting those numbers to string and back, and having the 69 * receiver initialize the unused fields by hand. 70 * 71 * XXX Would be nice if VSTRINGs could import a fixed-size buffer and 72 * gracefully reject attempts to extend it. 73 */ 74 ret = scan_fn(fp, flags | ATTR_FLAG_MORE, 75 RECV_ATTR_DATA(MAIL_ATTR_TIME, buf), 76 ATTR_TYPE_END); 77 if (ret == 1) { 78 if (LEN(buf) == sizeof(*stats)) { 79 memcpy((void *) stats, STR(buf), sizeof(*stats)); 80 } else { 81 msg_warn("msg_stats_scan: size mis-match: %u != %u", 82 (unsigned) LEN(buf), (unsigned) sizeof(*stats)); 83 ret = (-1); 84 } 85 } 86 vstring_free(buf); 87 return (ret); 88 } 89