1 /* $NetBSD: msg_stats_scan.c,v 1.3 2022/10/08 16:12: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_COMMON_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 /* Wietse Venema 35 /* Google, Inc. 36 /* 111 8th Avenue 37 /* New York, NY 10011, USA 38 /*--*/ 39 40 /* System library. */ 41 42 #include <sys_defs.h> 43 44 /* Utility library. */ 45 46 #include <attr.h> 47 #include <vstring.h> 48 #include <msg.h> 49 50 /* Global library. */ 51 52 #include <mail_proto.h> 53 #include <msg_stats.h> 54 55 /* 56 * SLMs. 57 */ 58 #define STR(x) vstring_str(x) 59 #define LEN(x) VSTRING_LEN(x) 60 61 /* msg_stats_scan - read MSG_STATS from stream */ 62 63 int msg_stats_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp, 64 int flags, void *ptr) 65 { 66 MSG_STATS *stats = (MSG_STATS *) ptr; 67 VSTRING *buf = vstring_alloc(sizeof(MSG_STATS) * 2); 68 int ret; 69 70 /* 71 * Receive the entire structure. This is not only simpler but also likely 72 * to be quicker than having the sender figure out what fields need to be 73 * sent, converting those numbers to string and back, and having the 74 * receiver initialize the unused fields by hand. 75 * 76 * XXX Would be nice if VSTRINGs could import a fixed-size buffer and 77 * gracefully reject attempts to extend it. 78 */ 79 ret = scan_fn(fp, flags | ATTR_FLAG_MORE, 80 RECV_ATTR_DATA(MAIL_ATTR_TIME, buf), 81 ATTR_TYPE_END); 82 if (ret == 1) { 83 if (LEN(buf) == sizeof(*stats)) { 84 memcpy((void *) stats, STR(buf), sizeof(*stats)); 85 } else { 86 msg_warn("msg_stats_scan: size mis-match: %u != %u", 87 (unsigned) LEN(buf), (unsigned) sizeof(*stats)); 88 ret = (-1); 89 } 90 } 91 vstring_free(buf); 92 return (ret); 93 } 94