diff options
Diffstat (limited to 'src/util/argv_attr_scan.c')
-rw-r--r-- | src/util/argv_attr_scan.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/util/argv_attr_scan.c b/src/util/argv_attr_scan.c new file mode 100644 index 0000000..3005cb2 --- /dev/null +++ b/src/util/argv_attr_scan.c @@ -0,0 +1,93 @@ +/*++ +/* NAME +/* argv_attr_scan +/* SUMMARY +/* read ARGV from stream +/* SYNOPSIS +/* #include <argv_attr.h> +/* +/* int argv_attr_scan(scan_fn, stream, flags, ptr) +/* ATTR_SCAN_MASTER_FN scan_fn; +/* VSTREAM *stream; +/* int flags; +/* void *ptr; +/* DESCRIPTION +/* argv_attr_scan() creates an ARGV and reads its contents +/* from the named stream using the specified attribute scan +/* routine. argv_attr_scan() is meant to be passed as a call-back +/* to attr_scan(), thusly: +/* +/* ARGV *argv = 0; +/* ... +/* ... RECV_ATTR_FUNC(argv_attr_scan, (void *) &argv), ... +/* ... +/* if (argv) +/* argv_free(argv); +/* DIAGNOSTICS +/* Fatal: out of memory. +/* +/* In case of error, this function returns non-zero and creates +/* an ARGV null pointer. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA +/*--*/ + + /* + * System library. + */ +#include <sys_defs.h> + + /* + * Utility library. + */ +#include <argv.h> +#include <argv_attr.h> +#include <attr.h> +#include <msg.h> +#include <vstream.h> +#include <vstring.h> + +/* argv_attr_scan - write ARGV to stream */ + +int argv_attr_scan(ATTR_PRINT_MASTER_FN scan_fn, VSTREAM *fp, + int flags, void *ptr) +{ + ARGV *argv = 0; + int size; + int ret; + + if ((ret = scan_fn(fp, flags | ATTR_FLAG_MORE, + RECV_ATTR_INT(ARGV_ATTR_SIZE, &size), + ATTR_TYPE_END)) == 1) { + if (msg_verbose) + msg_info("argv_attr_scan count=%d", size); + if (size < 0 || size > ARGV_ATTR_MAX) { + msg_warn("invalid size %d from %s while reading ARGV", + size, VSTREAM_PATH(fp)); + ret = -1; + } else if (size > 0) { + VSTRING *buffer = vstring_alloc(100); + + argv = argv_alloc(size); + while (ret == 1 && size-- > 0) { + if ((ret = scan_fn(fp, flags | ATTR_FLAG_MORE, + RECV_ATTR_STR(ARGV_ATTR_VALUE, buffer), + ATTR_TYPE_END)) == 1) + argv_add(argv, vstring_str(buffer), ARGV_END); + } + argv_terminate(argv); + vstring_free(buffer); + } + } + *(ARGV **) ptr = argv; + if (msg_verbose) + msg_info("argv_attr_scan ret=%d", ret); + return (ret); +} |