xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/argv_attr_scan.c (revision 67b9b338a7386232ac596b5fd0cd5a9cc8a03c71)
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