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
argv_attr_scan(ATTR_PRINT_COMMON_FN scan_fn,VSTREAM * fp,int flags,void * ptr)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