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