Home | History | Annotate | Line # | Download | only in util
      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