1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/*++
/* NAME
/* mail_parm_split 3
/* SUMMARY
/* split parameter list value
/* SYNOPSIS
/* #include <mail_parm_split.h>
/*
/* ARGV *mail_parm_split(
/* const char *name,
/* const char *value)
/* DESCRIPTION
/* mail_parm_split() splits a parameter list value into its
/* elements, and extracts text from elements that are entirely
/* enclosed in {}. It uses CHARS_COMMA_SP as list element
/* delimiters, and CHARS_BRACE for grouping.
/*
/* Arguments:
/* .IP name
/* Parameter name. This is used to provide context for
/* error messages.
/* .IP value
/* Parameter value.
/* DIAGNOSTICS
/* fatal: syntax error while extracting text from {}, such as:
/* missing closing brace, or text after closing brace.
/* SEE ALSO
/* argv_splitq(3), string array utilities
/* extpar(3), extract text from parentheses
/* 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
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/
/*
* System library.
*/
#include <sys_defs.h>
/*
* Utility library.
*/
#include <msg.h>
#include <mymalloc.h>
#include <stringops.h>
/*
* Global library.
*/
#include <mail_params.h>
#include <mail_parm_split.h>
/* mail_parm_split - split list, extract {text}, errors are fatal */
ARGV *mail_parm_split(const char *name, const char *value)
{
ARGV *argvp = argv_alloc(1);
char *saved_string = mystrdup(value);
char *bp = saved_string;
char *arg;
char *err;
/*
* The code that detects the error shall either signal or handle the
* error. In this case, mystrtokq() detects no error, extpar() signals
* the error to its caller, and this function handles the error.
*/
while ((arg = mystrtokq(&bp, CHARS_COMMA_SP, CHARS_BRACE)) != 0) {
if (*arg == CHARS_BRACE[0]
&& (err = extpar(&arg, CHARS_BRACE, EXTPAR_FLAG_STRIP)) != 0) {
#ifndef TEST
msg_fatal("%s: %s", name, err);
#else
msg_warn("%s: %s", name, err);
myfree(err);
#endif
}
argv_add(argvp, arg, (char *) 0);
}
argv_terminate(argvp);
myfree(saved_string);
return (argvp);
}
#ifdef TEST
/*
* This function is security-critical so it better have a unit-test driver.
*/
#include <string.h>
#include <vstream.h>
#include <vstream.h>
#include <vstring_vstream.h>
int main(void)
{
VSTRING *vp = vstring_alloc(100);
ARGV *argv;
char *start;
char *str;
char **cpp;
while (vstring_fgets_nonl(vp, VSTREAM_IN) && VSTRING_LEN(vp) > 0) {
start = vstring_str(vp);
vstream_printf("Input:\t>%s<\n", start);
vstream_fflush(VSTREAM_OUT);
argv = mail_parm_split("stdin", start);
for (cpp = argv->argv; (str = *cpp) != 0; cpp++)
vstream_printf("Output:\t>%s<\n", str);
argv_free(argv);
vstream_fflush(VSTREAM_OUT);
}
vstring_free(vp);
return (0);
}
#endif
|