mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-29 13:18:12 +00:00
snapshot-20011010
This commit is contained in:
parent
d1f6c6552f
commit
1ef3a9a63a
1
postfix/.indent.pro
vendored
1
postfix/.indent.pro
vendored
@ -54,6 +54,7 @@
|
||||
-THTABLE
|
||||
-THTABLE_INFO
|
||||
-TINET_ADDR_LIST
|
||||
-TINTV
|
||||
-TINT_TABLE
|
||||
-TJMP_BUF_WRAPPER
|
||||
-TLMTP_ATTR
|
||||
|
@ -15,7 +15,7 @@
|
||||
* Version of this program.
|
||||
*/
|
||||
#define VAR_MAIL_VERSION "mail_version"
|
||||
#define DEF_MAIL_VERSION "Snapshot-20011008"
|
||||
#define DEF_MAIL_VERSION "Snapshot-20011010"
|
||||
extern char *var_mail_version;
|
||||
|
||||
/* LICENSE
|
||||
|
@ -272,13 +272,16 @@ static void multi_server_enable_read(int unused_event, char *context)
|
||||
static void multi_server_wakeup(int fd)
|
||||
{
|
||||
VSTREAM *stream;
|
||||
|
||||
char *tmp;
|
||||
if (msg_verbose)
|
||||
msg_info("connection established fd %d", fd);
|
||||
non_blocking(fd, BLOCKING);
|
||||
close_on_exec(fd, CLOSE_ON_EXEC);
|
||||
client_count++;
|
||||
stream = vstream_fdopen(fd, O_RDWR);
|
||||
tmp = concatenate(multi_server_name, " socket", (char *) 0);
|
||||
vstream_control(stream, VSTREAM_CTL_PATH, tmp, VSTREAM_CTL_END);
|
||||
myfree(tmp);
|
||||
timed_ipc_setup(stream);
|
||||
if (multi_server_in_flow_delay && mail_flow_get(1) < 0)
|
||||
event_request_timer(multi_server_enable_read, (char *) stream,
|
||||
|
@ -221,6 +221,7 @@ static void single_server_timeout(int unused_event, char *unused_context)
|
||||
static void single_server_wakeup(int fd)
|
||||
{
|
||||
VSTREAM *stream;
|
||||
char *tmp;
|
||||
|
||||
/*
|
||||
* If the accept() succeeds, be sure to disable non-blocking I/O, because
|
||||
@ -233,6 +234,9 @@ static void single_server_wakeup(int fd)
|
||||
non_blocking(fd, BLOCKING);
|
||||
close_on_exec(fd, CLOSE_ON_EXEC);
|
||||
stream = vstream_fdopen(fd, O_RDWR);
|
||||
tmp = concatenate(single_server_name, " socket", (char *) 0);
|
||||
vstream_control(stream, VSTREAM_CTL_PATH, tmp, VSTREAM_CTL_END);
|
||||
myfree(tmp);
|
||||
timed_ipc_setup(stream);
|
||||
if (master_notify(var_pid, MASTER_STAT_TAKEN) < 0)
|
||||
single_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT);
|
||||
|
@ -23,7 +23,8 @@ SRCS = argv.c argv_split.c attr.c basename.c binhash.c chroot_uid.c \
|
||||
clean_env.c watchdog.c spawn_command.c duplex_pipe.c sane_rename.c \
|
||||
sane_link.c unescape.c timed_read.c timed_write.c dict_tcp.c \
|
||||
hex_quote.c dict_alloc.c rand_sleep.c sane_time.c dict_debug.c \
|
||||
sane_socketpair.c myrand.c netstring.c ctable.c
|
||||
sane_socketpair.c myrand.c netstring.c ctable.c attr_print.c intv.c \
|
||||
attr_scan.c
|
||||
OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
|
||||
close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \
|
||||
dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
|
||||
@ -48,7 +49,8 @@ OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
|
||||
clean_env.o watchdog.o spawn_command.o duplex_pipe.o sane_rename.o \
|
||||
sane_link.o unescape.o timed_read.o timed_write.o dict_tcp.o \
|
||||
hex_quote.o dict_alloc.o rand_sleep.o sane_time.o dict_debug.o \
|
||||
sane_socketpair.o myrand.o netstring.o ctable.o
|
||||
sane_socketpair.o myrand.o netstring.o ctable.o attr_print.o intv.o \
|
||||
attr_scan.o
|
||||
HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
|
||||
dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
|
||||
dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
|
||||
@ -64,7 +66,8 @@ HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
|
||||
vbuf.h vbuf_print.h vstream.h vstring.h vstring_vstream.h \
|
||||
dict_unix.h dict_pcre.h dict_regexp.h mac_expand.h clean_env.h \
|
||||
watchdog.h spawn_command.h sane_fsops.h dict_tcp.h hex_quote.h \
|
||||
sane_time.h sane_socketpair.h myrand.h netstring.h ctable.h
|
||||
sane_time.h sane_socketpair.h myrand.h netstring.h ctable.h \
|
||||
attr_io.h intv.h
|
||||
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
|
||||
stream_test.c dup2_pass_on_exec.c
|
||||
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
|
||||
@ -81,7 +84,7 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
|
||||
mystrtok sigdelay translit valid_hostname vstream_popen \
|
||||
vstring vstring_vstream doze select_bug stream_test mac_expand \
|
||||
watchdog unescape hex_quote name_mask rand_sleep sane_time ctable \
|
||||
inet_addr_list
|
||||
inet_addr_list attr_print attr_scan
|
||||
|
||||
LIB_DIR = ../../lib
|
||||
INC_DIR = ../../include
|
||||
@ -285,6 +288,16 @@ inet_addr_list: $(LIB) $@.o
|
||||
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
|
||||
mv junk $@.o
|
||||
|
||||
attr_print: $(LIB) $@.o
|
||||
mv $@.o junk
|
||||
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
|
||||
mv junk $@.o
|
||||
|
||||
attr_scan: $(LIB) $@.o
|
||||
mv $@.o junk
|
||||
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
|
||||
mv junk $@.o
|
||||
|
||||
depend: $(MAKES)
|
||||
(sed '1,/^# do not edit/!d' Makefile.in; \
|
||||
set -e; for i in [a-z][a-z0-9]*.c; do \
|
||||
@ -359,6 +372,21 @@ attr.o: sys_defs.h
|
||||
attr.o: mymalloc.h
|
||||
attr.o: htable.h
|
||||
attr.o: attr.h
|
||||
attr_print.o: attr_print.c
|
||||
attr_print.o: sys_defs.h
|
||||
attr_print.o: vstream.h
|
||||
attr_print.o: vbuf.h
|
||||
attr_print.o: msg.h
|
||||
attr_print.o: attr_io.h
|
||||
attr_scan.o: attr_scan.c
|
||||
attr_scan.o: sys_defs.h
|
||||
attr_scan.o: vstream.h
|
||||
attr_scan.o: vbuf.h
|
||||
attr_scan.o: vstring.h
|
||||
attr_scan.o: msg.h
|
||||
attr_scan.o: argv.h
|
||||
attr_scan.o: intv.h
|
||||
attr_scan.o: attr_io.h
|
||||
basename.o: basename.c
|
||||
basename.o: sys_defs.h
|
||||
basename.o: stringops.h
|
||||
@ -682,6 +710,11 @@ inet_util.o: sys_defs.h
|
||||
inet_util.o: mymalloc.h
|
||||
inet_util.o: split_at.h
|
||||
inet_util.o: inet_util.h
|
||||
intv.o: intv.c
|
||||
intv.o: sys_defs.h
|
||||
intv.o: mymalloc.h
|
||||
intv.o: msg.h
|
||||
intv.o: intv.h
|
||||
line_wrap.o: line_wrap.c
|
||||
line_wrap.o: sys_defs.h
|
||||
line_wrap.o: line_wrap.h
|
||||
|
63
postfix/src/util/attr_io.h
Normal file
63
postfix/src/util/attr_io.h
Normal file
@ -0,0 +1,63 @@
|
||||
#ifndef _ATTR_PRINT_H_INCLUDED_
|
||||
#define _ATTR_PRINT_H_INCLUDED_
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
/* attr_type 3h
|
||||
/* SUMMARY
|
||||
/* attribute list I/O
|
||||
/* SYNOPSIS
|
||||
/* #include "attr_type.h"
|
||||
DESCRIPTION
|
||||
.nf
|
||||
|
||||
/*
|
||||
* System library.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
|
||||
/*
|
||||
* Utility library.
|
||||
*/
|
||||
#include <vstream.h>
|
||||
|
||||
/*
|
||||
* External interface.
|
||||
*/
|
||||
#define ATTR_TYPE_END 0 /* end of data */
|
||||
#define ATTR_TYPE_NUM 1 /* Unsigned integer */
|
||||
#define ATTR_TYPE_STR 2 /* Character string */
|
||||
#define ATTR_TYPE_NUM_ARRAY 3 /* Unsigned integer sequence */
|
||||
#define ATTR_TYPE_STR_ARRAY 4 /* Character string sequence */
|
||||
|
||||
#define ATTR_FLAG_MISSING (1<<0) /* Flag missing attribute */
|
||||
#define ATTR_FLAG_EXTRA (1<<1) /* Flag spurious attribute */
|
||||
|
||||
extern int attr_print(VSTREAM *,...);
|
||||
extern int attr_vprint(VSTREAM *, va_list);
|
||||
extern int attr_scan(VSTREAM *, int,...);
|
||||
extern int attr_vscan(VSTREAM *, int, va_list);
|
||||
|
||||
/*
|
||||
* Attribute names for testing the compatibility of the read and write
|
||||
* routines.
|
||||
*/
|
||||
#ifdef TEST
|
||||
#define ATTR_NAME_NUM "number"
|
||||
#define ATTR_NAME_STR "string"
|
||||
#define ATTR_NAME_NUM_ARRAY "number_array"
|
||||
#define ATTR_NAME_STR_ARRAY "string_array"
|
||||
#endif
|
||||
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
#endif
|
175
postfix/src/util/attr_print.c
Normal file
175
postfix/src/util/attr_print.c
Normal file
@ -0,0 +1,175 @@
|
||||
/*++
|
||||
/* NAME
|
||||
/* attr_print 3
|
||||
/* SUMMARY
|
||||
/* send attributes over byte stream
|
||||
/* SYNOPSIS
|
||||
/* #include <attr_io.h>
|
||||
/*
|
||||
/* int attr_print(fp, type, name, ...)
|
||||
/* VSTREAM fp;
|
||||
/* int type;
|
||||
/* char *name;
|
||||
/* DESCRIPTION
|
||||
/* attr_print() takes zero or more (name, value) simple attributes
|
||||
/* or (name, count, value) list attributes, and converts its input
|
||||
/* to a byte stream that can be recovered with attr_scan(). The stream
|
||||
/* is not flushed.
|
||||
/*
|
||||
/* Attributes are sent in the requested order as specified with the
|
||||
/* attr_print() argument list. This routine satisfies the formatting
|
||||
/* rules as outlined in attr_scan(3).
|
||||
/*
|
||||
/* Arguments:
|
||||
/* .IP fp
|
||||
/* Stream to write the result to.
|
||||
/* .IP type
|
||||
/* The type determines the arguments that follow.
|
||||
/* .RS
|
||||
/* .IP "ATTR_TYPE_NUM (char *, int)"
|
||||
/* This argument is followed by an attribute name and an integer.
|
||||
/* .IP "ATTR_TYPE_STR (char *, char *)"
|
||||
/* This argument is followed by an attribute name and a null-terminated
|
||||
/* string.
|
||||
/* .IP "ATTR_TYPE_NUM_ARRAY (char *, int, int *)"
|
||||
/* This argument is followed by an attribute name, an integer array
|
||||
/* element count, and a pointer to integer.
|
||||
/* .IP "ATTR_TYPE_NUM_ARRAY (char *, int, char **)"
|
||||
/* This argument is followed by an attribute name, an integer array
|
||||
/* element count, and a pointer to a null-terminated array of
|
||||
/* null-terminated strings.
|
||||
/* .IP ATTR_TYPE_END
|
||||
/* This terminates the attribute list.
|
||||
/* .RE
|
||||
/* DIAGNOSTICS
|
||||
/* The result value is 0 in case of success, VSTREAM_EOF in case
|
||||
/* of trouble.
|
||||
/*
|
||||
/* Panic: interface violation. All system call errors are fatal.
|
||||
/* SEE ALSO
|
||||
/* attr_scan(3) recover attributes from byte stream
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <vstream.h>
|
||||
#include <msg.h>
|
||||
#include <attr_io.h>
|
||||
|
||||
/* attr_fprintf - encode attribute information on the fly */
|
||||
|
||||
static void PRINTFLIKE(2, 3) attr_fprintf(VSTREAM *fp, const char *format,...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vstream_vfprintf(fp, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* attr_vprint - send attribute list to stream */
|
||||
|
||||
int attr_vprint(VSTREAM *fp, va_list ap)
|
||||
{
|
||||
const char *myname = "attr_print";
|
||||
int attr_type;
|
||||
char *attr_name;
|
||||
unsigned int_val;
|
||||
char *str_val;
|
||||
char **cpp_val;
|
||||
unsigned *ip_val;
|
||||
int count_val;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Iterate over all (type, name, value) triples, and produce output on
|
||||
* the fly.
|
||||
*/
|
||||
while ((attr_type = va_arg(ap, int)) != ATTR_TYPE_END) {
|
||||
attr_name = va_arg(ap, char *);
|
||||
attr_fprintf(fp, "%s", attr_name);
|
||||
switch (attr_type) {
|
||||
case ATTR_TYPE_NUM:
|
||||
int_val = va_arg(ap, int);
|
||||
attr_fprintf(fp, ":%u", (unsigned) int_val);
|
||||
break;
|
||||
case ATTR_TYPE_STR:
|
||||
str_val = va_arg(ap, char *);
|
||||
attr_fprintf(fp, ":%s", str_val);
|
||||
break;
|
||||
case ATTR_TYPE_NUM_ARRAY:
|
||||
ip_val = va_arg(ap, int *);
|
||||
count_val = va_arg(ap, int);
|
||||
for (i = 0; i < count_val; i++)
|
||||
attr_fprintf(fp, ":%u", (unsigned) *ip_val++);
|
||||
break;
|
||||
case ATTR_TYPE_STR_ARRAY:
|
||||
cpp_val = va_arg(ap, char **);
|
||||
count_val = va_arg(ap, int);
|
||||
for (i = 0; i < count_val; i++) {
|
||||
str_val = *cpp_val++;
|
||||
attr_fprintf(fp, ":%s", str_val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
msg_panic("%s: unknown type code: %d", myname, attr_type);
|
||||
}
|
||||
VSTREAM_PUTC('\n', fp);
|
||||
}
|
||||
VSTREAM_PUTC('\n', fp);
|
||||
return (vstream_ferror(fp));
|
||||
}
|
||||
|
||||
int attr_print(VSTREAM *fp,...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, fp);
|
||||
ret = attr_vprint(fp, ap);
|
||||
va_end(ap);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/*
|
||||
* Proof of concept test program. Mirror image of the attr_scan test
|
||||
* program.
|
||||
*/
|
||||
#include <msg_vstream.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
static int int_array[] = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||
static char *str_array[] = {"a", "b", "c", "d", "e", "f", "g", "h"};
|
||||
|
||||
msg_vstream_init(argv[0], VSTREAM_ERR);
|
||||
attr_print(VSTREAM_OUT,
|
||||
ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711,
|
||||
ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
|
||||
ATTR_TYPE_NUM_ARRAY, ATTR_NAME_NUM_ARRAY,
|
||||
int_array, sizeof(int_array) / sizeof(int_array[0]),
|
||||
ATTR_TYPE_STR_ARRAY, ATTR_NAME_STR_ARRAY,
|
||||
str_array, sizeof(str_array) / sizeof(str_array[0]),
|
||||
ATTR_TYPE_END);
|
||||
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||
msg_fatal("write error: %m");
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif
|
369
postfix/src/util/attr_scan.c
Normal file
369
postfix/src/util/attr_scan.c
Normal file
@ -0,0 +1,369 @@
|
||||
/*++
|
||||
/* NAME
|
||||
/* attr_scan 3
|
||||
/* SUMMARY
|
||||
/* recover attributes from byte stream
|
||||
/* SYNOPSIS
|
||||
/* #include <attr_io.h>
|
||||
/*
|
||||
/* int attr_scan(fp, flags, type, name, ...)
|
||||
/* VSTREAM fp;
|
||||
/* int flags;
|
||||
/* int type;
|
||||
/* char *name;
|
||||
/* DESCRIPTION
|
||||
/* attr_scan() takes zero or more (name, value) scalar or array
|
||||
/* attribute arguments, and recovers the attribute values from the
|
||||
/* byte stream that was generated by attr_print().
|
||||
/*
|
||||
/* The input stream is formatted as follows, where (item)* stands
|
||||
/* for zero or more instances of the specified item, and where
|
||||
/* (item1 | item2) stands for choice:
|
||||
/*
|
||||
/* .in +5
|
||||
/* attr-list :== (simple-attr | list-attr)* newline
|
||||
/* .br
|
||||
/* simple-attr :== attr-name colon attr-value newline
|
||||
/* .br
|
||||
/* list-attr :== attr-name (colon attr-value)* newline
|
||||
/* .br
|
||||
/* attr-name :== any base64 encoded string
|
||||
/* .br
|
||||
/* attr-value :== any base64 encoded string
|
||||
/* .br
|
||||
/* colon :== the ASCII colon character
|
||||
/* .br
|
||||
/* newline :== the ASCII newline character
|
||||
/* .in
|
||||
/*
|
||||
/* All character values are 7-bit ASCII. All attribute names and
|
||||
/* attribute values are sent as base64-encoded strings. The
|
||||
/* formatting rules aim to make implementations in PERL and other
|
||||
/* non-C languages easy.
|
||||
/*
|
||||
/* Attributes must be sent in the requested order as specified with
|
||||
/* the attr_scan() argument list. The input stream may contain
|
||||
/* additional attributes at any point in the input stream, including
|
||||
/* additional instances of requested attributes.
|
||||
/*
|
||||
/* Additional attributes are silently skipped over, unless the
|
||||
/* ATTR_FLAG_EXTRA processing flag is specified (see below). This
|
||||
/* allows for some flexibility in the evolution of protocols while
|
||||
/* still providing the option of being strict where desirable.
|
||||
/*
|
||||
/* Arguments:
|
||||
/* .IP fp
|
||||
/* Stream to recover the attributes from.
|
||||
/* .IP flags
|
||||
/* The bit-wise OR of zero or more of the following.
|
||||
/* .RS
|
||||
/* .IP ATTR_FLAG_MISSING
|
||||
/* Log a warning when the input attribute list terminates before all
|
||||
/* requested attributes are recovered. It is always an error when the
|
||||
/* input stream ends without the newline attribute list terminator.
|
||||
/* .IP ATTR_FLAG_EXTRA
|
||||
/* Log a warning and stop attribute recovery when the input stream
|
||||
/* contains an attribute that was not requested.
|
||||
/* .RE
|
||||
/* .IP type
|
||||
/* The type determines the arguments that follow.
|
||||
/* .RS
|
||||
/* .IP "ATTR_TYPE_NUM (char *, int *)"
|
||||
/* This argument is followed by an attribute name and an integer pointer.
|
||||
/* This is used for recovering an integer attribute value.
|
||||
/* .IP "ATTR_TYPE_STR (char *, VSTRING *)"
|
||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||
/* This is used for recovering a string attribute value.
|
||||
/* .IP "ATTR_TYPE_NUM_ARRAY (char *, INTV *)"
|
||||
/* This argument is followed by an attribute name and an INTV pointer.
|
||||
/* This is used for recovering an integer array attribute value.
|
||||
/* .IP "ATTR_TYPE_NUM_ARRAY (char *, ARGV *)"
|
||||
/* This argument is followed by an attribute name and an ARGV pointer.
|
||||
/* This is used for recovering a string array attribute value.
|
||||
/* .IP ATTR_TYPE_END
|
||||
/* This terminates the requested attribute list.
|
||||
/* .RE
|
||||
/* DIAGNOSTICS
|
||||
/* The result value is the number of attributes that were successfully
|
||||
/* recovered from the input stream (an array-valued attribute counts
|
||||
/* as one attribute).
|
||||
/*
|
||||
/* Panic: interface violation. All system call errors are fatal.
|
||||
/* SEE ALSO
|
||||
/* attr_print(3) send attributes over byte stream.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <vstream.h>
|
||||
#include <vstring.h>
|
||||
#include <msg.h>
|
||||
#include <argv.h>
|
||||
#include <intv.h>
|
||||
#include <attr_io.h>
|
||||
|
||||
/* Application specific. */
|
||||
|
||||
extern int var_line_limit; /* XXX */
|
||||
|
||||
#define STR(x) vstring_str(x)
|
||||
#define LEN(x) VSTRING_LEN(x)
|
||||
|
||||
/* attr_scan_string - pull a string from the input stream */
|
||||
|
||||
static int attr_scan_string(VSTREAM *fp, VSTRING *plain_buf, const char *context)
|
||||
{
|
||||
VSTRING *base64_buf = 0;
|
||||
int limit = var_line_limit * 5 / 4;
|
||||
int ch;
|
||||
|
||||
if (base64_buf == 0)
|
||||
base64_buf = vstring_alloc(10);
|
||||
|
||||
VSTRING_RESET(base64_buf);
|
||||
while ((ch = VSTREAM_GETC(fp)) != ':' && ch != '\n') {
|
||||
if (ch == VSTREAM_EOF) {
|
||||
msg_warn("premature end-of-input from %s while reading %s",
|
||||
VSTREAM_PATH(fp), context);
|
||||
return (-1);
|
||||
}
|
||||
if (LEN(base64_buf) > limit) {
|
||||
msg_warn("string length > %d characters from %s while reading %s",
|
||||
limit, VSTREAM_PATH(fp), context);
|
||||
return (-1);
|
||||
}
|
||||
VSTRING_ADDCH(base64_buf, ch);
|
||||
}
|
||||
VSTRING_TERMINATE(base64_buf);
|
||||
vstring_strcpy(plain_buf, STR(base64_buf));
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s", context, STR(plain_buf));
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/* attr_scan_number - pull a number from the input stream */
|
||||
|
||||
static int attr_scan_number(VSTREAM *fp, unsigned *ptr, VSTRING *str_buf,
|
||||
const char *context)
|
||||
{
|
||||
char junk = 0;
|
||||
int ch;
|
||||
|
||||
if ((ch = attr_scan_string(fp, str_buf, context)) < 0)
|
||||
return (-1);
|
||||
if (sscanf(STR(str_buf), "%u%c", ptr, &junk) != 1 || junk != 0) {
|
||||
msg_warn("malformed numerical data from %s while %s: %.100s",
|
||||
VSTREAM_PATH(fp), context, STR(str_buf));
|
||||
return (-1);
|
||||
}
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/* attr_vscan - receive attribute list from stream */
|
||||
|
||||
int attr_vscan(VSTREAM *fp, int flags, va_list ap)
|
||||
{
|
||||
const char *myname = "attr_scan";
|
||||
static VSTRING *str_buf = 0;
|
||||
int wanted_type;
|
||||
char *wanted_name;
|
||||
int *number;
|
||||
VSTRING *string;
|
||||
INTV *number_array;
|
||||
ARGV *string_array;
|
||||
unsigned num_val;
|
||||
int ch;
|
||||
int conversions = 0;
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
*/
|
||||
if (str_buf == 0)
|
||||
str_buf = vstring_alloc(10);
|
||||
|
||||
/*
|
||||
* Iterate over all (type, name, value) triples.
|
||||
*/
|
||||
for (;;) {
|
||||
|
||||
/*
|
||||
* Determine the next attribute name on the caller's wish list.
|
||||
*/
|
||||
wanted_type = va_arg(ap, int);
|
||||
if (wanted_type == ATTR_TYPE_END) {
|
||||
wanted_name = "attribute list terminator";
|
||||
} else {
|
||||
wanted_name = va_arg(ap, char *);
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate the next attribute of interest in the input stream.
|
||||
*/
|
||||
for (;;) {
|
||||
|
||||
/*
|
||||
* Get the name of the next attribute. Hitting the end-of-input
|
||||
* early is OK if the caller is prepared to deal with missing
|
||||
* inputs.
|
||||
*/
|
||||
if ((ch = attr_scan_string(fp, str_buf,
|
||||
"attribute name")) == VSTREAM_EOF)
|
||||
return (conversions);
|
||||
if (ch == '\n' && LEN(str_buf) == 0) {
|
||||
if (wanted_type == ATTR_TYPE_END
|
||||
|| (flags & ATTR_FLAG_MISSING) == 0)
|
||||
return (conversions);
|
||||
msg_warn("missing attribute %s in input from %s",
|
||||
wanted_name, VSTREAM_PATH(fp));
|
||||
return (conversions);
|
||||
}
|
||||
if (msg_verbose)
|
||||
msg_info("want attribute %s, found attribute: %s",
|
||||
wanted_name, STR(str_buf));
|
||||
|
||||
/*
|
||||
* See if the caller asks for this attribute.
|
||||
*/
|
||||
if (wanted_type != ATTR_TYPE_END
|
||||
&& strcmp(wanted_name, STR(str_buf)) == 0)
|
||||
break;
|
||||
if ((flags & ATTR_FLAG_EXTRA) != 0) {
|
||||
msg_warn("spurious attribute %s in input from %s",
|
||||
STR(str_buf), VSTREAM_PATH(fp));
|
||||
return (conversions);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip over this attribute. The caller does not ask for it.
|
||||
*/
|
||||
while ((ch = VSTREAM_GETC(fp)) != VSTREAM_EOF && ch != '\n')
|
||||
/* void */ ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the requested conversion. If the target attribute is a
|
||||
* non-array type, do not allow the sender to send a multi-valued
|
||||
* attribute. If the target attribute is an array type, allow the
|
||||
* sender to send a zero-element array.
|
||||
*/
|
||||
switch (wanted_type) {
|
||||
case ATTR_TYPE_NUM:
|
||||
number = va_arg(ap, int *);
|
||||
if ((ch = attr_scan_number(fp, number, str_buf,
|
||||
"attribute value")) < 0)
|
||||
return (conversions);
|
||||
if (ch != '\n') {
|
||||
msg_warn("too many values for attribute %s from %s",
|
||||
wanted_name, VSTREAM_PATH(fp));
|
||||
return (conversions);
|
||||
}
|
||||
break;
|
||||
case ATTR_TYPE_STR:
|
||||
string = va_arg(ap, VSTRING *);
|
||||
if ((ch = attr_scan_string(fp, string, "attribute value")) < 0)
|
||||
return (conversions);
|
||||
if (ch != '\n') {
|
||||
msg_warn("too many values for attribute %s from %s",
|
||||
wanted_name, VSTREAM_PATH(fp));
|
||||
return (conversions);
|
||||
}
|
||||
break;
|
||||
case ATTR_TYPE_NUM_ARRAY:
|
||||
number_array = va_arg(ap, INTV *);
|
||||
while (ch != '\n') {
|
||||
if ((ch = attr_scan_number(fp, &num_val, str_buf,
|
||||
"attribute value")) < 0)
|
||||
return (conversions);
|
||||
intv_add(number_array, 1, num_val);
|
||||
}
|
||||
break;
|
||||
case ATTR_TYPE_STR_ARRAY:
|
||||
string_array = va_arg(ap, ARGV *);
|
||||
while (ch != '\n') {
|
||||
if ((ch = attr_scan_string(fp, str_buf, "attribute value")) < 0)
|
||||
return (conversions);
|
||||
argv_add(string_array, STR(str_buf), (char *) 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
msg_panic("%s: unknown type code: %d", myname, wanted_type);
|
||||
}
|
||||
conversions++;
|
||||
}
|
||||
}
|
||||
|
||||
/* attr_scan - read attribute list from stream */
|
||||
|
||||
int attr_scan(VSTREAM *fp, int flags,...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, flags);
|
||||
ret = attr_vscan(fp, flags, ap);
|
||||
va_end(ap);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/*
|
||||
* Proof of concept test program. Mirror image of the attr_scan test
|
||||
* program.
|
||||
*/
|
||||
#include <msg_vstream.h>
|
||||
|
||||
int var_line_limit = 2048;
|
||||
|
||||
int main(int unused_argc, char **used_argv)
|
||||
{
|
||||
INTV *intv = intv_alloc(1);
|
||||
ARGV *argv = argv_alloc(1);
|
||||
VSTRING *str_val = vstring_alloc(1);
|
||||
int int_val;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
msg_verbose = 1;
|
||||
msg_vstream_init(used_argv[0], VSTREAM_ERR);
|
||||
if ((ret = attr_scan(VSTREAM_IN,
|
||||
ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA,
|
||||
ATTR_TYPE_NUM, ATTR_NAME_NUM, &int_val,
|
||||
ATTR_TYPE_STR, ATTR_NAME_STR, str_val,
|
||||
ATTR_TYPE_NUM_ARRAY, ATTR_NAME_NUM_ARRAY, intv,
|
||||
ATTR_TYPE_STR_ARRAY, ATTR_NAME_STR_ARRAY, argv,
|
||||
ATTR_TYPE_END)) == 4) {
|
||||
vstream_printf("%s %d\n", ATTR_NAME_NUM, int_val);
|
||||
vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
|
||||
vstream_printf("%s", ATTR_NAME_NUM_ARRAY);
|
||||
for (i = 0; i < intv->intc; i++)
|
||||
vstream_printf(" %d", intv->intv[i]);
|
||||
vstream_printf("\n");
|
||||
vstream_printf("%s", ATTR_NAME_STR_ARRAY);
|
||||
for (i = 0; i < argv->argc; i++)
|
||||
vstream_printf(" %s", argv->argv[i]);
|
||||
vstream_printf("\n");
|
||||
} else {
|
||||
vstream_printf("return: %d\n", ret);
|
||||
}
|
||||
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||
msg_fatal("write error: %m");
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif
|
114
postfix/src/util/intv.c
Normal file
114
postfix/src/util/intv.c
Normal file
@ -0,0 +1,114 @@
|
||||
/*++
|
||||
/* NAME
|
||||
/* intv 3
|
||||
/* SUMMARY
|
||||
/* integer array utilities
|
||||
/* SYNOPSIS
|
||||
/* #include <intv.h>
|
||||
/*
|
||||
/* INTV *intv_alloc(len)
|
||||
/* int len;
|
||||
/*
|
||||
/* INTV *intv_free(intvp)
|
||||
/* INTV *intvp;
|
||||
/*
|
||||
/* void intv_add(intvp, count, arg, ...)
|
||||
/* INTV *intvp;
|
||||
/* int count;
|
||||
/* int *arg;
|
||||
/* DESCRIPTION
|
||||
/* The functions in this module manipulate arrays of integers.
|
||||
/* An INTV structure contains the following members:
|
||||
/* .IP len
|
||||
/* The actual length of the \fIintv\fR array.
|
||||
/* .IP intc
|
||||
/* The number of \fIintv\fR elements used.
|
||||
/* .IP intv
|
||||
/* An array of integer values.
|
||||
/* .PP
|
||||
/* intv_alloc() returns an empty integer array of the requested
|
||||
/* length. The result is ready for use by intv_add().
|
||||
/*
|
||||
/* intv_add() copies zero or more integers and adds them to the
|
||||
/* specified integer array.
|
||||
/*
|
||||
/* intv_free() releases storage for an integer array, and conveniently
|
||||
/* returns a null pointer.
|
||||
/* SEE ALSO
|
||||
/* msg(3) diagnostics interface
|
||||
/* DIAGNOSTICS
|
||||
/* Fatal errors: memory allocation problem.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
/* System libraries. */
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <stdlib.h> /* 44BSD stdarg.h uses abort() */
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Application-specific. */
|
||||
|
||||
#include "mymalloc.h"
|
||||
#include "msg.h"
|
||||
#include "intv.h"
|
||||
|
||||
/* intv_free - destroy integer array */
|
||||
|
||||
INTV *intv_free(INTV *intvp)
|
||||
{
|
||||
myfree((char *) intvp->intv);
|
||||
myfree((char *) intvp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* intv_alloc - initialize integer array */
|
||||
|
||||
INTV *intv_alloc(int len)
|
||||
{
|
||||
INTV *intvp;
|
||||
|
||||
/*
|
||||
* Sanity check.
|
||||
*/
|
||||
if (len < 1)
|
||||
msg_panic("intv_alloc: bad array length %d", len);
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
*/
|
||||
intvp = (INTV *) mymalloc(sizeof(*intvp));
|
||||
intvp->len = len;
|
||||
intvp->intv = (int *) mymalloc(intvp->len * sizeof(intvp->intv[0]));
|
||||
intvp->intc = 0;
|
||||
return (intvp);
|
||||
}
|
||||
|
||||
/* intv_add - add integer to vector */
|
||||
|
||||
void intv_add(INTV *intvp, int count,...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
/*
|
||||
* Make sure that always intvp->intc < intvp->len.
|
||||
*/
|
||||
va_start(ap, count);
|
||||
while (count-- > 0) {
|
||||
if (intvp->intc >= intvp->len) {
|
||||
intvp->len *= 2;
|
||||
intvp->intv = (int *) myrealloc((char *) intvp->intv,
|
||||
intvp->len * sizeof(int));
|
||||
}
|
||||
intvp->intv[intvp->intc++] = va_arg(ap, int);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
38
postfix/src/util/intv.h
Normal file
38
postfix/src/util/intv.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef _INTV_H_INCLUDED_
|
||||
#define _INTV_H_INCLUDED_
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
/* intv 3h
|
||||
/* SUMMARY
|
||||
/* string array utilities
|
||||
/* SYNOPSIS
|
||||
/* #include "intv.h"
|
||||
DESCRIPTION
|
||||
.nf
|
||||
|
||||
/*
|
||||
* External interface.
|
||||
*/
|
||||
typedef struct INTV {
|
||||
int len; /* number of array elements */
|
||||
int intc; /* array elements in use */
|
||||
int *intv; /* integer array */
|
||||
} INTV;
|
||||
|
||||
extern INTV *intv_alloc(int);
|
||||
extern void intv_add(INTV *, int,...);
|
||||
extern INTV *intv_free(INTV *);
|
||||
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
#endif
|
@ -26,7 +26,7 @@
|
||||
#if defined(FREEBSD2) || defined(FREEBSD3) || defined(FREEBSD4) \
|
||||
|| defined(FREEBSD5) \
|
||||
|| defined(BSDI2) || defined(BSDI3) || defined(BSDI4) \
|
||||
|| defined(OPENBSD2) || defined(NETBSD1)
|
||||
|| defined(OPENBSD2) || defined(OPENBSD3) || defined(NETBSD1)
|
||||
#define SUPPORTED
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@ -58,7 +58,8 @@
|
||||
#define HAS_DUPLEX_PIPE
|
||||
#endif
|
||||
|
||||
#if defined(OPENBSD2) || defined(FREEBSD3) || defined(FREEBSD4)
|
||||
#if defined(OPENBSD2) || defined(OPENBSD3) \
|
||||
|| defined(FREEBSD3) || defined(FREEBSD4)
|
||||
#define HAS_ISSETUGID
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user