1 /* $NetBSD: argv_attr_scan.c,v 1.3 2022/10/08 16:12:50 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* argv_attr_scan 6 /* SUMMARY 7 /* read ARGV from stream 8 /* SYNOPSIS 9 /* #include <argv_attr.h> 10 /* 11 /* int argv_attr_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 /* argv_attr_scan() creates an ARGV and reads its contents 18 /* from the named stream using the specified attribute scan 19 /* routine. argv_attr_scan() is meant to be passed as a call-back 20 /* to attr_scan(), thusly: 21 /* 22 /* ARGV *argv = 0; 23 /* ... 24 /* ... RECV_ATTR_FUNC(argv_attr_scan, (void *) &argv), ... 25 /* ... 26 /* if (argv) 27 /* argv_free(argv); 28 /* DIAGNOSTICS 29 /* Fatal: out of memory. 30 /* 31 /* In case of error, this function returns non-zero and creates 32 /* an ARGV null pointer. 33 /* LICENSE 34 /* .ad 35 /* .fi 36 /* The Secure Mailer license must be distributed with this software. 37 /* AUTHOR(S) 38 /* Wietse Venema 39 /* Google, Inc. 40 /* 111 8th Avenue 41 /* New York, NY 10011, USA 42 /*--*/ 43 44 /* 45 * System library. 46 */ 47 #include <sys_defs.h> 48 49 /* 50 * Utility library. 51 */ 52 #include <argv.h> 53 #include <argv_attr.h> 54 #include <attr.h> 55 #include <msg.h> 56 #include <vstream.h> 57 #include <vstring.h> 58 59 /* argv_attr_scan - write ARGV to stream */ 60 61 int argv_attr_scan(ATTR_PRINT_COMMON_FN scan_fn, VSTREAM *fp, 62 int flags, void *ptr) 63 { 64 ARGV *argv = 0; 65 int size; 66 int ret; 67 68 if ((ret = scan_fn(fp, flags | ATTR_FLAG_MORE, 69 RECV_ATTR_INT(ARGV_ATTR_SIZE, &size), 70 ATTR_TYPE_END)) == 1) { 71 if (msg_verbose) 72 msg_info("argv_attr_scan count=%d", size); 73 if (size < 0 || size > ARGV_ATTR_MAX) { 74 msg_warn("invalid size %d from %s while reading ARGV", 75 size, VSTREAM_PATH(fp)); 76 ret = -1; 77 } else if (size > 0) { 78 VSTRING *buffer = vstring_alloc(100); 79 80 argv = argv_alloc(size); 81 while (ret == 1 && size-- > 0) { 82 if ((ret = scan_fn(fp, flags | ATTR_FLAG_MORE, 83 RECV_ATTR_STR(ARGV_ATTR_VALUE, buffer), 84 ATTR_TYPE_END)) == 1) 85 argv_add(argv, vstring_str(buffer), ARGV_END); 86 } 87 argv_terminate(argv); 88 vstring_free(buffer); 89 } 90 } 91 *(ARGV **) ptr = argv; 92 if (msg_verbose) 93 msg_info("argv_attr_scan ret=%d", ret); 94 return (ret); 95 } 96